cdsclient-lib 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +19 -20
  2. package/dist/lib/cjs/client.d.ts +304 -0
  3. package/dist/lib/cjs/client.js +916 -0
  4. package/dist/lib/cjs/client.js.map +1 -0
  5. package/dist/lib/cjs/enums.d.ts +23 -0
  6. package/dist/lib/cjs/enums.js +28 -0
  7. package/dist/lib/cjs/enums.js.map +1 -0
  8. package/dist/lib/cjs/errors.d.ts +20 -0
  9. package/dist/lib/cjs/errors.js +25 -0
  10. package/dist/lib/cjs/errors.js.map +1 -0
  11. package/dist/lib/cjs/event/channelstates.d.ts +24 -0
  12. package/dist/lib/cjs/event/channelstates.js +28 -0
  13. package/dist/lib/cjs/event/channelstates.js.map +1 -0
  14. package/dist/lib/cjs/event/eventprovider.d.ts +40 -0
  15. package/dist/lib/cjs/event/eventprovider.js +62 -0
  16. package/dist/lib/cjs/event/eventprovider.js.map +1 -0
  17. package/dist/lib/cjs/event/events.d.ts +32 -0
  18. package/dist/lib/cjs/event/events.js +38 -0
  19. package/dist/lib/cjs/event/events.js.map +1 -0
  20. package/dist/lib/cjs/index.d.ts +23 -0
  21. package/dist/lib/cjs/index.js +68 -0
  22. package/dist/lib/cjs/index.js.map +1 -0
  23. package/dist/lib/cjs/interfaces.d.ts +162 -0
  24. package/dist/lib/cjs/interfaces.js +20 -0
  25. package/dist/lib/cjs/interfaces.js.map +1 -0
  26. package/dist/lib/cjs/models.d.ts +198 -0
  27. package/dist/lib/cjs/models.js +234 -0
  28. package/dist/lib/cjs/models.js.map +1 -0
  29. package/dist/lib/cjs/wsclient.d.ts +99 -0
  30. package/dist/lib/cjs/wsclient.js +330 -0
  31. package/dist/lib/cjs/wsclient.js.map +1 -0
  32. package/dist/lib/es6/client.d.ts +304 -0
  33. package/dist/lib/es6/client.js +876 -0
  34. package/dist/lib/es6/client.js.map +1 -0
  35. package/dist/lib/es6/enums.d.ts +23 -0
  36. package/dist/lib/es6/enums.js +25 -0
  37. package/dist/lib/es6/enums.js.map +1 -0
  38. package/dist/lib/es6/errors.d.ts +20 -0
  39. package/dist/lib/es6/errors.js +25 -0
  40. package/dist/lib/es6/errors.js.map +1 -0
  41. package/dist/lib/es6/event/channelstates.d.ts +24 -0
  42. package/dist/lib/es6/event/channelstates.js +25 -0
  43. package/dist/lib/es6/event/channelstates.js.map +1 -0
  44. package/dist/lib/es6/event/eventprovider.d.ts +40 -0
  45. package/dist/lib/es6/event/eventprovider.js +57 -0
  46. package/dist/lib/es6/event/eventprovider.js.map +1 -0
  47. package/dist/lib/es6/event/events.d.ts +32 -0
  48. package/dist/lib/es6/event/events.js +35 -0
  49. package/dist/lib/es6/event/events.js.map +1 -0
  50. package/dist/lib/es6/index.d.ts +23 -0
  51. package/dist/lib/es6/index.js +23 -0
  52. package/dist/lib/es6/index.js.map +1 -0
  53. package/dist/lib/es6/interfaces.d.ts +162 -0
  54. package/dist/lib/es6/interfaces.js +19 -0
  55. package/dist/lib/es6/interfaces.js.map +1 -0
  56. package/dist/lib/es6/models.d.ts +198 -0
  57. package/dist/lib/es6/models.js +201 -0
  58. package/dist/lib/es6/models.js.map +1 -0
  59. package/dist/lib/es6/wsclient.d.ts +99 -0
  60. package/dist/lib/es6/wsclient.js +292 -0
  61. package/dist/lib/es6/wsclient.js.map +1 -0
  62. package/package.json +28 -14
@@ -0,0 +1,876 @@
1
+ /**
2
+ * Copyright © 2024 Rajdeep Rath. All Rights Reserved.
3
+ *
4
+ * This codebase is open-source and provided for use exclusively with the Cloudisense platform,
5
+ * as governed by its End-User License Agreement (EULA). Unauthorized use, reproduction,
6
+ * or distribution of this code outside of the Cloudisense ecosystem is strictly prohibited.
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * You may not use this file except in compliance with the License.
10
+ * A copy of the License is available at:
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * This code may include third-party open-source libraries subject to their respective licenses.
14
+ * Such licenses are referenced in the source files or accompanying documentation.
15
+ *
16
+ * For questions or permissions beyond the scope of this notice, please contact Rajdeep Rath.
17
+ */
18
+ import 'reflect-metadata';
19
+ import { WSClient } from "./wsclient";
20
+ import { sha256 } from 'js-sha256';
21
+ import { EventList } from "strongly-typed-events";
22
+ import { ClientEventProvider } from "./event/eventprovider";
23
+ import { Base64 } from 'js-base64';
24
+ import { ClientStateType, ClientState, CloudisenseClientStatsDataEvent, CloudisenseClientLogDataEvent, CloudisenseClientSimpleNotificationEvent, CloudisenseClientErrorEvent, AuthData, CloudisenseClientUIDataEvent, CloudisenseClientScriptDataEvent } from "./models";
25
+ import { TOPIC_SCRIPT_MONITORING, TOPIC_LOG_MONITORING, TOPIC_STATS_MONITORING, TOPIC_UI_UPDATES } from "./event/events";
26
+ import * as CHANNEL_STATES from './event/channelstates';
27
+ import * as EVENTS from './event/events';
28
+ import axios from 'axios';
29
+ import { plainToInstance } from 'class-transformer';
30
+ export class CloudisenseApiClient extends ClientEventProvider {
31
+ constructor(config) {
32
+ super();
33
+ this._topicevents = new EventList();
34
+ this._errorCount = 0;
35
+ this.host = config.host;
36
+ this.port = config.port;
37
+ this.authdata = config.authdata;
38
+ this.autoconnect = (typeof config.autoconnect === 'undefined' || config.autoconnect === null) ? false : config.autoconnect;
39
+ this.reconnectOnFailure = (typeof config.reconnectOnFailure === 'undefined' || config.reconnectOnFailure === null) ? false : config.reconnectOnFailure;
40
+ this._restEndPoint = "http" + "://" + this.host + ":" + this.port; // fix this later
41
+ return this;
42
+ }
43
+ /**
44
+ * Subscribes to a specific DataEvent topic
45
+ *
46
+ * @param topicname topic name to subscribe to
47
+ * @param fn subscriber handler function
48
+ */
49
+ subscribeTopic(topicname, fn) {
50
+ return this._topicevents.get(topicname).subscribe(fn);
51
+ }
52
+ /**
53
+ * Unsubscribes from a specific DataEvent topic. The handler is executed at most once
54
+ *
55
+ * @param topicname topic name to unsubscribe from
56
+ * @param fn subscriber handler function
57
+ */
58
+ unsubscribeTopic(topicname, fn) {
59
+ this._topicevents.get(topicname).unsubscribe(fn);
60
+ }
61
+ /**
62
+ * Checks to see if a given DataEvent topic has a handler registered against it or not
63
+ *
64
+ * @param topicname
65
+ * @param fn
66
+ */
67
+ hasTopicHandler(topicname, fn) {
68
+ return this._topicevents.get(topicname).has(fn);
69
+ }
70
+ /**
71
+ * Gets the root path of the filesystem (constrained by sandbox)
72
+ *
73
+ * @returns Promise that resolved to root path data of the filesystem
74
+ */
75
+ get_accessible_file_system_paths() {
76
+ return new Promise((resolve, reject) => {
77
+ let promise = this._socketservice.doRPC("get_accessible_paths", {});
78
+ promise.then((data) => {
79
+ resolve(data);
80
+ }).catch((err) => {
81
+ reject(err);
82
+ });
83
+ });
84
+ }
85
+ /**
86
+ * Requests deletion of a file from the file system
87
+ *
88
+ * @param path The path of the file to delete
89
+ * @returns Promise that resolves to nothing if operation is successful and error if unsuccessful
90
+ */
91
+ delete_file(path) {
92
+ return new Promise((resolve, reject) => {
93
+ let promise = this._socketservice.doRPC("delete_file", {
94
+ "path": path
95
+ });
96
+ promise.then((data) => {
97
+ resolve(data);
98
+ }).catch((err) => {
99
+ reject(err);
100
+ });
101
+ });
102
+ }
103
+ /**
104
+ * Requests deletion of a directory from the file system
105
+ *
106
+ * @param path The path of the directory to delete
107
+ * @returns Promise that resolves to nothing if operation is successful and error if unsuccessful
108
+ */
109
+ delete_folder(root, dirname, deleteNonEmpty = false) {
110
+ return new Promise((resolve, reject) => {
111
+ let promise = this._socketservice.doRPC("delete_folder", {
112
+ "root": root,
113
+ "dirname": dirname,
114
+ "delete_non_empty": deleteNonEmpty
115
+ });
116
+ promise.then((data) => {
117
+ resolve(data);
118
+ }).catch((err) => {
119
+ reject(err);
120
+ });
121
+ });
122
+ }
123
+ /**
124
+ * Requests the download file from the file system (within allowed scope)
125
+ *
126
+ * @param path The path of the file to download
127
+ * @returns Promise that resolves to a download link if operation is successful and error if unsuccessful
128
+ */
129
+ download_file(path, mode = "static") {
130
+ return new Promise((resolve, reject) => {
131
+ let promise = this._socketservice.doRPC("download_file", {
132
+ "path": path,
133
+ "mode": mode
134
+ });
135
+ promise.then((data) => {
136
+ resolve(data);
137
+ }).catch((err) => {
138
+ reject(err);
139
+ });
140
+ });
141
+ }
142
+ /**
143
+ * Gets content listing of the file system path specified
144
+ *
145
+ * @returns Promise that resolved to path content (if any)
146
+ */
147
+ list_path_content(root, path = "") {
148
+ return new Promise((resolve, reject) => {
149
+ let promise = this._socketservice.doRPC("list_content", {
150
+ "root": root,
151
+ "path": path
152
+ });
153
+ promise.then((data) => {
154
+ resolve(data);
155
+ }).catch((err) => {
156
+ reject(err);
157
+ });
158
+ });
159
+ }
160
+ /**
161
+ * Fetched the content of a simple text file from server
162
+ *
163
+ * @returns
164
+ */
165
+ read_file(path) {
166
+ const promise = new Promise((resolve, reject) => {
167
+ const url = this.getBaseAPIendPoint() + "/file/read";
168
+ const params = new URLSearchParams();
169
+ params.append('path', path);
170
+ const config = {
171
+ headers: {
172
+ 'Content-Type': 'application/x-www-form-urlencoded'
173
+ }
174
+ };
175
+ const promise = axios.post(url, params, config);
176
+ promise.then((result) => {
177
+ if (result.status == 200) {
178
+ const content = Base64.decode(result.data.data);
179
+ console.debug(content);
180
+ resolve(content);
181
+ }
182
+ else {
183
+ throw new Error("Invalid or unexpected response");
184
+ }
185
+ })
186
+ .catch((err) => {
187
+ console.error(err.toString());
188
+ reject(err);
189
+ });
190
+ });
191
+ return promise;
192
+ }
193
+ /**
194
+ * Saves the content of a simple text file on server
195
+ *
196
+ * @returns
197
+ */
198
+ write_file(path, content) {
199
+ const promise = new Promise((resolve, reject) => {
200
+ const url = this.getBaseAPIendPoint() + "/file/write";
201
+ const params = new URLSearchParams();
202
+ params.append('path', path);
203
+ params.append('content', Base64.encode(content));
204
+ const config = {
205
+ headers: {
206
+ 'Content-Type': 'application/x-www-form-urlencoded'
207
+ }
208
+ };
209
+ const promise = axios.post(url, params, config);
210
+ promise.then((result) => {
211
+ if (result.status == 200) {
212
+ const content = Base64.decode(result.data.data);
213
+ console.debug(content);
214
+ resolve(content);
215
+ }
216
+ else {
217
+ throw new Error("Invalid or unexpected response");
218
+ }
219
+ })
220
+ .catch((err) => {
221
+ console.error(err.toString());
222
+ reject(err);
223
+ });
224
+ });
225
+ return promise;
226
+ }
227
+ /**
228
+ * Gets list of accessible logs
229
+ *
230
+ * @returns Promise that resolved to List of logs
231
+ */
232
+ get_logs() {
233
+ return new Promise((resolve, reject) => {
234
+ let promise = this._socketservice.doRPC("list_logs");
235
+ promise.then((data) => {
236
+ resolve(data);
237
+ }).catch((err) => {
238
+ reject(err);
239
+ });
240
+ });
241
+ }
242
+ /**
243
+ * Gets list of reaction engine rules
244
+ *
245
+ * @returns Promise that resolved to List of ReactionRules
246
+ */
247
+ list_rules(head = true) {
248
+ return new Promise((resolve, reject) => {
249
+ let promise = this._socketservice.doRPC("list_rules", { "head": head });
250
+ promise.then((data) => {
251
+ resolve(data);
252
+ }).catch((err) => {
253
+ reject(err);
254
+ });
255
+ });
256
+ }
257
+ /**
258
+ * Attempts to reloads all reaction rules in the system
259
+ *
260
+ * @returns Promise that resolved to nothing
261
+ */
262
+ reload_rules() {
263
+ return new Promise((resolve, reject) => {
264
+ let promise = this._socketservice.doRPC("reload_rules", {});
265
+ promise.then((data) => {
266
+ resolve(data);
267
+ }).catch((err) => {
268
+ reject(err);
269
+ });
270
+ });
271
+ }
272
+ /**
273
+ * Attempts to reloads a reaction rules by specified id
274
+ * in the system
275
+ *
276
+ * @returns Promise that resolved to id of the reaction rule
277
+ */
278
+ reload_rule(id) {
279
+ return new Promise((resolve, reject) => {
280
+ let promise = this._socketservice.doRPC("reload_rule", { "rule_id": id });
281
+ promise.then((data) => {
282
+ resolve(id);
283
+ }).catch((err) => {
284
+ reject(err);
285
+ });
286
+ });
287
+ }
288
+ /**
289
+ * Gets rule data of a reaction engine rule by specified id
290
+ *
291
+ * @returns Promise that resolved to Rule data
292
+ */
293
+ get_rule(id) {
294
+ return new Promise((resolve, reject) => {
295
+ let promise = this._socketservice.doRPC("read_rule", { "rule_id": id });
296
+ promise.then((data) => {
297
+ resolve(data);
298
+ }).catch((err) => {
299
+ reject(err);
300
+ });
301
+ });
302
+ }
303
+ /**
304
+ * Requests service to initiate restart via systemctl.
305
+ * Server should have sufficient permissions to execute the command
306
+ *
307
+ * @returns Promise that resolved to nothing (no return value)
308
+ */
309
+ request_restart(id) {
310
+ return new Promise((resolve, reject) => {
311
+ let promise = this._socketservice.doRPC("restart_self", {});
312
+ promise.then((data = null) => {
313
+ resolve(data);
314
+ }).catch((err) => {
315
+ reject(err);
316
+ });
317
+ });
318
+ }
319
+ /**
320
+ * Requests to load settings / configuration information from the server
321
+ *
322
+ * @returns Promise that resolved to settings data
323
+ */
324
+ loadSettings() {
325
+ return new Promise((resolve, reject) => {
326
+ let promise = this._socketservice.doRPC("get_configuration", {});
327
+ promise.then((data) => {
328
+ resolve(data);
329
+ }).catch((err) => {
330
+ reject(err);
331
+ });
332
+ });
333
+ }
334
+ /**
335
+ * Gets sample reaction rule data from server
336
+ *
337
+ * @returns Promise that resolved to Rule data
338
+ */
339
+ generate_sample_rule() {
340
+ return new Promise((resolve, reject) => {
341
+ let promise = this._socketservice.doRPC("generate_sample", {});
342
+ promise.then((data) => {
343
+ resolve(data);
344
+ }).catch((err) => {
345
+ reject(err);
346
+ });
347
+ });
348
+ }
349
+ /**
350
+ * Saves rule data of a reaction engine rule on server
351
+ *
352
+ * @returns Promise that resolved to Rule Id on successful write
353
+ */
354
+ write_rule(data, update = true) {
355
+ return new Promise((resolve, reject) => {
356
+ let promise = this._socketservice.doRPC("write_rule", { "rule_data": data, "update": update });
357
+ promise.then((response) => {
358
+ resolve(response);
359
+ }).catch((err) => {
360
+ reject(err);
361
+ });
362
+ });
363
+ }
364
+ /**
365
+ * Deletes a rule by specified id
366
+ *
367
+ * @returns Promise that resolves to the id of the deleted rule
368
+ */
369
+ delete_rule(id) {
370
+ return new Promise((resolve, reject) => {
371
+ let promise = this._socketservice.doRPC("delete_rule", { "rule_id": id });
372
+ promise.then(() => {
373
+ resolve(id);
374
+ }).catch((err) => {
375
+ reject(err);
376
+ });
377
+ });
378
+ }
379
+ /**
380
+ * Subscribes to arbitrary data channel (topic path) to get realtime data
381
+ *
382
+ * @returns Promise that resolved to subscribable topic path for the data channel for stats
383
+ */
384
+ subscribe_datachannel(topic) {
385
+ return new Promise((resolve, reject) => {
386
+ let payload = {
387
+ "topic": topic
388
+ };
389
+ let promise = this._socketservice.doRPC("subscribe_channel", payload);
390
+ promise.then((data) => {
391
+ resolve(data);
392
+ }).catch((err) => {
393
+ reject(err);
394
+ });
395
+ });
396
+ }
397
+ /**
398
+ * Subscribes to stats channel (topic path) to get realtime data
399
+ *
400
+ * @returns Promise that resolved to subscribable topic path for the data channel for stats
401
+ */
402
+ subscribe_stats() {
403
+ return new Promise((resolve, reject) => {
404
+ let payload = {
405
+ "topic": TOPIC_STATS_MONITORING
406
+ };
407
+ let promise = this._socketservice.doRPC("subscribe_channel", payload);
408
+ promise.then((data) => {
409
+ resolve(data);
410
+ }).catch((err) => {
411
+ reject(err);
412
+ });
413
+ });
414
+ }
415
+ /**
416
+ * Subscribes to ui updates channel (topic path) to get data updates for dashboard widgets
417
+ *
418
+ * @returns Promise that resolved to subscribable topic path for the data channel for stats
419
+ */
420
+ subscribe_ui_updates() {
421
+ return new Promise((resolve, reject) => {
422
+ let payload = {
423
+ "topic": TOPIC_UI_UPDATES
424
+ };
425
+ let promise = this._socketservice.doRPC("subscribe_channel", payload);
426
+ promise.then((data) => {
427
+ resolve(data);
428
+ }).catch((err) => {
429
+ reject(err);
430
+ });
431
+ });
432
+ }
433
+ /**
434
+ * Unsubscribes from stats channel (topic path) to get realtime data
435
+ *
436
+ * @returns Promise that resolved to boolean true on unsubscribe success
437
+ */
438
+ unsubscribe_stats() {
439
+ return new Promise((resolve, reject) => {
440
+ let payload = {
441
+ "topic": TOPIC_STATS_MONITORING
442
+ };
443
+ let promise = this._socketservice.doRPC("unsubscribe_channel", payload);
444
+ promise.then((data) => {
445
+ resolve(true);
446
+ }).catch((err) => {
447
+ reject(err);
448
+ });
449
+ });
450
+ }
451
+ /**
452
+ * Subscribes to log channel (topic path) to get realtime data
453
+ *
454
+ * @param topic
455
+ * @returns Promise that resolved to subscribable topic path for the data channel of thsi log
456
+ */
457
+ subscribe_log(topic) {
458
+ return new Promise((resolve, reject) => {
459
+ let payload = {
460
+ "topic": topic
461
+ };
462
+ let promise = this._socketservice.doRPC("subscribe_channel", payload);
463
+ promise.then((data) => {
464
+ resolve(data);
465
+ }).catch((err) => {
466
+ reject(err);
467
+ });
468
+ });
469
+ }
470
+ /**
471
+ *
472
+ * Unsubscribes from a log channel
473
+ *
474
+ * @param logkey
475
+ * @returns
476
+ */
477
+ unsubscribe_log(topic) {
478
+ return new Promise((resolve, reject) => {
479
+ let payload = {
480
+ "topic": topic
481
+ };
482
+ let promise = this._socketservice.doRPC("unsubscribe_channel", payload);
483
+ promise.then((data) => {
484
+ resolve(data);
485
+ }).catch((err) => {
486
+ reject(err);
487
+ });
488
+ });
489
+ }
490
+ /**
491
+ * Requests to download a log file from server
492
+ *
493
+ * @param logkey
494
+ * @returns
495
+ */
496
+ download_log(logkey, mode = "static") {
497
+ const promise = new Promise((resolve, reject) => {
498
+ const url = this.getBaseAPIendPoint() + "/log/download/" + mode;
499
+ const params = new URLSearchParams();
500
+ params.append('logname', logkey);
501
+ const config = {
502
+ headers: {
503
+ 'Content-Type': 'application/x-www-form-urlencoded'
504
+ }
505
+ };
506
+ const promise = axios.post(url, params, config);
507
+ promise.then((result) => {
508
+ if (result.data.status == "success") {
509
+ const download_url = this.getBaseAPIendPoint() + "/" + result.data.data;
510
+ resolve(download_url);
511
+ }
512
+ else {
513
+ throw new Error('Exception response received ' + JSON.stringify(result));
514
+ }
515
+ })
516
+ .catch((err) => {
517
+ reject(err);
518
+ });
519
+ });
520
+ return promise;
521
+ }
522
+ /**
523
+ * Gets list of system services that can be started/stopped through the service
524
+ *
525
+ * @returns
526
+ */
527
+ get_system_services() {
528
+ return new Promise((resolve, reject) => {
529
+ let promise = this._socketservice.doRPC("list_targets");
530
+ promise.then((data) => {
531
+ resolve(data);
532
+ }).catch((err) => {
533
+ reject(err);
534
+ });
535
+ });
536
+ }
537
+ /**
538
+ * Starts a system service using its name
539
+ *
540
+ * @param name
541
+ * @returns
542
+ */
543
+ start_service(name) {
544
+ return new Promise((resolve, reject) => {
545
+ let payload = {
546
+ "module": name
547
+ };
548
+ let promise = this._socketservice.doRPC("start_target", payload);
549
+ promise.then((data) => {
550
+ resolve(data);
551
+ }).catch((err) => {
552
+ reject(err);
553
+ });
554
+ });
555
+ }
556
+ /**
557
+ * Stops a system service using its name
558
+ *
559
+ * @param name
560
+ * @returns
561
+ */
562
+ stop_service(name) {
563
+ return new Promise((resolve, reject) => {
564
+ let payload = {
565
+ "module": name
566
+ };
567
+ let promise = this._socketservice.doRPC("stop_target", payload);
568
+ promise.then((data) => {
569
+ resolve(data);
570
+ }).catch((err) => {
571
+ reject(err);
572
+ });
573
+ });
574
+ }
575
+ /**
576
+ * Restarts a system service using its name
577
+ *
578
+ * @param name
579
+ * @returns
580
+ */
581
+ restart_service(name) {
582
+ return new Promise((resolve, reject) => {
583
+ let payload = {
584
+ "module": name
585
+ };
586
+ let promise = this._socketservice.doRPC("restart_target", payload);
587
+ promise.then((data) => {
588
+ resolve(data);
589
+ }).catch((err) => {
590
+ reject(err);
591
+ });
592
+ });
593
+ }
594
+ /**
595
+ *
596
+ * Execute arbitrary intent request
597
+ *
598
+ * @param intent
599
+ * @param params
600
+ * @returns
601
+ */
602
+ execute_arbitrary_action(intent, params) {
603
+ return new Promise((resolve, reject) => {
604
+ let promise = this._socketservice.doRPC(intent, params);
605
+ promise.then((data) => {
606
+ resolve(data);
607
+ }).catch((err) => {
608
+ reject(err);
609
+ });
610
+ });
611
+ }
612
+ /**
613
+ * Connects to backend service using auth data from previous authentication
614
+ *
615
+ * @param authData
616
+ * @returns Promise
617
+ */
618
+ connectWithAuthData(authData) {
619
+ return new Promise((resolve, reject) => {
620
+ this.__wsconnect(authData).then((wsclient) => {
621
+ resolve(wsclient);
622
+ })
623
+ .catch((err) => {
624
+ reject(err);
625
+ });
626
+ });
627
+ }
628
+ /**
629
+ * Connects to backend service using a set of valid credentials
630
+ *
631
+ * @param username
632
+ * @param password
633
+ * @returns
634
+ */
635
+ connectWithCredentials(username, password) {
636
+ return new Promise((resolve, reject) => {
637
+ var hashed_password = sha256.create().update(password).hex();
638
+ this.authenticate(username, hashed_password).then((res) => {
639
+ if (res.status == 200) {
640
+ const authData = plainToInstance(AuthData, res.data.data);
641
+ this._authtime = new Date().getUTCMilliseconds();
642
+ this.__wsconnect(authData).then((wsclient) => {
643
+ resolve(wsclient);
644
+ })
645
+ .catch((err) => {
646
+ reject(err);
647
+ });
648
+ }
649
+ else {
650
+ reject("Authentication failed with code " + res.status);
651
+ }
652
+ }).catch((err) => {
653
+ this._errorCount++;
654
+ const message = err.toString();
655
+ if (message.indexOf("ECONNREFUSED") > 0) {
656
+ if (this.reconnectOnFailure) {
657
+ this.attemptReconnect();
658
+ }
659
+ }
660
+ else {
661
+ reject(err);
662
+ }
663
+ });
664
+ });
665
+ }
666
+ __wsconnect(tokenData) {
667
+ return new Promise((resolve, reject) => {
668
+ const socket_client = new WSClient({
669
+ host: this.host,
670
+ port: this.port,
671
+ authtoken: this.authdata.access.token
672
+ })
673
+ .connectService()
674
+ .then((client) => {
675
+ this._errorCount = 0;
676
+ this._socketservice = client;
677
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.CONNECTED));
678
+ this._socketservice.onChannelData.subscribe((data) => {
679
+ this.processChannelData(data);
680
+ });
681
+ this._socketservice.onChannelState.subscribe((state) => {
682
+ switch (state) {
683
+ case CHANNEL_STATES.STATE_CHANNEL_ERROR:
684
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.CONNECTION_ERROR));
685
+ this._errorCount++;
686
+ if (this.reconnectOnFailure) {
687
+ // try to connect again
688
+ this.attemptReconnect();
689
+ }
690
+ break;
691
+ case CHANNEL_STATES.STATE_CHANNEL_DISCONNECTED:
692
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.CONNECTION_TERMINATED));
693
+ break;
694
+ case CHANNEL_STATES.STATE_CHANNEL_CONNECTION_LOST:
695
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.CONNECTION_LOST));
696
+ if (this.reconnectOnFailure) {
697
+ // try to connect again
698
+ this.attemptReconnect();
699
+ }
700
+ break;
701
+ case CHANNEL_STATES.STATE_CHANNEL_CONNECTIING:
702
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.CONNECTING));
703
+ break;
704
+ }
705
+ });
706
+ resolve(socket_client);
707
+ })
708
+ .catch((err) => {
709
+ reject(err);
710
+ });
711
+ });
712
+ }
713
+ /**
714
+ * Returns a boolean promise to help determine if socket si conencted or not
715
+ * @returns
716
+ */
717
+ connected() {
718
+ return new Promise((resolve, reject) => {
719
+ if (this._socketservice && this._socketservice.is_connected()) {
720
+ resolve(true);
721
+ }
722
+ else {
723
+ reject(false);
724
+ }
725
+ });
726
+ }
727
+ /**
728
+ * Disconnects the client if connected to the server, otherwise
729
+ * throws error.
730
+ */
731
+ disconnect() {
732
+ return new Promise((resolve, reject) => {
733
+ if (this._socketservice && this._socketservice.is_connected()) {
734
+ this._socketservice.disconnectService();
735
+ resolve(this._socketservice);
736
+ }
737
+ else {
738
+ reject("Unable to disconnect service");
739
+ }
740
+ });
741
+ }
742
+ /**
743
+ * Attempts to reconenct back to service using last successful credentials
744
+ */
745
+ attemptReconnect() {
746
+ console.log("Attempting to reconnect");
747
+ if (this.authdata != undefined && this.authdata != null) {
748
+ if (this._errorCount < CloudisenseApiClient.MAX_ERROR_TOLERANCE) {
749
+ setTimeout(() => {
750
+ this.connectWithAuthData(this.authdata);
751
+ }, 5000);
752
+ }
753
+ else {
754
+ throw new Error("too many connection failures");
755
+ }
756
+ }
757
+ }
758
+ /**
759
+ * Process push data from server and dispatch events for client
760
+ *
761
+ * @param data
762
+ */
763
+ processChannelData(data) {
764
+ if (data["type"] == "event") {
765
+ let notificationData = undefined;
766
+ let event = data;
767
+ this._onClientStateUpdate.dispatch(new ClientState(ClientStateType.EVENT_RECEIVED));
768
+ switch (event.name) {
769
+ case EVENTS.SERVER_PING_EVENT:
770
+ console.debug("Server ping message");
771
+ break;
772
+ case EVENTS.TEXT_NOTIFICATION_EVENT:
773
+ this._onTextNotificationEvent.dispatchAsync(new CloudisenseClientSimpleNotificationEvent(event.topic, event.data, event.meta, event.timestamp));
774
+ break;
775
+ case EVENTS.EVENT_UI_UPDATE:
776
+ this._onUIEvent.dispatchAsync(new CloudisenseClientUIDataEvent(event.topic, event.data, event.meta, event.timestamp));
777
+ this._dispatchTopicOrientedDataEvent(event);
778
+ break;
779
+ case EVENTS.TEXT_DATA_NOTIFICATION_EVENT:
780
+ this._onTextNotificationEvent.dispatchAsync(new CloudisenseClientSimpleNotificationEvent(event.topic, event.data, event.meta, event.timestamp));
781
+ this._dispatchTopicOrientedDataEvent(event);
782
+ break;
783
+ case EVENTS.ERROR_EVENT:
784
+ this._dispatchTopicOrientedErrorEvent(event);
785
+ break;
786
+ case EVENTS.DATA_EVENT:
787
+ this._dispatchTopicOrientedDataEvent(event);
788
+ break;
789
+ default:
790
+ console.error("Unrecognized event type");
791
+ break;
792
+ }
793
+ }
794
+ }
795
+ /**
796
+ * Dispatches topic specific error event with topic specific data
797
+ * @param event
798
+ */
799
+ _dispatchTopicOrientedErrorEvent(event) {
800
+ const topic = event.topic;
801
+ switch (topic) {
802
+ case (topic.startsWith(TOPIC_LOG_MONITORING)) ? topic : null:
803
+ case (topic.startsWith(TOPIC_SCRIPT_MONITORING)) ? topic : null:
804
+ case (topic.startsWith(TOPIC_STATS_MONITORING)) ? topic : null:
805
+ case (topic.startsWith(TOPIC_UI_UPDATES)) ? topic : null:
806
+ case (topic.startsWith(EVENTS.TOPIC_UI_INITIALIZATION)) ? topic : null:
807
+ this._topicevents.get(topic).dispatchAsync(this, new CloudisenseClientErrorEvent(event.topic, event.data, event.meta, event.timestamp));
808
+ break;
809
+ default:
810
+ console.error("Error for unexpected topic:" + topic);
811
+ break;
812
+ }
813
+ }
814
+ /**
815
+ * Dispatches topic specific event with topic specific data - (generic)
816
+ *
817
+ * @param event
818
+ */
819
+ _dispatchTopicOrientedDataEvent(event) {
820
+ const topic = event.topic;
821
+ switch (topic) {
822
+ case (topic.startsWith(TOPIC_LOG_MONITORING)) ? topic : null:
823
+ this._topicevents.get(topic).dispatchAsync(this, new CloudisenseClientLogDataEvent(event.topic, event.data, event.meta, event.timestamp));
824
+ break;
825
+ case (topic.startsWith(TOPIC_SCRIPT_MONITORING)) ? topic : null:
826
+ this._topicevents.get(topic).dispatchAsync(this, new CloudisenseClientScriptDataEvent(event.topic, event.data, event.meta, event.timestamp));
827
+ break;
828
+ case (topic.startsWith(TOPIC_STATS_MONITORING)) ? topic : null:
829
+ this._topicevents.get(topic).dispatchAsync(this, new CloudisenseClientStatsDataEvent(event.topic, event.data, event.meta, event.timestamp));
830
+ break;
831
+ case (topic.startsWith(TOPIC_UI_UPDATES)) ? topic : null:
832
+ this._topicevents.get(topic).dispatchAsync(this, new CloudisenseClientUIDataEvent(event.topic, event.data, event.meta, event.timestamp));
833
+ break;
834
+ default:
835
+ console.debug("Event for topic:" + topic);
836
+ break;
837
+ }
838
+ }
839
+ getBaseAPIendPoint() {
840
+ return this._restEndPoint;
841
+ }
842
+ /**
843
+ * Authenticates a user based on username and password
844
+ *
845
+ * @param username
846
+ * @param password
847
+ * @returns
848
+ */
849
+ authenticate(username, password) {
850
+ return new Promise((resolve, reject) => {
851
+ const url = this.getBaseAPIendPoint() + "/" + "authorize";
852
+ const params = new URLSearchParams();
853
+ params.append('username', username);
854
+ params.append('password', password);
855
+ const config = {
856
+ headers: {
857
+ 'Content-Type': 'application/x-www-form-urlencoded'
858
+ }
859
+ };
860
+ const promise = axios.post(url, params, config);
861
+ promise.then((result) => {
862
+ console.debug(result);
863
+ resolve(result);
864
+ })
865
+ .catch((err) => {
866
+ console.error(err.toString());
867
+ reject(err);
868
+ });
869
+ });
870
+ }
871
+ dispose() {
872
+ // TO DO cleanup
873
+ }
874
+ }
875
+ CloudisenseApiClient.MAX_ERROR_TOLERANCE = 5;
876
+ //# sourceMappingURL=client.js.map