@webex/plugin-meetings 3.4.0-next.5 → 3.4.0-next.7

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.
@@ -209,7 +209,7 @@ var Breakout = _webexCore.WebexPlugin.extend({
209
209
  sessionId: this.sessionId
210
210
  });
211
211
  },
212
- version: "3.4.0-next.5"
212
+ version: "3.4.0-next.7"
213
213
  });
214
214
  var _default = exports.default = Breakout;
215
215
  //# sourceMappingURL=breakout.js.map
@@ -1046,7 +1046,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
1046
1046
  this.trigger(_constants.BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
1047
1047
  }
1048
1048
  },
1049
- version: "3.4.0-next.5"
1049
+ version: "3.4.0-next.7"
1050
1050
  });
1051
1051
  var _default = exports.default = Breakouts;
1052
1052
  //# sourceMappingURL=index.js.map
@@ -373,7 +373,7 @@ var SimultaneousInterpretation = _webexCore.WebexPlugin.extend({
373
373
  throw error;
374
374
  });
375
375
  },
376
- version: "3.4.0-next.5"
376
+ version: "3.4.0-next.7"
377
377
  });
378
378
  var _default = exports.default = SimultaneousInterpretation;
379
379
  //# sourceMappingURL=index.js.map
@@ -18,7 +18,7 @@ var SILanguage = _webexCore.WebexPlugin.extend({
18
18
  languageCode: 'number',
19
19
  languageName: 'string'
20
20
  },
21
- version: "3.4.0-next.5"
21
+ version: "3.4.0-next.7"
22
22
  });
23
23
  var _default = exports.default = SILanguage;
24
24
  //# sourceMappingURL=siLanguage.js.map
@@ -12,11 +12,11 @@ _Object$defineProperty(exports, "__esModule", {
12
12
  value: true
13
13
  });
14
14
  exports.default = void 0;
15
- var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
16
15
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
17
16
  var _values = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/values"));
18
17
  var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
19
18
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
19
+ var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
20
20
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
21
21
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
22
22
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
@@ -116,46 +116,103 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
116
116
  }
117
117
 
118
118
  /**
119
- * Gets a list of media clusters from the backend and performs reachability checks on all the clusters
120
- * @returns {Promise<ReachabilityResults>} reachability results
121
- * @public
122
- * @memberof Reachability
119
+ * Fetches the list of media clusters from the backend
120
+ * @param {boolean} isRetry
121
+ * @private
122
+ * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
123
123
  */
124
124
  (0, _createClass2.default)(Reachability, [{
125
- key: "gatherReachability",
125
+ key: "getClusters",
126
126
  value: (function () {
127
- var _gatherReachability = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
128
- var _yield$this$reachabil, clusters, joinCookie;
127
+ var _getClusters = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
128
+ var isRetry,
129
+ _yield$this$reachabil,
130
+ clusters,
131
+ joinCookie,
132
+ _args = arguments;
129
133
  return _regenerator.default.wrap(function _callee$(_context) {
130
134
  while (1) switch (_context.prev = _context.next) {
131
135
  case 0:
132
- _context.prev = 0;
133
- _context.next = 3;
136
+ isRetry = _args.length > 0 && _args[0] !== undefined ? _args[0] : false;
137
+ _context.prev = 1;
138
+ _context.next = 4;
134
139
  return this.reachabilityRequest.getClusters(_util.default.getIpVersion(this.webex));
135
- case 3:
140
+ case 4:
136
141
  _yield$this$reachabil = _context.sent;
137
142
  clusters = _yield$this$reachabil.clusters;
138
143
  joinCookie = _yield$this$reachabil.joinCookie;
139
- _context.next = 8;
144
+ return _context.abrupt("return", {
145
+ clusters: clusters,
146
+ joinCookie: joinCookie
147
+ });
148
+ case 10:
149
+ _context.prev = 10;
150
+ _context.t0 = _context["catch"](1);
151
+ if (!isRetry) {
152
+ _context.next = 14;
153
+ break;
154
+ }
155
+ throw _context.t0;
156
+ case 14:
157
+ _loggerProxy.default.logger.error("Reachability:index#getClusters --> Failed with error: ".concat(_context.t0, ", retrying..."));
158
+ return _context.abrupt("return", this.getClusters(true));
159
+ case 16:
160
+ case "end":
161
+ return _context.stop();
162
+ }
163
+ }, _callee, this, [[1, 10]]);
164
+ }));
165
+ function getClusters() {
166
+ return _getClusters.apply(this, arguments);
167
+ }
168
+ return getClusters;
169
+ }()
170
+ /**
171
+ * Gets a list of media clusters from the backend and performs reachability checks on all the clusters
172
+ * @returns {Promise<ReachabilityResults>} reachability results
173
+ * @public
174
+ * @memberof Reachability
175
+ */
176
+ )
177
+ }, {
178
+ key: "gatherReachability",
179
+ value: (function () {
180
+ var _gatherReachability = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
181
+ var _yield$this$getCluste, clusters, joinCookie;
182
+ return _regenerator.default.wrap(function _callee2$(_context2) {
183
+ while (1) switch (_context2.prev = _context2.next) {
184
+ case 0:
185
+ _context2.prev = 0;
186
+ // kick off ip version detection. For now we don't await it, as we're doing it
187
+ // to gather the timings and send them with our reachability metrics
188
+ // @ts-ignore
189
+ this.webex.internal.device.ipNetworkDetector.detect();
190
+ _context2.next = 4;
191
+ return this.getClusters();
192
+ case 4:
193
+ _yield$this$getCluste = _context2.sent;
194
+ clusters = _yield$this$getCluste.clusters;
195
+ joinCookie = _yield$this$getCluste.joinCookie;
196
+ _context2.next = 9;
140
197
  return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageJoinCookie, (0, _stringify.default)(joinCookie));
141
- case 8:
198
+ case 9:
142
199
  this.reachabilityDefer = new _common.Defer();
143
200
 
144
201
  // Perform Reachability Check
145
- _context.next = 11;
202
+ _context2.next = 12;
146
203
  return this.performReachabilityChecks(clusters);
147
- case 11:
148
- return _context.abrupt("return", this.reachabilityDefer.promise);
149
- case 14:
150
- _context.prev = 14;
151
- _context.t0 = _context["catch"](0);
152
- _loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error:", _context.t0);
153
- return _context.abrupt("return", {});
154
- case 18:
204
+ case 12:
205
+ return _context2.abrupt("return", this.reachabilityDefer.promise);
206
+ case 15:
207
+ _context2.prev = 15;
208
+ _context2.t0 = _context2["catch"](0);
209
+ _loggerProxy.default.logger.error("Reachability:index#gatherReachability --> Error:", _context2.t0);
210
+ return _context2.abrupt("return", {});
211
+ case 19:
155
212
  case "end":
156
- return _context.stop();
213
+ return _context2.stop();
157
214
  }
158
- }, _callee, this, [[0, 14]]);
215
+ }, _callee2, this, [[0, 15]]);
159
216
  }));
160
217
  function gatherReachability() {
161
218
  return _gatherReachability.apply(this, arguments);
@@ -172,10 +229,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
172
229
  }, {
173
230
  key: "getReachabilityMetrics",
174
231
  value: (function () {
175
- var _getReachabilityMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
232
+ var _getReachabilityMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
176
233
  var stats, updateStats, resultsJson, results;
177
- return _regenerator.default.wrap(function _callee2$(_context2) {
178
- while (1) switch (_context2.prev = _context2.next) {
234
+ return _regenerator.default.wrap(function _callee3$(_context3) {
235
+ while (1) switch (_context3.prev = _context3.next) {
179
236
  case 0:
180
237
  stats = {
181
238
  reachability_public_udp_success: 0,
@@ -205,29 +262,29 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
205
262
  stats["reachability_".concat(clusterType, "_xtls_").concat(_outcome2)] += 1;
206
263
  }
207
264
  };
208
- _context2.prev = 2;
209
- _context2.next = 5;
265
+ _context3.prev = 2;
266
+ _context3.next = 5;
210
267
  return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
211
268
  case 5:
212
- resultsJson = _context2.sent;
269
+ resultsJson = _context3.sent;
213
270
  results = JSON.parse(resultsJson);
214
271
  (0, _values.default)(results).forEach(function (result) {
215
272
  updateStats(result.isVideoMesh ? 'vmn' : 'public', result);
216
273
  });
217
- _context2.next = 13;
274
+ _context3.next = 13;
218
275
  break;
219
276
  case 10:
220
- _context2.prev = 10;
221
- _context2.t0 = _context2["catch"](2);
277
+ _context3.prev = 10;
278
+ _context3.t0 = _context3["catch"](2);
222
279
  // empty storage, that's ok
223
- _loggerProxy.default.logger.warn('Roap:request#getReachabilityMetrics --> Error parsing reachability data: ', _context2.t0);
280
+ _loggerProxy.default.logger.warn('Roap:request#getReachabilityMetrics --> Error parsing reachability data: ', _context3.t0);
224
281
  case 13:
225
- return _context2.abrupt("return", stats);
282
+ return _context3.abrupt("return", stats);
226
283
  case 14:
227
284
  case "end":
228
- return _context2.stop();
285
+ return _context3.stop();
229
286
  }
230
- }, _callee2, this, [[2, 10]]);
287
+ }, _callee3, this, [[2, 10]]);
231
288
  }));
232
289
  function getReachabilityMetrics() {
233
290
  return _getReachabilityMetrics.apply(this, arguments);
@@ -280,17 +337,17 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
280
337
  }, {
281
338
  key: "getReachabilityResults",
282
339
  value: (function () {
283
- var _getReachabilityResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
340
+ var _getReachabilityResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
284
341
  var _this2 = this;
285
342
  var results, resultsJson, allClusterResults;
286
- return _regenerator.default.wrap(function _callee3$(_context3) {
287
- while (1) switch (_context3.prev = _context3.next) {
343
+ return _regenerator.default.wrap(function _callee4$(_context4) {
344
+ while (1) switch (_context4.prev = _context4.next) {
288
345
  case 0:
289
- _context3.prev = 0;
290
- _context3.next = 3;
346
+ _context4.prev = 0;
347
+ _context4.next = 3;
291
348
  return this.webex.boundedStorage.get(_constants.REACHABILITY.namespace, _constants.REACHABILITY.localStorageResult);
292
349
  case 3:
293
- resultsJson = _context3.sent;
350
+ resultsJson = _context4.sent;
294
351
  allClusterResults = JSON.parse(resultsJson);
295
352
  results = (0, _lodash.mapValues)(allClusterResults, function (clusterResult) {
296
353
  return {
@@ -305,20 +362,20 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
305
362
  })
306
363
  };
307
364
  });
308
- _context3.next = 11;
365
+ _context4.next = 11;
309
366
  break;
310
367
  case 8:
311
- _context3.prev = 8;
312
- _context3.t0 = _context3["catch"](0);
368
+ _context4.prev = 8;
369
+ _context4.t0 = _context4["catch"](0);
313
370
  // empty storage, that's ok
314
- _loggerProxy.default.logger.warn('Roap:request#attachReachabilityData --> Error parsing reachability data: ', _context3.t0);
371
+ _loggerProxy.default.logger.warn('Roap:request#attachReachabilityData --> Error parsing reachability data: ', _context4.t0);
315
372
  case 11:
316
- return _context3.abrupt("return", results);
373
+ return _context4.abrupt("return", results);
317
374
  case 12:
318
375
  case "end":
319
- return _context3.stop();
376
+ return _context4.stop();
320
377
  }
321
- }, _callee3, this, [[0, 8]]);
378
+ }, _callee4, this, [[0, 8]]);
322
379
  }));
323
380
  function getReachabilityResults() {
324
381
  return _getReachabilityResults.apply(this, arguments);
@@ -335,16 +392,16 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
335
392
  }, {
336
393
  key: "isAnyPublicClusterReachable",
337
394
  value: (function () {
338
- var _isAnyPublicClusterReachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
395
+ var _isAnyPublicClusterReachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
339
396
  var reachable, reachabilityData, reachabilityResults;
340
- return _regenerator.default.wrap(function _callee4$(_context4) {
341
- while (1) switch (_context4.prev = _context4.next) {
397
+ return _regenerator.default.wrap(function _callee5$(_context5) {
398
+ while (1) switch (_context5.prev = _context5.next) {
342
399
  case 0:
343
400
  reachable = false; // @ts-ignore
344
- _context4.next = 3;
401
+ _context5.next = 3;
345
402
  return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
346
403
  case 3:
347
- reachabilityData = _context4.sent;
404
+ reachabilityData = _context5.sent;
348
405
  if (reachabilityData) {
349
406
  try {
350
407
  reachabilityResults = JSON.parse(reachabilityData);
@@ -356,12 +413,12 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
356
413
  _loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
357
414
  }
358
415
  }
359
- return _context4.abrupt("return", reachable);
416
+ return _context5.abrupt("return", reachable);
360
417
  case 6:
361
418
  case "end":
362
- return _context4.stop();
419
+ return _context5.stop();
363
420
  }
364
- }, _callee4, this);
421
+ }, _callee5, this);
365
422
  }));
366
423
  function isAnyPublicClusterReachable() {
367
424
  return _isAnyPublicClusterReachable.apply(this, arguments);
@@ -382,16 +439,16 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
382
439
  }, {
383
440
  key: "isWebexMediaBackendUnreachable",
384
441
  value: (function () {
385
- var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
442
+ var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
386
443
  var unreachable, reachabilityData, reachabilityResults, protocols;
387
- return _regenerator.default.wrap(function _callee5$(_context5) {
388
- while (1) switch (_context5.prev = _context5.next) {
444
+ return _regenerator.default.wrap(function _callee6$(_context6) {
445
+ while (1) switch (_context6.prev = _context6.next) {
389
446
  case 0:
390
447
  unreachable = false; // @ts-ignore
391
- _context5.next = 3;
448
+ _context6.next = 3;
392
449
  return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
393
450
  case 3:
394
- reachabilityData = _context5.sent;
451
+ reachabilityData = _context6.sent;
395
452
  if (reachabilityData) {
396
453
  try {
397
454
  reachabilityResults = JSON.parse(reachabilityData);
@@ -429,12 +486,12 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
429
486
  _loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
430
487
  }
431
488
  }
432
- return _context5.abrupt("return", unreachable);
489
+ return _context6.abrupt("return", unreachable);
433
490
  case 6:
434
491
  case "end":
435
- return _context5.stop();
492
+ return _context6.stop();
436
493
  }
437
- }, _callee5, this);
494
+ }, _callee6, this);
438
495
  }));
439
496
  function isWebexMediaBackendUnreachable() {
440
497
  return _isWebexMediaBackendUnreachable.apply(this, arguments);
@@ -591,10 +648,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
591
648
  }, {
592
649
  key: "sendMetric",
593
650
  value: (function () {
594
- var _sendMetric = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6() {
651
+ var _sendMetric = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7() {
595
652
  var results, stats;
596
- return _regenerator.default.wrap(function _callee6$(_context6) {
597
- while (1) switch (_context6.prev = _context6.next) {
653
+ return _regenerator.default.wrap(function _callee7$(_context7) {
654
+ while (1) switch (_context7.prev = _context7.next) {
598
655
  case 0:
599
656
  results = [];
600
657
  (0, _values.default)(this.clusterReachability).forEach(function (clusterReachability) {
@@ -610,14 +667,24 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
610
667
  udp: this.getStatistics(results, 'udp', false),
611
668
  tcp: this.getStatistics(results, 'tcp', false),
612
669
  xtls: this.getStatistics(results, 'xtls', false)
670
+ },
671
+ ipver: {
672
+ // @ts-ignore
673
+ firstIpV4: this.webex.internal.device.ipNetworkDetector.firstIpV4,
674
+ // @ts-ignore
675
+ firstIpV6: this.webex.internal.device.ipNetworkDetector.firstIpV6,
676
+ // @ts-ignore
677
+ firstMdns: this.webex.internal.device.ipNetworkDetector.firstMdns,
678
+ // @ts-ignore
679
+ totalTime: this.webex.internal.device.ipNetworkDetector.totalTime
613
680
  }
614
681
  };
615
682
  _metrics.default.sendBehavioralMetric(_constants2.default.REACHABILITY_COMPLETED, _metrics.default.prepareMetricFields(stats));
616
683
  case 4:
617
684
  case "end":
618
- return _context6.stop();
685
+ return _context7.stop();
619
686
  }
620
- }, _callee6, this);
687
+ }, _callee7, this);
621
688
  }));
622
689
  function sendMetric() {
623
690
  return _sendMetric.apply(this, arguments);
@@ -671,17 +738,17 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
671
738
  }, {
672
739
  key: "storeResults",
673
740
  value: (function () {
674
- var _storeResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee7(results) {
675
- return _regenerator.default.wrap(function _callee7$(_context7) {
676
- while (1) switch (_context7.prev = _context7.next) {
741
+ var _storeResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(results) {
742
+ return _regenerator.default.wrap(function _callee8$(_context8) {
743
+ while (1) switch (_context8.prev = _context8.next) {
677
744
  case 0:
678
- _context7.next = 2;
745
+ _context8.next = 2;
679
746
  return this.webex.boundedStorage.put(this.namespace, _constants.REACHABILITY.localStorageResult, (0, _stringify.default)(results));
680
747
  case 2:
681
748
  case "end":
682
- return _context7.stop();
749
+ return _context8.stop();
683
750
  }
684
- }, _callee7, this);
751
+ }, _callee8, this);
685
752
  }));
686
753
  function storeResults(_x) {
687
754
  return _storeResults.apply(this, arguments);
@@ -715,19 +782,19 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
715
782
  }, {
716
783
  key: "performReachabilityChecks",
717
784
  value: (function () {
718
- var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(clusterList) {
785
+ var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(clusterList) {
719
786
  var _this4 = this;
720
787
  var results, isFirstResult;
721
- return _regenerator.default.wrap(function _callee10$(_context10) {
722
- while (1) switch (_context10.prev = _context10.next) {
788
+ return _regenerator.default.wrap(function _callee11$(_context11) {
789
+ while (1) switch (_context11.prev = _context11.next) {
723
790
  case 0:
724
791
  results = {};
725
792
  this.clusterReachability = {};
726
793
  if (!(!clusterList || !(0, _keys.default)(clusterList).length)) {
727
- _context10.next = 4;
794
+ _context11.next = 4;
728
795
  break;
729
796
  }
730
- return _context10.abrupt("return");
797
+ return _context11.abrupt("return");
731
798
  case 4:
732
799
  _loggerProxy.default.logger.log("Reachability:index#performReachabilityChecks --> doing UDP".concat(
733
800
  // @ts-ignore
@@ -783,7 +850,7 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
783
850
  tcp: true,
784
851
  xtls: true
785
852
  }; // save the initialized results (in case we don't get any "resultReady" events at all)
786
- _context10.next = 11;
853
+ _context11.next = 11;
787
854
  return this.storeResults(results);
788
855
  case 11:
789
856
  // now start the reachability on all the clusters
@@ -791,10 +858,10 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
791
858
  var cluster = clusterList[key];
792
859
  _this4.clusterReachability[key] = new _clusterReachability.ClusterReachability(key, cluster);
793
860
  _this4.clusterReachability[key].on(_clusterReachability.Events.resultReady, /*#__PURE__*/function () {
794
- var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(data) {
861
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(data) {
795
862
  var protocol, result, clientMediaIPs, latencyInMilliseconds, areAllResultsReady;
796
- return _regenerator.default.wrap(function _callee8$(_context8) {
797
- while (1) switch (_context8.prev = _context8.next) {
863
+ return _regenerator.default.wrap(function _callee9$(_context9) {
864
+ while (1) switch (_context9.prev = _context9.next) {
798
865
  case 0:
799
866
  protocol = data.protocol, result = data.result, clientMediaIPs = data.clientMediaIPs, latencyInMilliseconds = data.latencyInMilliseconds;
800
867
  if (isFirstResult[protocol]) {
@@ -811,7 +878,7 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
811
878
  results[key][protocol].result = result;
812
879
  results[key][protocol].clientMediaIPs = clientMediaIPs;
813
880
  results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;
814
- _context8.next = 9;
881
+ _context9.next = 9;
815
882
  return _this4.storeResults(results);
816
883
  case 9:
817
884
  if (areAllResultsReady) {
@@ -827,9 +894,9 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
827
894
  }
828
895
  case 10:
829
896
  case "end":
830
- return _context8.stop();
897
+ return _context9.stop();
831
898
  }
832
- }, _callee8);
899
+ }, _callee9);
833
900
  }));
834
901
  return function (_x3) {
835
902
  return _ref4.apply(this, arguments);
@@ -838,18 +905,18 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
838
905
 
839
906
  // clientMediaIps can be updated independently from the results, so we need to listen for them too
840
907
  _this4.clusterReachability[key].on(_clusterReachability.Events.clientMediaIpsUpdated, /*#__PURE__*/function () {
841
- var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(data) {
842
- return _regenerator.default.wrap(function _callee9$(_context9) {
843
- while (1) switch (_context9.prev = _context9.next) {
908
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(data) {
909
+ return _regenerator.default.wrap(function _callee10$(_context10) {
910
+ while (1) switch (_context10.prev = _context10.next) {
844
911
  case 0:
845
912
  results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;
846
- _context9.next = 3;
913
+ _context10.next = 3;
847
914
  return _this4.storeResults(results);
848
915
  case 3:
849
916
  case "end":
850
- return _context9.stop();
917
+ return _context10.stop();
851
918
  }
852
- }, _callee9);
919
+ }, _callee10);
853
920
  }));
854
921
  return function (_x4) {
855
922
  return _ref5.apply(this, arguments);
@@ -859,9 +926,9 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
859
926
  });
860
927
  case 12:
861
928
  case "end":
862
- return _context10.stop();
929
+ return _context11.stop();
863
930
  }
864
- }, _callee10, this);
931
+ }, _callee11, this);
865
932
  }));
866
933
  function performReachabilityChecks(_x2) {
867
934
  return _performReachabilityChecks.apply(this, arguments);
@@ -1 +1 @@
1
- {"version":3,"names":["_lodash","require","_common","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","_eventsScope","_constants2","_metrics","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","DEFAULT_TIMEOUT","VIDEO_MESH_TIMEOUT","OVERALL_TIMEOUT","Reachability","exports","_EventsScope","_inherits2","_super","webex","_this","_classCallCheck2","_assertThisInitialized2","REACHABILITY","namespace","videoMesh","udp","public","tcp","xtls","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","boundedStorage","put","localStorageJoinCookie","_stringify","reachabilityDefer","Defer","performReachabilityChecks","abrupt","promise","t0","LoggerProxy","logger","error","stop","gatherReachability","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","results","_callee2$","_context2","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","outcome","concat","get","localStorageResult","JSON","parse","_values","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this2","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee5","unreachable","protocols","_callee5$","_context5","tested","undefined","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","name","logUnreachableClusters","list","_ref3","log","areAllPublicClusterResultsReady","isEqual","expectedResultsCount","resultsCount","areAllResultsReady","resolveReachabilityPromise","_this$reachabilityDef","vmnTimer","clearTimeout","publicCloudTimer","resolve","abortClusterReachability","abort","getStatistics","values","map","min","max","average","Math","_toConsumableArray2","mean","_sendMetric","_callee6","_callee6$","_context6","vmn","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","REACHABILITY_COMPLETED","prepareMetricFields","sendMetric","startTimers","_this3","setTimeout","overallTimer","emit","file","function","_storeResults","_callee7","_callee7$","_context7","storeResults","_x","resetResultCounters","_performReachabilityChecks","_callee10","clusterList","_this4","isFirstResult","_callee10$","_context10","config","meetings","experimental","enableTcpReachability","enableTlsReachability","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","on","Events","resultReady","_ref4","_callee8","data","clientMediaIPs","_callee8$","_context8","_x3","clientMediaIpsUpdated","_ref5","_callee9","_callee9$","_context9","_x4","start","_x2","EventsScope"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {isEqual, mapValues, mean} from 'lodash';\n\nimport {Defer} from '@webex/common';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClientMediaIpsUpdatedEventData,\n ClusterReachability,\n ClusterReachabilityResult,\n Events,\n ResultEventData,\n TransportResult,\n} from './clusterReachability';\nimport EventsScope from '../common/events/events-scope';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n// timeouts in seconds\nconst DEFAULT_TIMEOUT = 3;\nconst VIDEO_MESH_TIMEOUT = 1;\nconst OVERALL_TIMEOUT = 15;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability extends EventsScope {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n reachabilityDefer?: Defer;\n\n vmnTimer?: ReturnType<typeof setTimeout>;\n publicCloudTimer?: ReturnType<typeof setTimeout>;\n overallTimer?: ReturnType<typeof setTimeout>;\n\n expectedResultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n resultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n super();\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n this.reachabilityDefer = new Defer();\n\n // Perform Reachability Check\n await this.performReachabilityChecks(clusters);\n\n return this.reachabilityDefer.promise;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none\n * of the media clusters where reachable with any of the protocols. This is done\n * irrespective of the config, so for example:\n * if config.meetings.experimental.enableTlsReachability === false,\n * it will return false, because TLS reachability won't be tested,\n * so we can't say for sure that media backend is unreachable over TLS.\n *\n * @returns {boolean}\n */\n async isWebexMediaBackendUnreachable() {\n let unreachable = false;\n\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n const protocols = {\n udp: {tested: false, reachable: undefined},\n tcp: {tested: false, reachable: undefined},\n xtls: {tested: false, reachable: undefined},\n };\n\n Object.values(reachabilityResults).forEach((result) => {\n Object.keys(protocols).forEach((protocol) => {\n if (\n result[protocol]?.result === 'reachable' ||\n result[protocol]?.result === 'unreachable'\n ) {\n protocols[protocol].tested = true;\n\n // we need at least 1 'reachable' result to mark the whole protocol as reachable\n if (result[protocol].result === 'reachable') {\n protocols[protocol].reachable = true;\n }\n }\n });\n });\n\n unreachable = Object.values(protocols).every(\n (protocol) => protocol.tested && !protocol.reachable\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return unreachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the public clusters\n * In other words, it means that all public clusters are reachable over each protocol,\n * because we only get a \"result\" if we managed to reach a cluster\n *\n * @returns {boolean}\n */\n private areAllPublicClusterResultsReady() {\n return isEqual(this.expectedResultsCount.public, this.resultsCount.public);\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the clusters\n *\n * @returns {boolean}\n */\n private areAllResultsReady() {\n return isEqual(this.expectedResultsCount, this.resultsCount);\n }\n\n /**\n * Resolves the promise returned by gatherReachability() method\n * @returns {void}\n */\n private resolveReachabilityPromise() {\n if (this.vmnTimer) {\n clearTimeout(this.vmnTimer);\n }\n if (this.publicCloudTimer) {\n clearTimeout(this.publicCloudTimer);\n }\n\n this.logUnreachableClusters();\n this.reachabilityDefer?.resolve();\n }\n\n /**\n * Aborts all cluster reachability checks that are in progress\n *\n * @returns {void}\n */\n private abortClusterReachability() {\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n clusterReachability.abort();\n });\n }\n\n /**\n * Helper function for calculating min/max/average values of latency\n *\n * @param {Array<any>} results\n * @param {string} protocol\n * @param {boolean} isVideoMesh\n * @returns {{min:number, max: number, average: number}}\n */\n protected getStatistics(\n results: Array<ClusterReachabilityResult & {isVideoMesh: boolean}>,\n protocol: 'udp' | 'tcp' | 'xtls',\n isVideoMesh: boolean\n ) {\n const values = results\n .filter((result) => result.isVideoMesh === isVideoMesh)\n .filter((result) => result[protocol].result === 'reachable')\n .map((result) => result[protocol].latencyInMilliseconds);\n\n if (values.length === 0) {\n return {\n min: -1,\n max: -1,\n average: -1,\n };\n }\n\n return {\n min: Math.min(...values),\n max: Math.max(...values),\n average: mean(values),\n };\n }\n\n /**\n * Sends a metric with all the statistics about how long reachability took\n *\n * @returns {void}\n */\n protected async sendMetric() {\n const results = [];\n\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n results.push({\n ...clusterReachability.getResult(),\n isVideoMesh: clusterReachability.isVideoMesh,\n });\n });\n\n const stats = {\n vmn: {\n udp: this.getStatistics(results, 'udp', true),\n },\n public: {\n udp: this.getStatistics(results, 'udp', false),\n tcp: this.getStatistics(results, 'tcp', false),\n xtls: this.getStatistics(results, 'xtls', false),\n },\n };\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,\n Metrics.prepareMetricFields(stats)\n );\n }\n\n /**\n * Starts all the timers used for various timeouts\n *\n * @returns {void}\n */\n private startTimers() {\n this.vmnTimer = setTimeout(() => {\n this.vmnTimer = undefined;\n // if we are only missing VMN results, then we don't want to wait for them any longer\n // as they are likely to fail if users are not on corporate network\n if (this.areAllPublicClusterResultsReady()) {\n LoggerProxy.logger.log(\n 'Reachability:index#startTimers --> Reachability checks timed out (VMN timeout)'\n );\n\n this.resolveReachabilityPromise();\n }\n }, VIDEO_MESH_TIMEOUT * 1000);\n\n this.publicCloudTimer = setTimeout(() => {\n this.publicCloudTimer = undefined;\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks timed out (${DEFAULT_TIMEOUT}s)`\n );\n\n // resolve the promise, so that the client won't be blocked waiting on meetings.register() for too long\n this.resolveReachabilityPromise();\n }, DEFAULT_TIMEOUT * 1000);\n\n this.overallTimer = setTimeout(() => {\n this.overallTimer = undefined;\n this.abortClusterReachability();\n this.emit(\n {\n file: 'reachability',\n function: 'overallTimer timeout',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks fully timed out (${OVERALL_TIMEOUT}s)`\n );\n }, OVERALL_TIMEOUT * 1000);\n }\n\n /**\n * Stores given reachability results in local storage\n *\n * @param {ReachabilityResults} results\n * @returns {Promise<void>}\n */\n private async storeResults(results: ReachabilityResults) {\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n }\n\n /**\n * Resets all the internal counters that keep track of the results\n *\n * @returns {void}\n */\n private resetResultCounters() {\n this.expectedResultsCount.videoMesh.udp = 0;\n this.expectedResultsCount.public.udp = 0;\n this.expectedResultsCount.public.tcp = 0;\n this.expectedResultsCount.public.xtls = 0;\n\n this.resultsCount.videoMesh.udp = 0;\n this.resultsCount.public.udp = 0;\n this.resultsCount.public.tcp = 0;\n this.resultsCount.public.xtls = 0;\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<void>} promise that's resolved as soon as the checks are started\n */\n private async performReachabilityChecks(clusterList: ClusterList) {\n const results: ReachabilityResults = {};\n\n this.clusterReachability = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return;\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n this.resetResultCounters();\n this.startTimers();\n\n // sanitize the urls in the clusterList\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n // Linus doesn't support xTLS reachability checks on video mesh nodes\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n // initialize the result for this cluster\n results[key] = {\n udp: {result: cluster.udp.length > 0 ? 'unreachable' : 'untested'},\n tcp: {result: cluster.tcp.length > 0 ? 'unreachable' : 'untested'},\n xtls: {result: cluster.xtls.length > 0 ? 'unreachable' : 'untested'},\n isVideoMesh: cluster.isVideoMesh,\n };\n\n // update expected results counters to include this cluster\n this.expectedResultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'].udp +=\n cluster.udp.length;\n if (!cluster.isVideoMesh) {\n this.expectedResultsCount.public.tcp += cluster.tcp.length;\n this.expectedResultsCount.public.xtls += cluster.xtls.length;\n }\n });\n\n const isFirstResult = {\n udp: true,\n tcp: true,\n xtls: true,\n };\n\n // save the initialized results (in case we don't get any \"resultReady\" events at all)\n await this.storeResults(results);\n\n // now start the reachability on all the clusters\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n this.clusterReachability[key].on(Events.resultReady, async (data: ResultEventData) => {\n const {protocol, result, clientMediaIPs, latencyInMilliseconds} = data;\n\n if (isFirstResult[protocol]) {\n this.emit(\n {\n file: 'reachability',\n function: 'resultReady event handler',\n },\n 'reachability:firstResultAvailable',\n {\n protocol,\n }\n );\n isFirstResult[protocol] = false;\n }\n this.resultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'][protocol] += 1;\n\n const areAllResultsReady = this.areAllResultsReady();\n\n results[key][protocol].result = result;\n results[key][protocol].clientMediaIPs = clientMediaIPs;\n results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;\n\n await this.storeResults(results);\n\n if (areAllResultsReady) {\n clearTimeout(this.overallTimer);\n this.overallTimer = undefined;\n this.emit(\n {\n file: 'reachability',\n function: 'performReachabilityChecks',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#gatherReachability --> Reachability checks fully completed`\n );\n this.resolveReachabilityPromise();\n }\n });\n\n // clientMediaIps can be updated independently from the results, so we need to listen for them too\n this.clusterReachability[key].on(\n Events.clientMediaIpsUpdated,\n async (data: ClientMediaIpsUpdatedEventData) => {\n results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;\n\n await this.storeResults(results);\n }\n );\n\n this.clusterReachability[key].start(); // not awaiting on purpose\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_lodash","require","_common","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","_eventsScope","_constants2","_metrics","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","DEFAULT_TIMEOUT","VIDEO_MESH_TIMEOUT","OVERALL_TIMEOUT","Reachability","exports","_EventsScope","_inherits2","_super","webex","_this","_classCallCheck2","_assertThisInitialized2","REACHABILITY","namespace","videoMesh","udp","public","tcp","xtls","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_getClusters","_asyncToGenerator2","_regenerator","mark","_callee","isRetry","_yield$this$reachabil","clusters","joinCookie","_args","wrap","_callee$","_context","prev","next","undefined","getClusters","MeetingUtil","getIpVersion","sent","abrupt","t0","LoggerProxy","logger","error","concat","stop","_gatherReachability","_callee2","_yield$this$getCluste","_callee2$","_context2","internal","device","ipNetworkDetector","detect","boundedStorage","put","localStorageJoinCookie","_stringify","reachabilityDefer","Defer","performReachabilityChecks","promise","gatherReachability","_getReachabilityMetrics","_callee3","stats","updateStats","resultsJson","results","_callee3$","_context3","reachability_public_udp_success","reachability_public_udp_failed","reachability_public_tcp_success","reachability_public_tcp_failed","reachability_public_xtls_success","reachability_public_xtls_failed","reachability_vmn_udp_success","reachability_vmn_udp_failed","reachability_vmn_tcp_success","reachability_vmn_tcp_failed","reachability_vmn_xtls_success","reachability_vmn_xtls_failed","clusterType","outcome","get","localStorageResult","JSON","parse","_values","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee4","_this2","allClusterResults","_callee4$","_context4","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee5","reachabilityData","reachabilityResults","_callee5$","_context5","catch","some","_result$udp","_result$tcp","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee6","unreachable","protocols","_callee6$","_context6","tested","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","name","logUnreachableClusters","list","_ref3","log","areAllPublicClusterResultsReady","isEqual","expectedResultsCount","resultsCount","areAllResultsReady","resolveReachabilityPromise","_this$reachabilityDef","vmnTimer","clearTimeout","publicCloudTimer","resolve","abortClusterReachability","abort","getStatistics","values","map","min","max","average","Math","_toConsumableArray2","mean","_sendMetric","_callee7","_callee7$","_context7","vmn","ipver","firstIpV4","firstIpV6","firstMdns","totalTime","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","REACHABILITY_COMPLETED","prepareMetricFields","sendMetric","startTimers","_this3","setTimeout","overallTimer","emit","file","function","_storeResults","_callee8","_callee8$","_context8","storeResults","_x","resetResultCounters","_performReachabilityChecks","_callee11","clusterList","_this4","isFirstResult","_callee11$","_context11","config","meetings","experimental","enableTcpReachability","enableTlsReachability","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","on","Events","resultReady","_ref4","_callee9","data","clientMediaIPs","_callee9$","_context9","_x3","clientMediaIpsUpdated","_ref5","_callee10","_callee10$","_context10","_x4","start","_x2","EventsScope"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable class-methods-use-this */\nimport {isEqual, mapValues, mean} from 'lodash';\n\nimport {Defer} from '@webex/common';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport MeetingUtil from '../meeting/util';\n\nimport {REACHABILITY} from '../constants';\n\nimport ReachabilityRequest, {ClusterList} from './request';\nimport {\n ClientMediaIpsUpdatedEventData,\n ClusterReachability,\n ClusterReachabilityResult,\n Events,\n ResultEventData,\n TransportResult,\n} from './clusterReachability';\nimport EventsScope from '../common/events/events-scope';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport Metrics from '../metrics';\n\nexport type ReachabilityMetrics = {\n reachability_public_udp_success: number;\n reachability_public_udp_failed: number;\n reachability_public_tcp_success: number;\n reachability_public_tcp_failed: number;\n reachability_public_xtls_success: number;\n reachability_public_xtls_failed: number;\n reachability_vmn_udp_success: number;\n reachability_vmn_udp_failed: number;\n reachability_vmn_tcp_success: number;\n reachability_vmn_tcp_failed: number;\n reachability_vmn_xtls_success: number;\n reachability_vmn_xtls_failed: number;\n};\n\n/**\n * This is the type that matches what backend expects us to send to them. It is a bit weird, because\n * it uses strings instead of booleans and numbers, but that's what they require.\n */\nexport type TransportResultForBackend = {\n reachable?: 'true' | 'false';\n latencyInMilliseconds?: string;\n clientMediaIPs?: string[];\n untested?: 'true';\n};\n\nexport type ReachabilityResultForBackend = {\n udp: TransportResultForBackend;\n tcp: TransportResultForBackend;\n xtls: TransportResultForBackend;\n};\n\n// this is the type that is required by the backend when we send them reachability results\nexport type ReachabilityResultsForBackend = Record<string, ReachabilityResultForBackend>;\n\n// this is the type used by Reachability class internally and stored in local storage\nexport type ReachabilityResults = Record<\n string,\n ClusterReachabilityResult & {\n isVideoMesh?: boolean;\n }\n>;\n\n// timeouts in seconds\nconst DEFAULT_TIMEOUT = 3;\nconst VIDEO_MESH_TIMEOUT = 1;\nconst OVERALL_TIMEOUT = 15;\n\n/**\n * @class Reachability\n * @export\n */\nexport default class Reachability extends EventsScope {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n reachabilityDefer?: Defer;\n\n vmnTimer?: ReturnType<typeof setTimeout>;\n publicCloudTimer?: ReturnType<typeof setTimeout>;\n overallTimer?: ReturnType<typeof setTimeout>;\n\n expectedResultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n resultsCount = {videoMesh: {udp: 0}, public: {udp: 0, tcp: 0, xtls: 0}};\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\n super();\n this.webex = webex;\n\n /**\n * internal request object for the server\n * @instance\n * @type {Array}\n * @private\n * @memberof Reachability\n */\n this.reachabilityRequest = new ReachabilityRequest(this.webex);\n\n this.clusterReachability = {};\n }\n\n /**\n * Fetches the list of media clusters from the backend\n * @param {boolean} isRetry\n * @private\n * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}\n */\n async getClusters(isRetry = false): Promise<{clusters: ClusterList; joinCookie: any}> {\n try {\n const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(\n MeetingUtil.getIpVersion(this.webex)\n );\n\n return {clusters, joinCookie};\n } catch (error) {\n if (isRetry) {\n throw error;\n }\n\n LoggerProxy.logger.error(\n `Reachability:index#getClusters --> Failed with error: ${error}, retrying...`\n );\n\n return this.getClusters(true);\n }\n }\n\n /**\n * Gets a list of media clusters from the backend and performs reachability checks on all the clusters\n * @returns {Promise<ReachabilityResults>} reachability results\n * @public\n * @memberof Reachability\n */\n public async gatherReachability(): Promise<ReachabilityResults> {\n // Fetch clusters and measure latency\n try {\n // kick off ip version detection. For now we don't await it, as we're doing it\n // to gather the timings and send them with our reachability metrics\n // @ts-ignore\n this.webex.internal.device.ipNetworkDetector.detect();\n\n const {clusters, joinCookie} = await this.getClusters();\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n this.reachabilityDefer = new Defer();\n\n // Perform Reachability Check\n await this.performReachabilityChecks(clusters);\n\n return this.reachabilityDefer.promise;\n } catch (error) {\n LoggerProxy.logger.error(`Reachability:index#gatherReachability --> Error:`, error);\n\n return {};\n }\n }\n\n /**\n * Returns statistics about last reachability results. The returned value is an object\n * with a flat list of properties so that it can be easily sent with metrics\n *\n * @returns {Promise} Promise with metrics values, it never rejects/throws.\n */\n async getReachabilityMetrics(): Promise<ReachabilityMetrics> {\n const stats: ReachabilityMetrics = {\n reachability_public_udp_success: 0,\n reachability_public_udp_failed: 0,\n reachability_public_tcp_success: 0,\n reachability_public_tcp_failed: 0,\n reachability_public_xtls_success: 0,\n reachability_public_xtls_failed: 0,\n reachability_vmn_udp_success: 0,\n reachability_vmn_udp_failed: 0,\n reachability_vmn_tcp_success: 0,\n reachability_vmn_tcp_failed: 0,\n reachability_vmn_xtls_success: 0,\n reachability_vmn_xtls_failed: 0,\n };\n\n const updateStats = (clusterType: 'public' | 'vmn', result: ClusterReachabilityResult) => {\n if (result.udp && result.udp.result !== 'untested') {\n const outcome = result.udp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_udp_${outcome}`] += 1;\n }\n if (result.tcp && result.tcp.result !== 'untested') {\n const outcome = result.tcp.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_tcp_${outcome}`] += 1;\n }\n if (result.xtls && result.xtls.result !== 'untested') {\n const outcome = result.xtls.result === 'reachable' ? 'success' : 'failed';\n stats[`reachability_${clusterType}_xtls_${outcome}`] += 1;\n }\n };\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const results: ReachabilityResults = JSON.parse(resultsJson);\n\n Object.values(results).forEach((result) => {\n updateStats(result.isVideoMesh ? 'vmn' : 'public', result);\n });\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#getReachabilityMetrics --> Error parsing reachability data: ',\n e\n );\n }\n\n return stats;\n }\n\n /**\n * Maps our internal transport result to the format that backend expects\n * @param {TransportResult} transportResult\n * @returns {TransportResultForBackend}\n */\n private mapTransportResultToBackendDataFormat(\n transportResult: TransportResult\n ): TransportResultForBackend {\n const output: TransportResultForBackend = {};\n\n for (const [key, value] of Object.entries(transportResult)) {\n switch (key) {\n case 'result':\n switch (value) {\n case 'reachable':\n output.reachable = 'true';\n break;\n case 'unreachable':\n output.reachable = 'false';\n break;\n case 'untested':\n output.untested = 'true';\n break;\n }\n break;\n case 'latencyInMilliseconds':\n output.latencyInMilliseconds = value.toString();\n break;\n default:\n output[key] = value;\n }\n }\n\n return output;\n }\n\n /**\n * Reachability results as an object in the format that backend expects\n *\n * @returns {any} reachability results that need to be sent to the backend\n */\n async getReachabilityResults(): Promise<ReachabilityResultsForBackend | undefined> {\n let results: ReachabilityResultsForBackend;\n\n try {\n // @ts-ignore\n const resultsJson = await this.webex.boundedStorage.get(\n REACHABILITY.namespace,\n REACHABILITY.localStorageResult\n );\n\n const allClusterResults: ReachabilityResults = JSON.parse(resultsJson);\n\n results = mapValues(allClusterResults, (clusterResult) => ({\n udp: this.mapTransportResultToBackendDataFormat(clusterResult.udp || {result: 'untested'}),\n tcp: this.mapTransportResultToBackendDataFormat(clusterResult.tcp || {result: 'untested'}),\n xtls: this.mapTransportResultToBackendDataFormat(\n clusterResult.xtls || {result: 'untested'}\n ),\n }));\n } catch (e) {\n // empty storage, that's ok\n LoggerProxy.logger.warn(\n 'Roap:request#attachReachabilityData --> Error parsing reachability data: ',\n e\n );\n }\n\n return results;\n }\n\n /**\n * fetches reachability data and checks for cluster reachability\n * @returns {boolean}\n * @public\n * @memberof Reachability\n */\n async isAnyPublicClusterReachable() {\n let reachable = false;\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n reachable = Object.values(reachabilityResults).some(\n (result) =>\n !result.isVideoMesh &&\n (result.udp?.result === 'reachable' || result.tcp?.result === 'reachable')\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return reachable;\n }\n\n /**\n * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none\n * of the media clusters where reachable with any of the protocols. This is done\n * irrespective of the config, so for example:\n * if config.meetings.experimental.enableTlsReachability === false,\n * it will return false, because TLS reachability won't be tested,\n * so we can't say for sure that media backend is unreachable over TLS.\n *\n * @returns {boolean}\n */\n async isWebexMediaBackendUnreachable() {\n let unreachable = false;\n\n // @ts-ignore\n const reachabilityData = await this.webex.boundedStorage\n .get(this.namespace, REACHABILITY.localStorageResult)\n .catch(() => {});\n\n if (reachabilityData) {\n try {\n const reachabilityResults: ReachabilityResults = JSON.parse(reachabilityData);\n\n const protocols = {\n udp: {tested: false, reachable: undefined},\n tcp: {tested: false, reachable: undefined},\n xtls: {tested: false, reachable: undefined},\n };\n\n Object.values(reachabilityResults).forEach((result) => {\n Object.keys(protocols).forEach((protocol) => {\n if (\n result[protocol]?.result === 'reachable' ||\n result[protocol]?.result === 'unreachable'\n ) {\n protocols[protocol].tested = true;\n\n // we need at least 1 'reachable' result to mark the whole protocol as reachable\n if (result[protocol].result === 'reachable') {\n protocols[protocol].reachable = true;\n }\n }\n });\n });\n\n unreachable = Object.values(protocols).every(\n (protocol) => protocol.tested && !protocol.reachable\n );\n } catch (e) {\n LoggerProxy.logger.error(\n `Roap:request#attachReachabilityData --> Error in parsing reachability data: ${e}`\n );\n }\n }\n\n return unreachable;\n }\n\n /**\n * Get list of all unreachable clusters\n * @returns {array} Unreachable clusters\n * @private\n * @memberof Reachability\n */\n private getUnreachableClusters(): Array<{name: string; protocol: string}> {\n const unreachableList = [];\n\n Object.entries(this.clusterReachability).forEach(([key, clusterReachability]) => {\n const result = clusterReachability.getResult();\n\n if (result.udp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'udp'});\n }\n if (result.tcp.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'tcp'});\n }\n if (result.xtls.result === 'unreachable') {\n unreachableList.push({name: key, protocol: 'xtls'});\n }\n });\n\n return unreachableList;\n }\n\n /**\n * Make a log of unreachable clusters.\n * @returns {undefined}\n * @private\n * @memberof Reachability\n */\n private logUnreachableClusters() {\n const list = this.getUnreachableClusters();\n\n list.forEach(({name, protocol}) => {\n LoggerProxy.logger.log(\n `Reachability:index#logUnreachableClusters --> failed to reach ${name} over ${protocol}`\n );\n });\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the public clusters\n * In other words, it means that all public clusters are reachable over each protocol,\n * because we only get a \"result\" if we managed to reach a cluster\n *\n * @returns {boolean}\n */\n private areAllPublicClusterResultsReady() {\n return isEqual(this.expectedResultsCount.public, this.resultsCount.public);\n }\n\n /**\n * Returns true if we've obtained all the reachability results for all the clusters\n *\n * @returns {boolean}\n */\n private areAllResultsReady() {\n return isEqual(this.expectedResultsCount, this.resultsCount);\n }\n\n /**\n * Resolves the promise returned by gatherReachability() method\n * @returns {void}\n */\n private resolveReachabilityPromise() {\n if (this.vmnTimer) {\n clearTimeout(this.vmnTimer);\n }\n if (this.publicCloudTimer) {\n clearTimeout(this.publicCloudTimer);\n }\n\n this.logUnreachableClusters();\n this.reachabilityDefer?.resolve();\n }\n\n /**\n * Aborts all cluster reachability checks that are in progress\n *\n * @returns {void}\n */\n private abortClusterReachability() {\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n clusterReachability.abort();\n });\n }\n\n /**\n * Helper function for calculating min/max/average values of latency\n *\n * @param {Array<any>} results\n * @param {string} protocol\n * @param {boolean} isVideoMesh\n * @returns {{min:number, max: number, average: number}}\n */\n protected getStatistics(\n results: Array<ClusterReachabilityResult & {isVideoMesh: boolean}>,\n protocol: 'udp' | 'tcp' | 'xtls',\n isVideoMesh: boolean\n ) {\n const values = results\n .filter((result) => result.isVideoMesh === isVideoMesh)\n .filter((result) => result[protocol].result === 'reachable')\n .map((result) => result[protocol].latencyInMilliseconds);\n\n if (values.length === 0) {\n return {\n min: -1,\n max: -1,\n average: -1,\n };\n }\n\n return {\n min: Math.min(...values),\n max: Math.max(...values),\n average: mean(values),\n };\n }\n\n /**\n * Sends a metric with all the statistics about how long reachability took\n *\n * @returns {void}\n */\n protected async sendMetric() {\n const results = [];\n\n Object.values(this.clusterReachability).forEach((clusterReachability) => {\n results.push({\n ...clusterReachability.getResult(),\n isVideoMesh: clusterReachability.isVideoMesh,\n });\n });\n\n const stats = {\n vmn: {\n udp: this.getStatistics(results, 'udp', true),\n },\n public: {\n udp: this.getStatistics(results, 'udp', false),\n tcp: this.getStatistics(results, 'tcp', false),\n xtls: this.getStatistics(results, 'xtls', false),\n },\n ipver: {\n // @ts-ignore\n firstIpV4: this.webex.internal.device.ipNetworkDetector.firstIpV4,\n // @ts-ignore\n firstIpV6: this.webex.internal.device.ipNetworkDetector.firstIpV6,\n // @ts-ignore\n firstMdns: this.webex.internal.device.ipNetworkDetector.firstMdns,\n // @ts-ignore\n totalTime: this.webex.internal.device.ipNetworkDetector.totalTime,\n },\n };\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,\n Metrics.prepareMetricFields(stats)\n );\n }\n\n /**\n * Starts all the timers used for various timeouts\n *\n * @returns {void}\n */\n private startTimers() {\n this.vmnTimer = setTimeout(() => {\n this.vmnTimer = undefined;\n // if we are only missing VMN results, then we don't want to wait for them any longer\n // as they are likely to fail if users are not on corporate network\n if (this.areAllPublicClusterResultsReady()) {\n LoggerProxy.logger.log(\n 'Reachability:index#startTimers --> Reachability checks timed out (VMN timeout)'\n );\n\n this.resolveReachabilityPromise();\n }\n }, VIDEO_MESH_TIMEOUT * 1000);\n\n this.publicCloudTimer = setTimeout(() => {\n this.publicCloudTimer = undefined;\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks timed out (${DEFAULT_TIMEOUT}s)`\n );\n\n // resolve the promise, so that the client won't be blocked waiting on meetings.register() for too long\n this.resolveReachabilityPromise();\n }, DEFAULT_TIMEOUT * 1000);\n\n this.overallTimer = setTimeout(() => {\n this.overallTimer = undefined;\n this.abortClusterReachability();\n this.emit(\n {\n file: 'reachability',\n function: 'overallTimer timeout',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#startTimers --> Reachability checks fully timed out (${OVERALL_TIMEOUT}s)`\n );\n }, OVERALL_TIMEOUT * 1000);\n }\n\n /**\n * Stores given reachability results in local storage\n *\n * @param {ReachabilityResults} results\n * @returns {Promise<void>}\n */\n private async storeResults(results: ReachabilityResults) {\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n }\n\n /**\n * Resets all the internal counters that keep track of the results\n *\n * @returns {void}\n */\n private resetResultCounters() {\n this.expectedResultsCount.videoMesh.udp = 0;\n this.expectedResultsCount.public.udp = 0;\n this.expectedResultsCount.public.tcp = 0;\n this.expectedResultsCount.public.xtls = 0;\n\n this.resultsCount.videoMesh.udp = 0;\n this.resultsCount.public.udp = 0;\n this.resultsCount.public.tcp = 0;\n this.resultsCount.public.xtls = 0;\n }\n\n /**\n * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<void>} promise that's resolved as soon as the checks are started\n */\n private async performReachabilityChecks(clusterList: ClusterList) {\n const results: ReachabilityResults = {};\n\n this.clusterReachability = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return;\n }\n\n LoggerProxy.logger.log(\n `Reachability:index#performReachabilityChecks --> doing UDP${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability ? ',TCP' : ''\n }${\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability ? ',TLS' : ''\n } reachability checks`\n );\n\n this.resetResultCounters();\n this.startTimers();\n\n // sanitize the urls in the clusterList\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n // Linus doesn't support TCP reachability checks on video mesh nodes\n const includeTcpReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTcpReachability && !cluster.isVideoMesh;\n\n if (!includeTcpReachability) {\n cluster.tcp = [];\n }\n\n // Linus doesn't support xTLS reachability checks on video mesh nodes\n const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n // initialize the result for this cluster\n results[key] = {\n udp: {result: cluster.udp.length > 0 ? 'unreachable' : 'untested'},\n tcp: {result: cluster.tcp.length > 0 ? 'unreachable' : 'untested'},\n xtls: {result: cluster.xtls.length > 0 ? 'unreachable' : 'untested'},\n isVideoMesh: cluster.isVideoMesh,\n };\n\n // update expected results counters to include this cluster\n this.expectedResultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'].udp +=\n cluster.udp.length;\n if (!cluster.isVideoMesh) {\n this.expectedResultsCount.public.tcp += cluster.tcp.length;\n this.expectedResultsCount.public.xtls += cluster.xtls.length;\n }\n });\n\n const isFirstResult = {\n udp: true,\n tcp: true,\n xtls: true,\n };\n\n // save the initialized results (in case we don't get any \"resultReady\" events at all)\n await this.storeResults(results);\n\n // now start the reachability on all the clusters\n Object.keys(clusterList).forEach((key) => {\n const cluster = clusterList[key];\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n this.clusterReachability[key].on(Events.resultReady, async (data: ResultEventData) => {\n const {protocol, result, clientMediaIPs, latencyInMilliseconds} = data;\n\n if (isFirstResult[protocol]) {\n this.emit(\n {\n file: 'reachability',\n function: 'resultReady event handler',\n },\n 'reachability:firstResultAvailable',\n {\n protocol,\n }\n );\n isFirstResult[protocol] = false;\n }\n this.resultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'][protocol] += 1;\n\n const areAllResultsReady = this.areAllResultsReady();\n\n results[key][protocol].result = result;\n results[key][protocol].clientMediaIPs = clientMediaIPs;\n results[key][protocol].latencyInMilliseconds = latencyInMilliseconds;\n\n await this.storeResults(results);\n\n if (areAllResultsReady) {\n clearTimeout(this.overallTimer);\n this.overallTimer = undefined;\n this.emit(\n {\n file: 'reachability',\n function: 'performReachabilityChecks',\n },\n 'reachability:done',\n {}\n );\n this.sendMetric();\n\n LoggerProxy.logger.log(\n `Reachability:index#gatherReachability --> Reachability checks fully completed`\n );\n this.resolveReachabilityPromise();\n }\n });\n\n // clientMediaIps can be updated independently from the results, so we need to listen for them too\n this.clusterReachability[key].on(\n Events.clientMediaIpsUpdated,\n async (data: ClientMediaIpsUpdatedEventData) => {\n results[key][data.protocol].clientMediaIPs = data.clientMediaIPs;\n\n await this.storeResults(results);\n }\n );\n\n this.clusterReachability[key].start(); // not awaiting on purpose\n });\n }\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
4
  import { Defer } from '@webex/common';
5
- import ReachabilityRequest from './request';
5
+ import ReachabilityRequest, { ClusterList } from './request';
6
6
  import { ClusterReachability, ClusterReachabilityResult } from './clusterReachability';
7
7
  import EventsScope from '../common/events/events-scope';
8
8
  export type ReachabilityMetrics = {
@@ -79,6 +79,16 @@ export default class Reachability extends EventsScope {
79
79
  * @memberof Reachability
80
80
  */
81
81
  constructor(webex: object);
82
+ /**
83
+ * Fetches the list of media clusters from the backend
84
+ * @param {boolean} isRetry
85
+ * @private
86
+ * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
87
+ */
88
+ getClusters(isRetry?: boolean): Promise<{
89
+ clusters: ClusterList;
90
+ joinCookie: any;
91
+ }>;
82
92
  /**
83
93
  * Gets a list of media clusters from the backend and performs reachability checks on all the clusters
84
94
  * @returns {Promise<ReachabilityResults>} reachability results
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
62
62
  updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
63
63
  this.set('canManageWebcast', canManageWebcast);
64
64
  },
65
- version: "3.4.0-next.5"
65
+ version: "3.4.0-next.7"
66
66
  });
67
67
  var _default = exports.default = Webinar;
68
68
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.4.0-next.5",
46
+ "@webex/plugin-meetings": "3.4.0-next.7",
47
47
  "@webex/plugin-rooms": "3.4.0-next.1",
48
48
  "@webex/test-helper-chai": "3.4.0-next.1",
49
49
  "@webex/test-helper-mocha": "3.4.0-next.1",
@@ -70,7 +70,7 @@
70
70
  "@webex/internal-plugin-metrics": "3.4.0-next.1",
71
71
  "@webex/internal-plugin-support": "3.4.0-next.1",
72
72
  "@webex/internal-plugin-user": "3.4.0-next.1",
73
- "@webex/internal-plugin-voicea": "3.4.0-next.5",
73
+ "@webex/internal-plugin-voicea": "3.4.0-next.7",
74
74
  "@webex/media-helpers": "3.4.0-next.2",
75
75
  "@webex/plugin-people": "3.4.0-next.1",
76
76
  "@webex/plugin-rooms": "3.4.0-next.1",
@@ -91,5 +91,5 @@
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.4.0-next.5"
94
+ "version": "3.4.0-next.7"
95
95
  }
@@ -114,6 +114,32 @@ export default class Reachability extends EventsScope {
114
114
  this.clusterReachability = {};
115
115
  }
116
116
 
117
+ /**
118
+ * Fetches the list of media clusters from the backend
119
+ * @param {boolean} isRetry
120
+ * @private
121
+ * @returns {Promise<{clusters: ClusterList, joinCookie: any}>}
122
+ */
123
+ async getClusters(isRetry = false): Promise<{clusters: ClusterList; joinCookie: any}> {
124
+ try {
125
+ const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
126
+ MeetingUtil.getIpVersion(this.webex)
127
+ );
128
+
129
+ return {clusters, joinCookie};
130
+ } catch (error) {
131
+ if (isRetry) {
132
+ throw error;
133
+ }
134
+
135
+ LoggerProxy.logger.error(
136
+ `Reachability:index#getClusters --> Failed with error: ${error}, retrying...`
137
+ );
138
+
139
+ return this.getClusters(true);
140
+ }
141
+ }
142
+
117
143
  /**
118
144
  * Gets a list of media clusters from the backend and performs reachability checks on all the clusters
119
145
  * @returns {Promise<ReachabilityResults>} reachability results
@@ -123,9 +149,12 @@ export default class Reachability extends EventsScope {
123
149
  public async gatherReachability(): Promise<ReachabilityResults> {
124
150
  // Fetch clusters and measure latency
125
151
  try {
126
- const {clusters, joinCookie} = await this.reachabilityRequest.getClusters(
127
- MeetingUtil.getIpVersion(this.webex)
128
- );
152
+ // kick off ip version detection. For now we don't await it, as we're doing it
153
+ // to gather the timings and send them with our reachability metrics
154
+ // @ts-ignore
155
+ this.webex.internal.device.ipNetworkDetector.detect();
156
+
157
+ const {clusters, joinCookie} = await this.getClusters();
129
158
 
130
159
  // @ts-ignore
131
160
  await this.webex.boundedStorage.put(
@@ -513,6 +542,16 @@ export default class Reachability extends EventsScope {
513
542
  tcp: this.getStatistics(results, 'tcp', false),
514
543
  xtls: this.getStatistics(results, 'xtls', false),
515
544
  },
545
+ ipver: {
546
+ // @ts-ignore
547
+ firstIpV4: this.webex.internal.device.ipNetworkDetector.firstIpV4,
548
+ // @ts-ignore
549
+ firstIpV6: this.webex.internal.device.ipNetworkDetector.firstIpV6,
550
+ // @ts-ignore
551
+ firstMdns: this.webex.internal.device.ipNetworkDetector.firstMdns,
552
+ // @ts-ignore
553
+ totalTime: this.webex.internal.device.ipNetworkDetector.totalTime,
554
+ },
516
555
  };
517
556
  Metrics.sendBehavioralMetric(
518
557
  BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,
@@ -7,7 +7,7 @@ import Reachability, {
7
7
  ReachabilityResults,
8
8
  ReachabilityResultsForBackend,
9
9
  } from '@webex/plugin-meetings/src/reachability/';
10
- import { ClusterNode } from '../../../../src/reachability/request';
10
+ import {ClusterNode} from '../../../../src/reachability/request';
11
11
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
12
12
  import * as ClusterReachabilityModule from '@webex/plugin-meetings/src/reachability/clusterReachability';
13
13
  import Metrics from '@webex/plugin-meetings/src/metrics';
@@ -145,7 +145,6 @@ describe('isAnyPublicClusterReachable', () => {
145
145
  });
146
146
  });
147
147
 
148
-
149
148
  describe('isWebexMediaBackendUnreachable', () => {
150
149
  let webex;
151
150
 
@@ -486,6 +485,16 @@ describe('gatherReachability', () => {
486
485
  JSON.stringify({old: 'joinCookie'})
487
486
  );
488
487
 
488
+ webex.internal.device.ipNetworkDetector = {
489
+ supportsIpV4: false,
490
+ supportsIpV6: false,
491
+ firstIpV4: -1,
492
+ firstIpV6: -1,
493
+ firstMdns: -1,
494
+ totalTime: -1,
495
+ detect: sinon.stub().resolves(),
496
+ };
497
+
489
498
  clock = sinon.useFakeTimers();
490
499
 
491
500
  mockClusterReachabilityInstances = {};
@@ -1035,6 +1044,15 @@ describe('gatherReachability', () => {
1035
1044
  enableTlsReachability: true,
1036
1045
  };
1037
1046
 
1047
+ // the metrics related to ipver are not tested in these tests and are all the same, so setting them up here
1048
+ const expectedMetricsFull = {
1049
+ ...expectedMetrics,
1050
+ ipver_firstIpV4: -1,
1051
+ ipver_firstIpV6: -1,
1052
+ ipver_firstMdns: -1,
1053
+ ipver_totalTime: -1,
1054
+ };
1055
+
1038
1056
  const receivedEvents = {
1039
1057
  done: 0,
1040
1058
  firstResultAvailable: {
@@ -1119,11 +1137,89 @@ describe('gatherReachability', () => {
1119
1137
  assert.calledWith(
1120
1138
  Metrics.sendBehavioralMetric,
1121
1139
  'js_sdk_reachability_completed',
1122
- expectedMetrics
1140
+ expectedMetricsFull
1123
1141
  );
1124
1142
  })
1125
1143
  );
1126
1144
 
1145
+ it(`starts ip network version detection and includes the results in the metrics`, async () => {
1146
+ webex.config.meetings.experimental = {
1147
+ enableTcpReachability: true,
1148
+ enableTlsReachability: true,
1149
+ };
1150
+ webex.internal.device.ipNetworkDetector = {
1151
+ supportsIpV4: true,
1152
+ supportsIpV6: true,
1153
+ firstIpV4: 10,
1154
+ firstIpV6: 20,
1155
+ firstMdns: 30,
1156
+ totalTime: 40,
1157
+ detect: sinon.stub().resolves(),
1158
+ };
1159
+
1160
+ const receivedEvents = {
1161
+ done: 0,
1162
+ };
1163
+
1164
+ const reachability = new Reachability(webex);
1165
+
1166
+ reachability.on('reachability:done', () => {
1167
+ receivedEvents.done += 1;
1168
+ });
1169
+
1170
+ // simulate having just 1 cluster, we don't need more for this test
1171
+ reachability.reachabilityRequest.getClusters = sinon.stub().returns({
1172
+ clusters: {
1173
+ publicCluster: {
1174
+ udp: ['udp-url'],
1175
+ tcp: [],
1176
+ xtls: [],
1177
+ isVideoMesh: false,
1178
+ },
1179
+ },
1180
+ joinCookie: {id: 'id'},
1181
+ });
1182
+
1183
+ const resultPromise = reachability.gatherReachability();
1184
+
1185
+ await testUtils.flushPromises();
1186
+
1187
+ // trigger mock result events from ClusterReachability instance
1188
+ mockClusterReachabilityInstances['publicCluster'].emitFakeResult('udp', {
1189
+ result: 'reachable',
1190
+ clientMediaIPs: ['1.2.3.4'],
1191
+ latencyInMilliseconds: 100,
1192
+ });
1193
+
1194
+ await resultPromise;
1195
+
1196
+ // check events emitted by Reachability class
1197
+ assert.equal(receivedEvents['done'], 1);
1198
+
1199
+ // and that ip network detection was started
1200
+ assert.calledOnceWithExactly(webex.internal.device.ipNetworkDetector.detect);
1201
+
1202
+ // finally, check the metrics - they should contain values from ipNetworkDetector
1203
+ assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
1204
+ vmn_udp_min: -1,
1205
+ vmn_udp_max: -1,
1206
+ vmn_udp_average: -1,
1207
+ public_udp_min: 100,
1208
+ public_udp_max: 100,
1209
+ public_udp_average: 100,
1210
+ public_tcp_min: -1,
1211
+ public_tcp_max: -1,
1212
+ public_tcp_average: -1,
1213
+ public_xtls_min: -1,
1214
+ public_xtls_max: -1,
1215
+ public_xtls_average: -1,
1216
+ ipver_firstIpV4: webex.internal.device.ipNetworkDetector.firstIpV4,
1217
+ ipver_firstIpV6: webex.internal.device.ipNetworkDetector.firstIpV6,
1218
+ ipver_firstMdns: webex.internal.device.ipNetworkDetector.firstMdns,
1219
+ ipver_totalTime: webex.internal.device.ipNetworkDetector.totalTime,
1220
+ });
1221
+ });
1222
+
1127
1223
  it('keeps updating reachability results after the 3s public cloud timeout expires', async () => {
1128
1224
  webex.config.meetings.experimental = {
1129
1225
  enableTcpReachability: true,
@@ -1466,6 +1562,70 @@ describe('gatherReachability', () => {
1466
1562
  xtls: [], // empty list because TLS is disabled in config
1467
1563
  });
1468
1564
  });
1565
+
1566
+ it('retry of getClusters is succesfull', async () => {
1567
+ webex.config.meetings.experimental = {
1568
+ enableTcpReachability: true,
1569
+ enableTlsReachability: false,
1570
+ };
1571
+
1572
+ const getClustersResult = {
1573
+ clusters: {
1574
+ 'cluster name': {
1575
+ udp: ['testUDP1', 'testUDP2'],
1576
+ tcp: ['testTCP1', 'testTCP2'],
1577
+ xtls: ['testXTLS1', 'testXTLS2'],
1578
+ isVideoMesh: false,
1579
+ },
1580
+ },
1581
+ joinCookie: {id: 'id'},
1582
+ };
1583
+
1584
+ const reachability = new Reachability(webex);
1585
+
1586
+ let getClustersCallCount = 0;
1587
+
1588
+ reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
1589
+ getClustersCallCount++;
1590
+
1591
+ if (getClustersCallCount == 1) {
1592
+ throw new Error('fake error');
1593
+ }
1594
+
1595
+ return getClustersResult;
1596
+ });
1597
+
1598
+ const promise = reachability.gatherReachability();
1599
+
1600
+ await simulateTimeout();
1601
+ await promise;
1602
+
1603
+ assert.equal(getClustersCallCount, 2);
1604
+
1605
+ assert.calledOnce(clusterReachabilityCtorStub);
1606
+ });
1607
+
1608
+ it('two failed calls to getClusters', async () => {
1609
+ const reachability = new Reachability(webex);
1610
+
1611
+ let getClustersCallCount = 0;
1612
+
1613
+ reachability.reachabilityRequest.getClusters = sinon.stub().callsFake(() => {
1614
+ getClustersCallCount++;
1615
+
1616
+ throw new Error('fake error');
1617
+ });
1618
+
1619
+ const promise = reachability.gatherReachability();
1620
+
1621
+ await simulateTimeout();
1622
+
1623
+ await promise;
1624
+
1625
+ assert.equal(getClustersCallCount, 2);
1626
+
1627
+ assert.neverCalledWith(clusterReachabilityCtorStub);
1628
+ });
1469
1629
  });
1470
1630
 
1471
1631
  describe('getReachabilityResults', () => {