@webex/plugin-meetings 3.3.0 → 3.3.1

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 (35) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +4 -2
  4. package/dist/constants.js.map +1 -1
  5. package/dist/interpretation/index.js +1 -1
  6. package/dist/interpretation/siLanguage.js +1 -1
  7. package/dist/mediaQualityMetrics/config.js +10 -10
  8. package/dist/mediaQualityMetrics/config.js.map +1 -1
  9. package/dist/meeting/index.js +21 -8
  10. package/dist/meeting/index.js.map +1 -1
  11. package/dist/meetings/index.js +6 -1
  12. package/dist/meetings/index.js.map +1 -1
  13. package/dist/reachability/index.js +82 -9
  14. package/dist/reachability/index.js.map +1 -1
  15. package/dist/statsAnalyzer/index.js +4 -2
  16. package/dist/statsAnalyzer/index.js.map +1 -1
  17. package/dist/statsAnalyzer/mqaUtil.js +14 -0
  18. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  19. package/dist/types/constants.d.ts +2 -1
  20. package/dist/types/mediaQualityMetrics/config.d.ts +8 -2
  21. package/dist/types/meeting/index.d.ts +8 -0
  22. package/dist/types/reachability/index.d.ts +11 -0
  23. package/dist/webinar/index.js +1 -1
  24. package/package.json +22 -22
  25. package/src/constants.ts +2 -1
  26. package/src/mediaQualityMetrics/config.ts +13 -7
  27. package/src/meeting/index.ts +23 -9
  28. package/src/meetings/index.ts +7 -2
  29. package/src/reachability/index.ts +57 -0
  30. package/src/statsAnalyzer/index.ts +6 -3
  31. package/src/statsAnalyzer/mqaUtil.ts +18 -0
  32. package/test/unit/spec/meeting/index.js +28 -8
  33. package/test/unit/spec/meetings/index.js +38 -15
  34. package/test/unit/spec/reachability/index.ts +266 -0
  35. package/test/unit/spec/stats-analyzer/index.js +89 -8
@@ -317,6 +317,79 @@ var Reachability = exports.default = /*#__PURE__*/function () {
317
317
  }
318
318
  return isAnyPublicClusterReachable;
319
319
  }()
320
+ /**
321
+ * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none
322
+ * of the media clusters where reachable with any of the protocols. This is done
323
+ * irrespective of the config, so for example:
324
+ * if config.meetings.experimental.enableTlsReachability === false,
325
+ * it will return false, because TLS reachability won't be tested,
326
+ * so we can't say for sure that media backend is unreachable over TLS.
327
+ *
328
+ * @returns {boolean}
329
+ */
330
+ )
331
+ }, {
332
+ key: "isWebexMediaBackendUnreachable",
333
+ value: (function () {
334
+ var _isWebexMediaBackendUnreachable = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
335
+ var unreachable, reachabilityData, reachabilityResults, protocols;
336
+ return _regenerator.default.wrap(function _callee5$(_context5) {
337
+ while (1) switch (_context5.prev = _context5.next) {
338
+ case 0:
339
+ unreachable = false; // @ts-ignore
340
+ _context5.next = 3;
341
+ return this.webex.boundedStorage.get(this.namespace, _constants.REACHABILITY.localStorageResult).catch(function () {});
342
+ case 3:
343
+ reachabilityData = _context5.sent;
344
+ if (reachabilityData) {
345
+ try {
346
+ reachabilityResults = JSON.parse(reachabilityData);
347
+ protocols = {
348
+ udp: {
349
+ tested: false,
350
+ reachable: undefined
351
+ },
352
+ tcp: {
353
+ tested: false,
354
+ reachable: undefined
355
+ },
356
+ xtls: {
357
+ tested: false,
358
+ reachable: undefined
359
+ }
360
+ };
361
+ (0, _values.default)(reachabilityResults).forEach(function (result) {
362
+ (0, _keys.default)(protocols).forEach(function (protocol) {
363
+ var _result$protocol, _result$protocol2;
364
+ if (((_result$protocol = result[protocol]) === null || _result$protocol === void 0 ? void 0 : _result$protocol.result) === 'reachable' || ((_result$protocol2 = result[protocol]) === null || _result$protocol2 === void 0 ? void 0 : _result$protocol2.result) === 'unreachable') {
365
+ protocols[protocol].tested = true;
366
+
367
+ // we need at least 1 'reachable' result to mark the whole protocol as reachable
368
+ if (result[protocol].result === 'reachable') {
369
+ protocols[protocol].reachable = true;
370
+ }
371
+ }
372
+ });
373
+ });
374
+ unreachable = (0, _values.default)(protocols).every(function (protocol) {
375
+ return protocol.tested && !protocol.reachable;
376
+ });
377
+ } catch (e) {
378
+ _loggerProxy.default.logger.error("Roap:request#attachReachabilityData --> Error in parsing reachability data: ".concat(e));
379
+ }
380
+ }
381
+ return _context5.abrupt("return", unreachable);
382
+ case 6:
383
+ case "end":
384
+ return _context5.stop();
385
+ }
386
+ }, _callee5, this);
387
+ }));
388
+ function isWebexMediaBackendUnreachable() {
389
+ return _isWebexMediaBackendUnreachable.apply(this, arguments);
390
+ }
391
+ return isWebexMediaBackendUnreachable;
392
+ }()
320
393
  /**
321
394
  * Get list of all unreachable clusters
322
395
  * @returns {array} Unreachable clusters
@@ -380,18 +453,18 @@ var Reachability = exports.default = /*#__PURE__*/function () {
380
453
  }, {
381
454
  key: "performReachabilityChecks",
382
455
  value: (function () {
383
- var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(clusterList) {
456
+ var _performReachabilityChecks = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(clusterList) {
384
457
  var _this2 = this;
385
458
  var results, clusterReachabilityChecks;
386
- return _regenerator.default.wrap(function _callee5$(_context5) {
387
- while (1) switch (_context5.prev = _context5.next) {
459
+ return _regenerator.default.wrap(function _callee6$(_context6) {
460
+ while (1) switch (_context6.prev = _context6.next) {
388
461
  case 0:
389
462
  results = {};
390
463
  if (!(!clusterList || !(0, _keys.default)(clusterList).length)) {
391
- _context5.next = 3;
464
+ _context6.next = 3;
392
465
  break;
393
466
  }
394
- return _context5.abrupt("return", _promise.default.resolve(results));
467
+ return _context6.abrupt("return", _promise.default.resolve(results));
395
468
  case 3:
396
469
  _loggerProxy.default.logger.log("Reachability:index#performReachabilityChecks --> doing UDP".concat(
397
470
  // @ts-ignore
@@ -420,16 +493,16 @@ var Reachability = exports.default = /*#__PURE__*/function () {
420
493
  results[key].isVideoMesh = cluster.isVideoMesh;
421
494
  });
422
495
  });
423
- _context5.next = 7;
496
+ _context6.next = 7;
424
497
  return _promise.default.all(clusterReachabilityChecks);
425
498
  case 7:
426
499
  this.logUnreachableClusters();
427
- return _context5.abrupt("return", results);
500
+ return _context6.abrupt("return", results);
428
501
  case 9:
429
502
  case "end":
430
- return _context5.stop();
503
+ return _context6.stop();
431
504
  }
432
- }, _callee5, this);
505
+ }, _callee6, this);
433
506
  }));
434
507
  function performReachabilityChecks(_x) {
435
508
  return _performReachabilityChecks.apply(this, arguments);
@@ -1 +1 @@
1
- {"version":3,"names":["_lodash","require","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","Reachability","exports","default","webex","_classCallCheck2","_defineProperty2","REACHABILITY","namespace","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","results","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","performReachabilityChecks","boundedStorage","put","localStorageResult","_stringify","localStorageJoinCookie","LoggerProxy","logger","log","abrupt","t0","error","stop","gatherReachability","apply","arguments","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","_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","result","udp","outcome","concat","tcp","xtls","get","JSON","parse","_values","forEach","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","length","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","e","isAnyPublicClusterReachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","push","name","protocol","logUnreachableClusters","list","_ref3","_performReachabilityChecks","_callee5","clusterList","_this2","clusterReachabilityChecks","_callee5$","_context5","_keys","_promise","resolve","config","meetings","experimental","enableTcpReachability","enableTlsReachability","map","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","start","then","all","_x"],"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 {mapValues} from 'lodash';\n\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 ClusterReachability,\n ClusterReachabilityResult,\n TransportResult,\n} from './clusterReachability';\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/**\n * @class Reachability\n * @export\n */\nexport default class Reachability {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\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 // Perform Reachability Check\n const results = await this.performReachabilityChecks(clusters);\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n LoggerProxy.logger.log(\n 'Reachability:index#gatherReachability --> Reachability checks completed'\n );\n\n return results;\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 * 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 * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<ReachabilityResults>} reachability check results\n */\n private async performReachabilityChecks(clusterList: ClusterList): Promise<ReachabilityResults> {\n const results: ReachabilityResults = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return Promise.resolve(results);\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 const clusterReachabilityChecks = Object.keys(clusterList).map((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 const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n\n return this.clusterReachability[key].start().then((result) => {\n results[key] = result;\n results[key].isVideoMesh = cluster.isVideoMesh;\n });\n });\n\n await Promise.all(clusterReachabilityChecks);\n\n this.logUnreachableClusters();\n\n return results;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_lodash","require","_loggerProxy","_interopRequireDefault","_util","_constants","_request","_clusterReachability","Reachability","exports","default","webex","_classCallCheck2","_defineProperty2","REACHABILITY","namespace","reachabilityRequest","ReachabilityRequest","clusterReachability","_createClass2","key","value","_gatherReachability","_asyncToGenerator2","_regenerator","mark","_callee","_yield$this$reachabil","clusters","joinCookie","results","wrap","_callee$","_context","prev","next","getClusters","MeetingUtil","getIpVersion","sent","performReachabilityChecks","boundedStorage","put","localStorageResult","_stringify","localStorageJoinCookie","LoggerProxy","logger","log","abrupt","t0","error","stop","gatherReachability","apply","arguments","_getReachabilityMetrics","_callee2","stats","updateStats","resultsJson","_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","result","udp","outcome","concat","tcp","xtls","get","JSON","parse","_values","forEach","isVideoMesh","warn","getReachabilityMetrics","mapTransportResultToBackendDataFormat","transportResult","output","_i","_Object$entries","_entries","length","_Object$entries$_i","_slicedToArray2","reachable","untested","latencyInMilliseconds","toString","_getReachabilityResults","_callee3","_this","allClusterResults","_callee3$","_context3","mapValues","clusterResult","getReachabilityResults","_isAnyPublicClusterReachable","_callee4","reachabilityData","reachabilityResults","_callee4$","_context4","catch","some","_result$udp","_result$tcp","e","isAnyPublicClusterReachable","_isWebexMediaBackendUnreachable","_callee5","unreachable","protocols","_callee5$","_context5","tested","undefined","_keys","protocol","_result$protocol","_result$protocol2","every","isWebexMediaBackendUnreachable","getUnreachableClusters","unreachableList","_ref","_ref2","getResult","push","name","logUnreachableClusters","list","_ref3","_performReachabilityChecks","_callee6","clusterList","_this2","clusterReachabilityChecks","_callee6$","_context6","_promise","resolve","config","meetings","experimental","enableTcpReachability","enableTlsReachability","map","cluster","includeTcpReachability","includeTlsReachability","ClusterReachability","start","then","all","_x"],"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 {mapValues} from 'lodash';\n\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 ClusterReachability,\n ClusterReachabilityResult,\n TransportResult,\n} from './clusterReachability';\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/**\n * @class Reachability\n * @export\n */\nexport default class Reachability {\n namespace = REACHABILITY.namespace;\n webex: object;\n reachabilityRequest: ReachabilityRequest;\n clusterReachability: {\n [key: string]: ClusterReachability;\n };\n\n /**\n * Creates an instance of Reachability.\n * @param {object} webex\n * @memberof Reachability\n */\n constructor(webex: object) {\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 // Perform Reachability Check\n const results = await this.performReachabilityChecks(clusters);\n\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageResult,\n JSON.stringify(results)\n );\n // @ts-ignore\n await this.webex.boundedStorage.put(\n this.namespace,\n REACHABILITY.localStorageJoinCookie,\n JSON.stringify(joinCookie)\n );\n\n LoggerProxy.logger.log(\n 'Reachability:index#gatherReachability --> Reachability checks completed'\n );\n\n return results;\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 * Performs reachability checks for all clusters\n * @param {ClusterList} clusterList\n * @returns {Promise<ReachabilityResults>} reachability check results\n */\n private async performReachabilityChecks(clusterList: ClusterList): Promise<ReachabilityResults> {\n const results: ReachabilityResults = {};\n\n if (!clusterList || !Object.keys(clusterList).length) {\n return Promise.resolve(results);\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 const clusterReachabilityChecks = Object.keys(clusterList).map((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 const includeTlsReachability =\n // @ts-ignore\n this.webex.config.meetings.experimental.enableTlsReachability && !cluster.isVideoMesh;\n\n if (!includeTlsReachability) {\n cluster.xtls = [];\n }\n\n this.clusterReachability[key] = new ClusterReachability(key, cluster);\n\n return this.clusterReachability[key].start().then((result) => {\n results[key] = result;\n results[key].isVideoMesh = cluster.isVideoMesh;\n });\n });\n\n await Promise.all(clusterReachabilityChecks);\n\n this.logUnreachableClusters();\n\n return results;\n }\n}\n"],"mappings":"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"}
@@ -919,10 +919,10 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
919
919
  this.statsResults[mediaType][sendrecvType].encoderImplementation = result.encoderImplementation;
920
920
  this.statsResults[mediaType][sendrecvType].qualityLimitationReason = result.qualityLimitationReason;
921
921
  this.statsResults[mediaType][sendrecvType].qualityLimitationResolutionChanges = result.qualityLimitationResolutionChanges;
922
- this.statsResults[mediaType][sendrecvType].retransmittedPacketsSent = result.retransmittedPacketsSent;
922
+ this.statsResults[mediaType][sendrecvType].totalRtxPacketsSent = result.retransmittedPacketsSent;
923
+ this.statsResults[mediaType][sendrecvType].totalRtxBytesSent = result.retransmittedBytesSent;
923
924
  this.statsResults[mediaType][sendrecvType].totalBytesSent = result.bytesSent;
924
925
  this.statsResults[mediaType][sendrecvType].headerBytesSent = result.headerBytesSent;
925
- this.statsResults[mediaType][sendrecvType].retransmittedBytesSent = result.retransmittedBytesSent;
926
926
  this.statsResults[mediaType][sendrecvType].requestedBitrate = result.requestedBitrate;
927
927
  this.statsResults[mediaType][sendrecvType].requestedFrameSize = result.requestedFrameSize;
928
928
  }
@@ -1013,6 +1013,8 @@ var StatsAnalyzer = exports.StatsAnalyzer = /*#__PURE__*/function (_EventsScope)
1013
1013
  this.statsResults[mediaType][sendrecvType].fecPacketsReceived = result.fecPacketsReceived;
1014
1014
  this.statsResults[mediaType][sendrecvType].totalBytesReceived = result.bytesReceived;
1015
1015
  this.statsResults[mediaType][sendrecvType].headerBytesReceived = result.headerBytesReceived;
1016
+ this.statsResults[mediaType][sendrecvType].totalRtxPacketsReceived = result.retransmittedPacketsReceived;
1017
+ this.statsResults[mediaType][sendrecvType].totalRtxBytesReceived = result.retransmittedBytesReceived;
1016
1018
  this.statsResults[mediaType][sendrecvType].meanRtpJitter.push(result.jitter);
1017
1019
 
1018
1020
  // Audio stats