@webex/plugin-meetings 3.3.1-next.20 → 3.3.1-next.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/metrics/index.js +57 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/reachability/index.js +1 -1
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/metrics/index.d.ts +15 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +21 -21
- package/src/metrics/index.ts +44 -0
- package/src/reachability/index.ts +4 -1
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/reachability/index.ts +96 -63
package/dist/breakouts/index.js
CHANGED
|
@@ -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.3.1-next.
|
|
1049
|
+
version: "3.3.1-next.22"
|
|
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.3.1-next.
|
|
376
|
+
version: "3.3.1-next.22"
|
|
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.3.1-next.
|
|
21
|
+
version: "3.3.1-next.22"
|
|
22
22
|
});
|
|
23
23
|
var _default = exports.default = SILanguage;
|
|
24
24
|
//# sourceMappingURL=siLanguage.js.map
|
package/dist/metrics/index.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
4
|
+
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
5
|
+
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
6
|
+
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
|
|
7
|
+
var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
|
|
3
8
|
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
9
|
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
5
10
|
_Object$defineProperty(exports, "__esModule", {
|
|
6
11
|
value: true
|
|
7
12
|
});
|
|
8
13
|
exports.default = void 0;
|
|
14
|
+
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
|
|
15
|
+
var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
|
|
16
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
17
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
|
|
9
18
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
10
19
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
11
20
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
12
21
|
var _class;
|
|
22
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
23
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
24
|
/*!
|
|
14
25
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
15
26
|
*/
|
|
@@ -81,6 +92,52 @@ var Metrics = /*#__PURE__*/function () {
|
|
|
81
92
|
tags: metricTags
|
|
82
93
|
});
|
|
83
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Flattens an object into one that has no nested properties. Each level of nesting is represented
|
|
98
|
+
* by "_" in the flattened object property names.
|
|
99
|
+
* This function is needed, because Amplitude doesn't allow passing nested objects as metricFields.
|
|
100
|
+
* Use this function for metricFields before calling sendBehavioralMetric() if you want to send
|
|
101
|
+
* nested objects in your metrics.
|
|
102
|
+
*
|
|
103
|
+
* If the function is called with a literal, it returns an object with a single property "value"
|
|
104
|
+
* and the literal value in it.
|
|
105
|
+
*
|
|
106
|
+
* @param {any} payload object you want to flatten
|
|
107
|
+
* @param {string} prefix string prefix prepended to any property names in flatten object
|
|
108
|
+
* @returns {Object}
|
|
109
|
+
*/
|
|
110
|
+
}, {
|
|
111
|
+
key: "prepareMetricFields",
|
|
112
|
+
value: function prepareMetricFields() {
|
|
113
|
+
var _this = this;
|
|
114
|
+
var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
115
|
+
var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
116
|
+
var output = {};
|
|
117
|
+
if ((0, _isArray.default)(payload)) {
|
|
118
|
+
payload.forEach(function (item, index) {
|
|
119
|
+
var propName = prefix.length > 0 ? "".concat(prefix, "_").concat(index) : "".concat(index);
|
|
120
|
+
output = _objectSpread(_objectSpread({}, output), _this.prepareMetricFields(item, propName));
|
|
121
|
+
});
|
|
122
|
+
return output;
|
|
123
|
+
}
|
|
124
|
+
if ((0, _typeof2.default)(payload) !== 'object' || payload === null) {
|
|
125
|
+
if (prefix.length > 0) {
|
|
126
|
+
return (0, _defineProperty2.default)({}, prefix, payload);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
value: payload
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
(0, _entries.default)(payload).forEach(function (_ref2) {
|
|
133
|
+
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
134
|
+
key = _ref3[0],
|
|
135
|
+
value = _ref3[1];
|
|
136
|
+
var propName = prefix.length > 0 ? "".concat(prefix, "_").concat(key) : key;
|
|
137
|
+
output = _objectSpread(_objectSpread({}, output), _this.prepareMetricFields(value, propName));
|
|
138
|
+
});
|
|
139
|
+
return output;
|
|
140
|
+
}
|
|
84
141
|
}]);
|
|
85
142
|
return Metrics;
|
|
86
143
|
}(); // Export Metrics singleton ---------------------------------------------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Metrics","_classCallCheck2","default","_defineProperty2","instance","_createClass2","key","value","initialSetup","webex","sendBehavioralMetric","metricName","metricFields","arguments","length","undefined","metricTags","internal","metrics","submitClientMetrics","type","config","fields","tags","_class","_default","exports"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(webex: object) {\n this.webex = webex;\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["Metrics","_classCallCheck2","default","_defineProperty2","instance","_createClass2","key","value","initialSetup","webex","sendBehavioralMetric","metricName","metricFields","arguments","length","undefined","metricTags","internal","metrics","submitClientMetrics","type","config","fields","tags","prepareMetricFields","_this","payload","prefix","output","_isArray","forEach","item","index","propName","concat","_objectSpread","_typeof2","_entries","_ref2","_ref3","_slicedToArray2","_class","_default","exports"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(webex: object) {\n this.webex = webex;\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n\n /**\n * Flattens an object into one that has no nested properties. Each level of nesting is represented\n * by \"_\" in the flattened object property names.\n * This function is needed, because Amplitude doesn't allow passing nested objects as metricFields.\n * Use this function for metricFields before calling sendBehavioralMetric() if you want to send\n * nested objects in your metrics.\n *\n * If the function is called with a literal, it returns an object with a single property \"value\"\n * and the literal value in it.\n *\n * @param {any} payload object you want to flatten\n * @param {string} prefix string prefix prepended to any property names in flatten object\n * @returns {Object}\n */\n prepareMetricFields(payload: any = {}, prefix = '') {\n let output = {};\n\n if (Array.isArray(payload)) {\n payload.forEach((item, index) => {\n const propName = prefix.length > 0 ? `${prefix}_${index}` : `${index}`;\n\n output = {...output, ...this.prepareMetricFields(item, propName)};\n });\n\n return output;\n }\n\n if (typeof payload !== 'object' || payload === null) {\n if (prefix.length > 0) {\n return {[prefix]: payload};\n }\n\n return {value: payload};\n }\n\n Object.entries(payload).forEach(([key, value]) => {\n const propName = prefix.length > 0 ? `${prefix}_${key}` : key;\n\n output = {...output, ...this.prepareMetricFields(value, propName)};\n });\n\n return output;\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":"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"}
|
|
@@ -612,7 +612,7 @@ var Reachability = exports.default = /*#__PURE__*/function (_EventsScope) {
|
|
|
612
612
|
xtls: this.getStatistics(results, 'xtls', false)
|
|
613
613
|
}
|
|
614
614
|
};
|
|
615
|
-
_metrics.default.sendBehavioralMetric(_constants2.default.REACHABILITY_COMPLETED, stats);
|
|
615
|
+
_metrics.default.sendBehavioralMetric(_constants2.default.REACHABILITY_COMPLETED, _metrics.default.prepareMetricFields(stats));
|
|
616
616
|
case 4:
|
|
617
617
|
case "end":
|
|
618
618
|
return _context6.stop();
|
|
@@ -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","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(BEHAVIORAL_METRICS.REACHABILITY_COMPLETED, stats);\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","_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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"}
|
|
@@ -40,6 +40,21 @@ declare class Metrics {
|
|
|
40
40
|
* @returns {void}
|
|
41
41
|
*/
|
|
42
42
|
sendBehavioralMetric(metricName: string, metricFields?: object, metricTags?: object): void;
|
|
43
|
+
/**
|
|
44
|
+
* Flattens an object into one that has no nested properties. Each level of nesting is represented
|
|
45
|
+
* by "_" in the flattened object property names.
|
|
46
|
+
* This function is needed, because Amplitude doesn't allow passing nested objects as metricFields.
|
|
47
|
+
* Use this function for metricFields before calling sendBehavioralMetric() if you want to send
|
|
48
|
+
* nested objects in your metrics.
|
|
49
|
+
*
|
|
50
|
+
* If the function is called with a literal, it returns an object with a single property "value"
|
|
51
|
+
* and the literal value in it.
|
|
52
|
+
*
|
|
53
|
+
* @param {any} payload object you want to flatten
|
|
54
|
+
* @param {string} prefix string prefix prepended to any property names in flatten object
|
|
55
|
+
* @returns {Object}
|
|
56
|
+
*/
|
|
57
|
+
prepareMetricFields(payload?: any, prefix?: string): {};
|
|
43
58
|
}
|
|
44
59
|
declare const instance: Metrics;
|
|
45
60
|
export default instance;
|
package/dist/webinar/index.js
CHANGED
|
@@ -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.3.1-next.
|
|
65
|
+
version: "3.3.1-next.22"
|
|
66
66
|
});
|
|
67
67
|
var _default = exports.default = Webinar;
|
|
68
68
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
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.3.1-next.
|
|
47
|
-
"@webex/plugin-rooms": "3.3.1-next.
|
|
48
|
-
"@webex/test-helper-chai": "3.3.1-next.
|
|
49
|
-
"@webex/test-helper-mocha": "3.3.1-next.
|
|
50
|
-
"@webex/test-helper-mock-webex": "3.3.1-next.
|
|
51
|
-
"@webex/test-helper-retry": "3.3.1-next.
|
|
52
|
-
"@webex/test-helper-test-users": "3.3.1-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.3.1-next.22",
|
|
47
|
+
"@webex/plugin-rooms": "3.3.1-next.6",
|
|
48
|
+
"@webex/test-helper-chai": "3.3.1-next.5",
|
|
49
|
+
"@webex/test-helper-mocha": "3.3.1-next.5",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.3.1-next.5",
|
|
51
|
+
"@webex/test-helper-retry": "3.3.1-next.5",
|
|
52
|
+
"@webex/test-helper-test-users": "3.3.1-next.5",
|
|
53
53
|
"chai": "^4.3.4",
|
|
54
54
|
"chai-as-promised": "^7.1.1",
|
|
55
55
|
"eslint": "^8.24.0",
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"typescript": "^4.7.4"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@webex/common": "3.3.1-next.
|
|
64
|
+
"@webex/common": "3.3.1-next.5",
|
|
65
65
|
"@webex/internal-media-core": "2.7.1",
|
|
66
|
-
"@webex/internal-plugin-conversation": "3.3.1-next.
|
|
67
|
-
"@webex/internal-plugin-device": "3.3.1-next.
|
|
68
|
-
"@webex/internal-plugin-llm": "3.3.1-next.
|
|
69
|
-
"@webex/internal-plugin-mercury": "3.3.1-next.
|
|
70
|
-
"@webex/internal-plugin-metrics": "3.3.1-next.
|
|
71
|
-
"@webex/internal-plugin-support": "3.3.1-next.
|
|
72
|
-
"@webex/internal-plugin-user": "3.3.1-next.
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.3.1-next.
|
|
74
|
-
"@webex/media-helpers": "3.3.1-next.
|
|
75
|
-
"@webex/plugin-people": "3.3.1-next.
|
|
76
|
-
"@webex/plugin-rooms": "3.3.1-next.
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.3.1-next.6",
|
|
67
|
+
"@webex/internal-plugin-device": "3.3.1-next.5",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.3.1-next.7",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.3.1-next.6",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.3.1-next.5",
|
|
71
|
+
"@webex/internal-plugin-support": "3.3.1-next.6",
|
|
72
|
+
"@webex/internal-plugin-user": "3.3.1-next.5",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.3.1-next.22",
|
|
74
|
+
"@webex/media-helpers": "3.3.1-next.8",
|
|
75
|
+
"@webex/plugin-people": "3.3.1-next.6",
|
|
76
|
+
"@webex/plugin-rooms": "3.3.1-next.6",
|
|
77
77
|
"@webex/web-capabilities": "^1.3.0",
|
|
78
|
-
"@webex/webex-core": "3.3.1-next.
|
|
78
|
+
"@webex/webex-core": "3.3.1-next.5",
|
|
79
79
|
"ampersand-collection": "^2.0.2",
|
|
80
80
|
"bowser": "^2.11.0",
|
|
81
81
|
"btoa": "^1.2.1",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"//": [
|
|
93
93
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
94
94
|
],
|
|
95
|
-
"version": "3.3.1-next.
|
|
95
|
+
"version": "3.3.1-next.22"
|
|
96
96
|
}
|
package/src/metrics/index.ts
CHANGED
|
@@ -65,6 +65,50 @@ class Metrics {
|
|
|
65
65
|
tags: metricTags,
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Flattens an object into one that has no nested properties. Each level of nesting is represented
|
|
71
|
+
* by "_" in the flattened object property names.
|
|
72
|
+
* This function is needed, because Amplitude doesn't allow passing nested objects as metricFields.
|
|
73
|
+
* Use this function for metricFields before calling sendBehavioralMetric() if you want to send
|
|
74
|
+
* nested objects in your metrics.
|
|
75
|
+
*
|
|
76
|
+
* If the function is called with a literal, it returns an object with a single property "value"
|
|
77
|
+
* and the literal value in it.
|
|
78
|
+
*
|
|
79
|
+
* @param {any} payload object you want to flatten
|
|
80
|
+
* @param {string} prefix string prefix prepended to any property names in flatten object
|
|
81
|
+
* @returns {Object}
|
|
82
|
+
*/
|
|
83
|
+
prepareMetricFields(payload: any = {}, prefix = '') {
|
|
84
|
+
let output = {};
|
|
85
|
+
|
|
86
|
+
if (Array.isArray(payload)) {
|
|
87
|
+
payload.forEach((item, index) => {
|
|
88
|
+
const propName = prefix.length > 0 ? `${prefix}_${index}` : `${index}`;
|
|
89
|
+
|
|
90
|
+
output = {...output, ...this.prepareMetricFields(item, propName)};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return output;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (typeof payload !== 'object' || payload === null) {
|
|
97
|
+
if (prefix.length > 0) {
|
|
98
|
+
return {[prefix]: payload};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {value: payload};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
105
|
+
const propName = prefix.length > 0 ? `${prefix}_${key}` : key;
|
|
106
|
+
|
|
107
|
+
output = {...output, ...this.prepareMetricFields(value, propName)};
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return output;
|
|
111
|
+
}
|
|
68
112
|
}
|
|
69
113
|
|
|
70
114
|
// Export Metrics singleton ---------------------------------------------------
|
|
@@ -514,7 +514,10 @@ export default class Reachability extends EventsScope {
|
|
|
514
514
|
xtls: this.getStatistics(results, 'xtls', false),
|
|
515
515
|
},
|
|
516
516
|
};
|
|
517
|
-
Metrics.sendBehavioralMetric(
|
|
517
|
+
Metrics.sendBehavioralMetric(
|
|
518
|
+
BEHAVIORAL_METRICS.REACHABILITY_COMPLETED,
|
|
519
|
+
Metrics.prepareMetricFields(stats)
|
|
520
|
+
);
|
|
518
521
|
}
|
|
519
522
|
|
|
520
523
|
/**
|
|
@@ -58,4 +58,130 @@ describe('Meeting metrics', () => {
|
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
describe('prepareMetricFields', () => {
|
|
63
|
+
it('handles empty objects correctly', () => {
|
|
64
|
+
const result = metrics.prepareMetricFields({});
|
|
65
|
+
|
|
66
|
+
assert.deepEqual(result, {});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('handles literal values correctly', () => {
|
|
70
|
+
assert.deepEqual(metrics.prepareMetricFields('any string'), {value: 'any string'});
|
|
71
|
+
assert.deepEqual(metrics.prepareMetricFields(999), {value: 999});
|
|
72
|
+
assert.deepEqual(metrics.prepareMetricFields(null), {value: null});
|
|
73
|
+
assert.deepEqual(metrics.prepareMetricFields(true), {value: true});
|
|
74
|
+
assert.deepEqual(metrics.prepareMetricFields(false), {value: false});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('handles simple objects correctly', () => {
|
|
78
|
+
const result = metrics.prepareMetricFields({
|
|
79
|
+
someStringProp: 'some string',
|
|
80
|
+
numberProp: 100,
|
|
81
|
+
booleanPropFalse: false,
|
|
82
|
+
booleanPropTrue: true,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
assert.deepEqual(result, {
|
|
86
|
+
someStringProp: 'some string',
|
|
87
|
+
numberProp: 100,
|
|
88
|
+
booleanPropFalse: false,
|
|
89
|
+
booleanPropTrue: true,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('handles nested objects correctly', () => {
|
|
94
|
+
const result = metrics.prepareMetricFields({
|
|
95
|
+
someStringProp: 'some string',
|
|
96
|
+
nestedObject: {
|
|
97
|
+
stringProp: 'another string',
|
|
98
|
+
numberProp: 1234,
|
|
99
|
+
deepObject: {
|
|
100
|
+
oneMoreString: 'deep nested string',
|
|
101
|
+
someBoolean: true,
|
|
102
|
+
oneMoreNumber: 10,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
assert.deepEqual(result, {
|
|
108
|
+
someStringProp: 'some string',
|
|
109
|
+
nestedObject_stringProp: 'another string',
|
|
110
|
+
nestedObject_numberProp: 1234,
|
|
111
|
+
nestedObject_deepObject_oneMoreString: 'deep nested string',
|
|
112
|
+
nestedObject_deepObject_someBoolean: true,
|
|
113
|
+
nestedObject_deepObject_oneMoreNumber: 10,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('handles arrays correctly', () => {
|
|
118
|
+
const result = metrics.prepareMetricFields(['a string', 10, true, false, {id: 'object id'}]);
|
|
119
|
+
|
|
120
|
+
assert.deepEqual(result, {
|
|
121
|
+
0: 'a string',
|
|
122
|
+
1: 10,
|
|
123
|
+
2: true,
|
|
124
|
+
3: false,
|
|
125
|
+
'4_id': 'object id',
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('handles arrays nested in objects correctly', () => {
|
|
130
|
+
const result = metrics.prepareMetricFields({
|
|
131
|
+
something: 10,
|
|
132
|
+
anObject: {
|
|
133
|
+
someArray: ['a string', 10, true, false, {id: 'object id'}],
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
assert.deepEqual(result, {
|
|
138
|
+
something: 10,
|
|
139
|
+
anObject_someArray_0: 'a string',
|
|
140
|
+
anObject_someArray_1: 10,
|
|
141
|
+
anObject_someArray_2: true,
|
|
142
|
+
anObject_someArray_3: false,
|
|
143
|
+
anObject_someArray_4_id: 'object id',
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('handles arrays nested in arrays correctly', () => {
|
|
148
|
+
const result = metrics.prepareMetricFields({
|
|
149
|
+
something: 10,
|
|
150
|
+
topLevelArray: [
|
|
151
|
+
[1, 2, 'three', {prop1: '1st prop of object 1', prop2: '2nd prop of object 1'}],
|
|
152
|
+
[10, 20, 'thirty', {prop1: '1st prop of object 2', prop2: '2nd prop of object 2'}],
|
|
153
|
+
],
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
assert.deepEqual(result, {
|
|
157
|
+
something: 10,
|
|
158
|
+
topLevelArray_0_0: 1,
|
|
159
|
+
topLevelArray_0_1: 2,
|
|
160
|
+
topLevelArray_0_2: 'three',
|
|
161
|
+
topLevelArray_0_3_prop1: '1st prop of object 1',
|
|
162
|
+
topLevelArray_0_3_prop2: '2nd prop of object 1',
|
|
163
|
+
topLevelArray_1_0: 10,
|
|
164
|
+
topLevelArray_1_1: 20,
|
|
165
|
+
topLevelArray_1_2: 'thirty',
|
|
166
|
+
topLevelArray_1_3_prop1: '1st prop of object 2',
|
|
167
|
+
topLevelArray_1_3_prop2: '2nd prop of object 2',
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('prepends the prefix', () => {
|
|
172
|
+
const result = metrics.prepareMetricFields({
|
|
173
|
+
someStringProp: 'a string',
|
|
174
|
+
numberProp: 111,
|
|
175
|
+
booleanPropFalse: false,
|
|
176
|
+
booleanPropTrue: true,
|
|
177
|
+
}, 'testPrefix');
|
|
178
|
+
|
|
179
|
+
assert.deepEqual(result, {
|
|
180
|
+
testPrefix_someStringProp: 'a string',
|
|
181
|
+
testPrefix_numberProp: 111,
|
|
182
|
+
testPrefix_booleanPropFalse: false,
|
|
183
|
+
testPrefix_booleanPropTrue: true,
|
|
184
|
+
});
|
|
185
|
+
})
|
|
186
|
+
});
|
|
61
187
|
});
|
|
@@ -575,12 +575,18 @@ describe('gatherReachability', () => {
|
|
|
575
575
|
},
|
|
576
576
|
},
|
|
577
577
|
expectedMetrics: {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
578
|
+
vmn_udp_min: -1,
|
|
579
|
+
vmn_udp_max: -1,
|
|
580
|
+
vmn_udp_average: -1,
|
|
581
|
+
public_udp_min: 22,
|
|
582
|
+
public_udp_max: 22,
|
|
583
|
+
public_udp_average: 22,
|
|
584
|
+
public_tcp_min: 11,
|
|
585
|
+
public_tcp_max: 11,
|
|
586
|
+
public_tcp_average: 11,
|
|
587
|
+
public_xtls_min: 33,
|
|
588
|
+
public_xtls_max: 33,
|
|
589
|
+
public_xtls_average: 33,
|
|
584
590
|
},
|
|
585
591
|
},
|
|
586
592
|
// ========================================================================
|
|
@@ -657,12 +663,18 @@ describe('gatherReachability', () => {
|
|
|
657
663
|
},
|
|
658
664
|
},
|
|
659
665
|
expectedMetrics: {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
+
vmn_udp_min: -1,
|
|
667
|
+
vmn_udp_max: -1,
|
|
668
|
+
vmn_udp_average: -1,
|
|
669
|
+
public_udp_min: 13,
|
|
670
|
+
public_udp_max: 13,
|
|
671
|
+
public_udp_average: 13,
|
|
672
|
+
public_tcp_min: 53,
|
|
673
|
+
public_tcp_max: 53,
|
|
674
|
+
public_tcp_average: 53,
|
|
675
|
+
public_xtls_min: 113,
|
|
676
|
+
public_xtls_max: 113,
|
|
677
|
+
public_xtls_average: 113,
|
|
666
678
|
},
|
|
667
679
|
},
|
|
668
680
|
// ========================================================================
|
|
@@ -788,12 +800,18 @@ describe('gatherReachability', () => {
|
|
|
788
800
|
},
|
|
789
801
|
},
|
|
790
802
|
expectedMetrics: {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
803
|
+
vmn_udp_min: -1,
|
|
804
|
+
vmn_udp_max: -1,
|
|
805
|
+
vmn_udp_average: -1,
|
|
806
|
+
public_udp_min: 10,
|
|
807
|
+
public_udp_max: 30,
|
|
808
|
+
public_udp_average: 20,
|
|
809
|
+
public_tcp_min: 100,
|
|
810
|
+
public_tcp_max: 120,
|
|
811
|
+
public_tcp_average: 110,
|
|
812
|
+
public_xtls_min: 200,
|
|
813
|
+
public_xtls_max: 240,
|
|
814
|
+
public_xtls_average: 220,
|
|
797
815
|
},
|
|
798
816
|
},
|
|
799
817
|
// ========================================================================
|
|
@@ -831,12 +849,18 @@ describe('gatherReachability', () => {
|
|
|
831
849
|
},
|
|
832
850
|
},
|
|
833
851
|
expectedMetrics: {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
852
|
+
vmn_udp_min: -1,
|
|
853
|
+
vmn_udp_max: -1,
|
|
854
|
+
vmn_udp_average: -1,
|
|
855
|
+
public_udp_min: -1,
|
|
856
|
+
public_udp_max: -1,
|
|
857
|
+
public_udp_average: -1,
|
|
858
|
+
public_tcp_min: -1,
|
|
859
|
+
public_tcp_max: -1,
|
|
860
|
+
public_tcp_average: -1,
|
|
861
|
+
public_xtls_min: -1,
|
|
862
|
+
public_xtls_max: -1,
|
|
863
|
+
public_xtls_average: -1,
|
|
840
864
|
},
|
|
841
865
|
},
|
|
842
866
|
// ========================================================================
|
|
@@ -913,12 +937,18 @@ describe('gatherReachability', () => {
|
|
|
913
937
|
},
|
|
914
938
|
},
|
|
915
939
|
expectedMetrics: {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
940
|
+
vmn_udp_min: -1,
|
|
941
|
+
vmn_udp_max: -1,
|
|
942
|
+
vmn_udp_average: -1,
|
|
943
|
+
public_udp_min: 10,
|
|
944
|
+
public_udp_max: 10,
|
|
945
|
+
public_udp_average: 10,
|
|
946
|
+
public_tcp_min: 100,
|
|
947
|
+
public_tcp_max: 100,
|
|
948
|
+
public_tcp_average: 100,
|
|
949
|
+
public_xtls_min: 200,
|
|
950
|
+
public_xtls_max: 200,
|
|
951
|
+
public_xtls_average: 200,
|
|
922
952
|
},
|
|
923
953
|
},
|
|
924
954
|
// ========================================================================
|
|
@@ -975,12 +1005,18 @@ describe('gatherReachability', () => {
|
|
|
975
1005
|
},
|
|
976
1006
|
},
|
|
977
1007
|
expectedMetrics: {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1008
|
+
vmn_udp_min: 100,
|
|
1009
|
+
vmn_udp_max: 300,
|
|
1010
|
+
vmn_udp_average: 200,
|
|
1011
|
+
public_udp_min: -1,
|
|
1012
|
+
public_udp_max: -1,
|
|
1013
|
+
public_udp_average: -1,
|
|
1014
|
+
public_tcp_min: -1,
|
|
1015
|
+
public_tcp_max: -1,
|
|
1016
|
+
public_tcp_average: -1,
|
|
1017
|
+
public_xtls_min: -1,
|
|
1018
|
+
public_xtls_max: -1,
|
|
1019
|
+
public_xtls_average: -1,
|
|
984
1020
|
},
|
|
985
1021
|
},
|
|
986
1022
|
].forEach(
|
|
@@ -2003,9 +2039,11 @@ describe('sendMetric', () => {
|
|
|
2003
2039
|
// setup stub for getStatistics to return values that show what parameters it was called with,
|
|
2004
2040
|
// this way we can verify that the correct results of calls to getStatistics are placed
|
|
2005
2041
|
// in correct data fields when sendBehavioralMetric() is called
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2042
|
+
const getStatisticsStub = sinon
|
|
2043
|
+
.stub(reachability, 'getStatistics')
|
|
2044
|
+
.callsFake((results, protocol, isVideoMesh) => {
|
|
2045
|
+
return {result: 'fake', protocol, isVideoMesh};
|
|
2046
|
+
});
|
|
2009
2047
|
|
|
2010
2048
|
// setup fake clusterReachability results
|
|
2011
2049
|
reachability.setFakeClusterReachability({
|
|
@@ -2041,31 +2079,26 @@ describe('sendMetric', () => {
|
|
|
2041
2079
|
},
|
|
2042
2080
|
];
|
|
2043
2081
|
|
|
2082
|
+
// check that getStatistics is called 4 times and each time with all the results
|
|
2083
|
+
assert.callCount(getStatisticsStub, 4);
|
|
2084
|
+
assert.alwaysCalledWith(getStatisticsStub, expectedResults, sinon.match.any, sinon.match.any);
|
|
2085
|
+
|
|
2044
2086
|
assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
protocol: 'tcp',
|
|
2061
|
-
isVideoMesh: false,
|
|
2062
|
-
},
|
|
2063
|
-
xtls: {
|
|
2064
|
-
results: expectedResults,
|
|
2065
|
-
protocol: 'xtls',
|
|
2066
|
-
isVideoMesh: false,
|
|
2067
|
-
},
|
|
2068
|
-
},
|
|
2087
|
+
vmn_udp_result: 'fake',
|
|
2088
|
+
vmn_udp_protocol: 'udp',
|
|
2089
|
+
vmn_udp_isVideoMesh: true,
|
|
2090
|
+
|
|
2091
|
+
public_udp_result: 'fake',
|
|
2092
|
+
public_udp_protocol: 'udp',
|
|
2093
|
+
public_udp_isVideoMesh: false,
|
|
2094
|
+
|
|
2095
|
+
public_tcp_result: 'fake',
|
|
2096
|
+
public_tcp_protocol: 'tcp',
|
|
2097
|
+
public_tcp_isVideoMesh: false,
|
|
2098
|
+
|
|
2099
|
+
public_xtls_result: 'fake',
|
|
2100
|
+
public_xtls_protocol: 'xtls',
|
|
2101
|
+
public_xtls_isVideoMesh: false,
|
|
2069
2102
|
});
|
|
2070
2103
|
});
|
|
2071
2104
|
});
|