@webex/internal-plugin-metrics 3.0.0-beta.282 → 3.0.0-beta.284
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/batcher.js +2 -1
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +2 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +22 -3
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/client-metrics-batcher.js +2 -1
- package/dist/client-metrics-batcher.js.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +9 -1
- package/dist/types/config.d.ts +1 -0
- package/package.json +9 -9
- package/src/batcher.js +1 -0
- package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +1 -0
- package/src/call-diagnostic/call-diagnostic-metrics.ts +14 -2
- package/src/client-metrics-batcher.js +1 -0
- package/src/config.js +1 -0
- package/test/unit/spec/batcher.js +2 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +115 -44
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +78 -1
- package/test/unit/spec/client-metrics-batcher.js +2 -0
- package/test/unit/spec/metrics.js +1 -0
- package/test/unit/spec/new-metrics.ts +1 -1
package/dist/batcher.js
CHANGED
package/dist/batcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["sym","MetricsBatcher","Batcher","extend","namespace","prepareItem","item","env","process","NODE_ENV","appType","config","time","version","webex","resolve","prepareRequest","queue","map","postTime","submitHttpRequest","payload","request","method","service","resource","body","metrics","handleHttpSuccess","res","all","options","acceptItem","handleHttpError","reason","WebexHttpError","NetworkOrCORSError","logger","warn","delay","nextDelay","batcherRetryPlateau","safeSetTimeout","rerequest","prototype","getDeferredForRequest","then","defer","req","enqueue","bounce","catch","reject","fingerprintRequest","fingerprintResponse"],"sources":["batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher, WebexHttpError} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nconst sym = Symbol('metric id');\n\nconst MetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Keep non-prod data out of metrics\n const env = process.env.NODE_ENV === 'production' ? null : 'TEST';\n\n item.appType = item.appType || this.config.appType;\n item.env = item.env || env;\n item.time = item.time || Date.now();\n item.version = item.version || this.webex.version;\n\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(\n queue.map((item) => {\n item.postTime = item.postTime || Date.now();\n\n return item;\n })\n );\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'metrics',\n body: {\n metrics: payload,\n },\n });\n },\n\n handleHttpSuccess(res) {\n return Promise.all(res.options.body.metrics.map((item) => this.acceptItem(item)));\n },\n\n handleHttpError(reason) {\n if (reason instanceof WebexHttpError.NetworkOrCORSError) {\n this.logger.warn(\n 'metrics-batcher: received network error submitting metrics, reenqueuing payload'\n );\n\n return Promise.all(\n reason.options.body.metrics.map(\n (item) =>\n new Promise((resolve) => {\n const delay = item[sym].nextDelay;\n\n if (delay < this.config.batcherRetryPlateau) {\n item[sym].nextDelay *= 2;\n }\n safeSetTimeout(() => {\n resolve(this.rerequest(item));\n }, delay);\n })\n )\n );\n }\n\n return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);\n },\n\n rerequest(item) {\n return Promise.all([this.getDeferredForRequest(item), this.prepareItem(item)]).then(\n ([defer, req]) => {\n this.enqueue(req)\n .then(() => this.bounce())\n .catch((reason) => defer.reject(reason));\n }\n );\n },\n\n fingerprintRequest(item) {\n item[sym] = item[sym] || {\n nextDelay: 1000,\n };\n\n return Promise.resolve(item[sym]);\n },\n\n fingerprintResponse(item) {\n return Promise.resolve(item[sym]);\n },\n});\n\nexport default MetricsBatcher;\n"],"mappings":";;;;;;;;;;;;;AAIA;AACA;AALA;AACA;AACA;;AAKA,IAAMA,GAAG,GAAG,qBAAO,WAAW,CAAC;AAE/B,IAAMC,cAAc,GAAGC,kBAAO,CAACC,MAAM,CAAC;EACpCC,SAAS,EAAE,SAAS;EAEpBC,WAAW,uBAACC,IAAI,EAAE;IAChB;IACA,IAAMC,GAAG,GAAGC,OAAO,CAACD,GAAG,CAACE,QAAQ,KAAK,YAAY,GAAG,IAAI,GAAG,MAAM;IAEjEH,IAAI,CAACI,OAAO,GAAGJ,IAAI,CAACI,OAAO,IAAI,IAAI,CAACC,MAAM,CAACD,OAAO;IAClDJ,IAAI,CAACC,GAAG,GAAGD,IAAI,CAACC,GAAG,IAAIA,GAAG;IAC1BD,IAAI,CAACM,IAAI,GAAGN,IAAI,CAACM,IAAI,IAAI,mBAAU;IACnCN,IAAI,CAACO,OAAO,GAAGP,IAAI,CAACO,OAAO,IAAI,IAAI,CAACC,KAAK,CAACD,OAAO;IAEjD,OAAO,iBAAQE,OAAO,CAACT,IAAI,CAAC;EAC9B,CAAC;EAEDU,cAAc,0BAACC,KAAK,EAAE;IACpB,OAAO,iBAAQF,OAAO,CACpBE,KAAK,CAACC,GAAG,CAAC,UAACZ,IAAI,EAAK;MAClBA,IAAI,CAACa,QAAQ,GAAGb,IAAI,CAACa,QAAQ,IAAI,mBAAU;MAE3C,OAAOb,IAAI;IACb,CAAC,CAAC,CACH;EACH,CAAC;EAEDc,iBAAiB,6BAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACP,KAAK,CAACQ,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,SAAS;MACnBC,IAAI,EAAE;QACJC,OAAO,EAAEN;MACX;
|
|
1
|
+
{"version":3,"names":["sym","MetricsBatcher","Batcher","extend","namespace","prepareItem","item","env","process","NODE_ENV","appType","config","time","version","webex","resolve","prepareRequest","queue","map","postTime","submitHttpRequest","payload","request","method","service","resource","body","metrics","waitForServiceTimeout","handleHttpSuccess","res","all","options","acceptItem","handleHttpError","reason","WebexHttpError","NetworkOrCORSError","logger","warn","delay","nextDelay","batcherRetryPlateau","safeSetTimeout","rerequest","prototype","getDeferredForRequest","then","defer","req","enqueue","bounce","catch","reject","fingerprintRequest","fingerprintResponse"],"sources":["batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher, WebexHttpError} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nconst sym = Symbol('metric id');\n\nconst MetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Keep non-prod data out of metrics\n const env = process.env.NODE_ENV === 'production' ? null : 'TEST';\n\n item.appType = item.appType || this.config.appType;\n item.env = item.env || env;\n item.time = item.time || Date.now();\n item.version = item.version || this.webex.version;\n\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(\n queue.map((item) => {\n item.postTime = item.postTime || Date.now();\n\n return item;\n })\n );\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'metrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n });\n },\n\n handleHttpSuccess(res) {\n return Promise.all(res.options.body.metrics.map((item) => this.acceptItem(item)));\n },\n\n handleHttpError(reason) {\n if (reason instanceof WebexHttpError.NetworkOrCORSError) {\n this.logger.warn(\n 'metrics-batcher: received network error submitting metrics, reenqueuing payload'\n );\n\n return Promise.all(\n reason.options.body.metrics.map(\n (item) =>\n new Promise((resolve) => {\n const delay = item[sym].nextDelay;\n\n if (delay < this.config.batcherRetryPlateau) {\n item[sym].nextDelay *= 2;\n }\n safeSetTimeout(() => {\n resolve(this.rerequest(item));\n }, delay);\n })\n )\n );\n }\n\n return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);\n },\n\n rerequest(item) {\n return Promise.all([this.getDeferredForRequest(item), this.prepareItem(item)]).then(\n ([defer, req]) => {\n this.enqueue(req)\n .then(() => this.bounce())\n .catch((reason) => defer.reject(reason));\n }\n );\n },\n\n fingerprintRequest(item) {\n item[sym] = item[sym] || {\n nextDelay: 1000,\n };\n\n return Promise.resolve(item[sym]);\n },\n\n fingerprintResponse(item) {\n return Promise.resolve(item[sym]);\n },\n});\n\nexport default MetricsBatcher;\n"],"mappings":"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"}
|
|
@@ -50,7 +50,8 @@ var CallDiagnosticEventsBatcher = _batcher.default.extend({
|
|
|
50
50
|
resource: 'clientmetrics',
|
|
51
51
|
body: {
|
|
52
52
|
metrics: payload
|
|
53
|
-
}
|
|
53
|
+
},
|
|
54
|
+
waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout
|
|
54
55
|
}).then(function (res) {
|
|
55
56
|
_this.webex.logger.log(_config.CALL_DIAGNOSTIC_LOG_IDENTIFIER, "CallDiagnosticEventsBatcher: @submitHttpRequest#".concat(batchId, ". Request successful:"), "response:", res);
|
|
56
57
|
return res;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","batchId","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","request","method","service","resource","body","metrics","then","res","catch","err","error","generateCommonErrorMetadata","reject"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {uniqueId} from 'lodash';\nimport Batcher from '../batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic-metrics.util';\nimport {CALL_DIAGNOSTIC_LOG_IDENTIFIER} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n const batchId = uniqueId('call-diagnostic-metrics-batch-');\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Sending the request:`,\n 'payload:',\n payload\n );\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n })\n .then((res) => {\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request successful:`,\n `response:`,\n res\n );\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":";;;;;;;;;;AAIA;AACA;AACA;AACA;AAEA,IAAMA,2BAA2B,GAAGC,gBAAO,CAACC,MAAM,CAAC;EACjDC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;AACA;EACEC,WAAW,uBAACC,IAAI,EAAE;IAChB,OAAO,iBAAQC,OAAO,CAAC,IAAAC,kDAA2B,EAAC,IAAI,CAACC,KAAK,EAAEH,IAAI,CAAC,CAAC;EACvE,CAAC;EAED;AACF;AACA;AACA;AACA;EACEI,cAAc,0BAACC,KAAK,EAAE;IACpB;IACAA,KAAK,CAACC,OAAO,CAAC,UAACN,IAAI,EAAK;MACtBA,IAAI,CAACO,YAAY,CAACC,UAAU,GAAGR,IAAI,CAACO,YAAY,CAACC,UAAU,IAAI,CAAC,CAAC;MACjER,IAAI,CAACO,YAAY,CAACC,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;IAC9D,CAAC,CAAC;IAEF,OAAO,iBAAQV,OAAO,CAACI,KAAK,CAAC;EAC/B,CAAC;EAED;AACF;AACA;AACA;AACA;EACEO,iBAAiB,6BAACC,OAAO,EAAE;IAAA;IACzB,IAAMC,OAAO,GAAG,wBAAS,gCAAgC,CAAC;IAC1D,IAAI,CAACX,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,6BAC1D,UAAU,EACVD,OAAO,CACR;IAED,OAAO,IAAI,CAACV,KAAK,CACde,OAAO,CAAC;MACPC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEV;MACX;
|
|
1
|
+
{"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","batchId","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","request","method","service","resource","body","metrics","waitForServiceTimeout","config","then","res","catch","err","error","generateCommonErrorMetadata","reject"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {uniqueId} from 'lodash';\nimport Batcher from '../batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic-metrics.util';\nimport {CALL_DIAGNOSTIC_LOG_IDENTIFIER} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n const batchId = uniqueId('call-diagnostic-metrics-batch-');\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Sending the request:`,\n 'payload:',\n payload\n );\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n })\n .then((res) => {\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request successful:`,\n `response:`,\n res\n );\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":";;;;;;;;;;AAIA;AACA;AACA;AACA;AAEA,IAAMA,2BAA2B,GAAGC,gBAAO,CAACC,MAAM,CAAC;EACjDC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;AACA;EACEC,WAAW,uBAACC,IAAI,EAAE;IAChB,OAAO,iBAAQC,OAAO,CAAC,IAAAC,kDAA2B,EAAC,IAAI,CAACC,KAAK,EAAEH,IAAI,CAAC,CAAC;EACvE,CAAC;EAED;AACF;AACA;AACA;AACA;EACEI,cAAc,0BAACC,KAAK,EAAE;IACpB;IACAA,KAAK,CAACC,OAAO,CAAC,UAACN,IAAI,EAAK;MACtBA,IAAI,CAACO,YAAY,CAACC,UAAU,GAAGR,IAAI,CAACO,YAAY,CAACC,UAAU,IAAI,CAAC,CAAC;MACjER,IAAI,CAACO,YAAY,CAACC,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;IAC9D,CAAC,CAAC;IAEF,OAAO,iBAAQV,OAAO,CAACI,KAAK,CAAC;EAC/B,CAAC;EAED;AACF;AACA;AACA;AACA;EACEO,iBAAiB,6BAACC,OAAO,EAAE;IAAA;IACzB,IAAMC,OAAO,GAAG,wBAAS,gCAAgC,CAAC;IAC1D,IAAI,CAACX,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,6BAC1D,UAAU,EACVD,OAAO,CACR;IAED,OAAO,IAAI,CAACV,KAAK,CACde,OAAO,CAAC;MACPC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEV;MACX,CAAC;MACDW,qBAAqB,EAAE,IAAI,CAACrB,KAAK,CAACsB,MAAM,CAACF,OAAO,CAACC;IACnD,CAAC,CAAC,CACDE,IAAI,CAAC,UAACC,GAAG,EAAK;MACb,KAAI,CAACxB,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,yCAE1Da,GAAG,CACJ;MAED,OAAOA,GAAG;IACZ,CAAC,CAAC,CACDC,KAAK,CAAC,UAACC,GAAG,EAAK;MACd,KAAI,CAAC1B,KAAK,CAACY,MAAM,CAACe,KAAK,CACrBb,sCAA8B,4DACqBH,OAAO,yCAChD,IAAAiB,kCAA2B,EAACF,GAAG,CAAC,EAC3C;MAED,OAAO,iBAAQG,MAAM,CAACH,GAAG,CAAC;IAC5B,CAAC,CAAC;EACN;AACF,CAAC,CAAC;AAAC,eAEYlC,2BAA2B;AAAA"}
|
|
@@ -13,6 +13,7 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
13
13
|
});
|
|
14
14
|
exports.default = void 0;
|
|
15
15
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
16
|
+
var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
|
|
16
17
|
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
17
18
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
18
19
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
@@ -51,6 +52,8 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
51
52
|
// @ts-ignore
|
|
52
53
|
|
|
53
54
|
// to avoid adding @ts-ignore everywhere
|
|
55
|
+
// the default validator before piping an event to the batcher
|
|
56
|
+
// this function can be overridden by the user
|
|
54
57
|
|
|
55
58
|
/**
|
|
56
59
|
* Constructor
|
|
@@ -66,6 +69,12 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
66
69
|
// @ts-ignore
|
|
67
70
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticEventsBatcher", void 0);
|
|
68
71
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "logger", void 0);
|
|
72
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "validator", function (options) {
|
|
73
|
+
return _promise.default.resolve({
|
|
74
|
+
event: options === null || options === void 0 ? void 0 : options.event,
|
|
75
|
+
valid: true
|
|
76
|
+
});
|
|
77
|
+
});
|
|
69
78
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "submitToCallDiagnosticsPreLogin", function (event, preLoginId) {
|
|
70
79
|
// build metrics-a event type
|
|
71
80
|
// @ts-ignore
|
|
@@ -232,7 +241,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
232
241
|
}
|
|
233
242
|
if (meeting !== null && meeting !== void 0 && (_meeting$meetingInfo2 = meeting.meetingInfo) !== null && _meeting$meetingInfo2 !== void 0 && _meeting$meetingInfo2.confID) {
|
|
234
243
|
var _meeting$meetingInfo3;
|
|
235
|
-
identifiers.webexConferenceIdStr = (_meeting$meetingInfo3 = meeting.meetingInfo) === null || _meeting$meetingInfo3 === void 0 ? void 0 : _meeting$meetingInfo3.confID;
|
|
244
|
+
identifiers.webexConferenceIdStr = "".concat((_meeting$meetingInfo3 = meeting.meetingInfo) === null || _meeting$meetingInfo3 === void 0 ? void 0 : _meeting$meetingInfo3.confID);
|
|
236
245
|
}
|
|
237
246
|
if (meeting !== null && meeting !== void 0 && (_meeting$meetingInfo4 = meeting.meetingInfo) !== null && _meeting$meetingInfo4 !== void 0 && _meeting$meetingInfo4.meetingId) {
|
|
238
247
|
var _meeting$meetingInfo5;
|
|
@@ -244,7 +253,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
244
253
|
identifiers.mediaAgentGroupId = mediaConnections === null || mediaConnections === void 0 ? void 0 : (_mediaConnections$2 = mediaConnections[0]) === null || _mediaConnections$2 === void 0 ? void 0 : _mediaConnections$2.mediaAgentGroupId;
|
|
245
254
|
}
|
|
246
255
|
if (!(identifiers !== null && identifiers !== void 0 && identifiers.webexConferenceIdStr) && webexConferenceIdStr) {
|
|
247
|
-
identifiers.webexConferenceIdStr = webexConferenceIdStr;
|
|
256
|
+
identifiers.webexConferenceIdStr = "".concat(webexConferenceIdStr);
|
|
248
257
|
}
|
|
249
258
|
if (!(identifiers !== null && identifiers !== void 0 && identifiers.globalMeetingId) && globalMeetingId) {
|
|
250
259
|
identifiers.globalMeetingId = globalMeetingId;
|
|
@@ -368,6 +377,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
368
377
|
|
|
369
378
|
// append media quality event data to the call diagnostic event
|
|
370
379
|
var diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);
|
|
380
|
+
this.validator({
|
|
381
|
+
type: 'mqe',
|
|
382
|
+
event: diagnosticEvent
|
|
383
|
+
});
|
|
371
384
|
this.submitToCallDiagnostics(diagnosticEvent);
|
|
372
385
|
} else {
|
|
373
386
|
throw new Error('Media quality events cant be sent outside the context of a meeting. Meeting id is required.');
|
|
@@ -670,6 +683,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
670
683
|
if (options !== null && options !== void 0 && options.preLoginId) {
|
|
671
684
|
return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options === null || options === void 0 ? void 0 : options.preLoginId);
|
|
672
685
|
}
|
|
686
|
+
this.validator({
|
|
687
|
+
type: 'ce',
|
|
688
|
+
event: diagnosticEvent
|
|
689
|
+
});
|
|
673
690
|
return this.submitToCallDiagnostics(diagnosticEvent);
|
|
674
691
|
}
|
|
675
692
|
|
|
@@ -733,7 +750,9 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
|
|
|
733
750
|
body: {
|
|
734
751
|
metrics: [diagnosticEvent]
|
|
735
752
|
},
|
|
736
|
-
headers: {}
|
|
753
|
+
headers: {},
|
|
754
|
+
// @ts-ignore
|
|
755
|
+
waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout
|
|
737
756
|
};
|
|
738
757
|
if (options.preLoginId) {
|
|
739
758
|
request.headers = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","event","preLoginId","diagnosticEvent","prepareDiagnosticMetricItem","webex","eventPayload","type","originTime","sent","Date","toISOString","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","internal","newMetrics","postPreLoginMetric","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","options","defaultClientType","config","metrics","clientType","defaultSubClientType","subClientType","providedClientVersion","clientVersion","defaultSDKClientVersion","CLIENT_NAME","version","versionMetadata","extractVersionMetadata","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","clientInfo","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","osVersion","os","getOSNameInternal","browser","browserVersion","environment","newEnvironment","clientLaunchMethod","Error","mediaConnections","correlationId","webexConferenceIdStr","globalMeetingId","identifiers","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","confID","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","eventId","uuid","v4","triggered","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","serviceErrorName","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","errorData","errorName","rawError","isBrowserMediaErrorName","getErrorPayloadForClientErrorCode","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","body","code","reason","reasonCode","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","isMeetingInfoServiceError","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","isNetworkError","NETWORK_ERROR","errorDescription","message","isUnauthorizedError","AUTHENTICATION_FAILED_CODE","UNKNOWN_ERROR","errors","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","rawErrorMessage","generateCommonErrorMetadata","generatedError","generateClientEventErrorPayload","push","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","submitToCallDiagnosticsPreLogin","finalEvent","request","clientEvent","method","service","resource","headers","authorization","prepareFetchOptions","clientErrorPayload","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n extractVersionMetadata,\n isMeetingInfoServiceError,\n isBrowserMediaErrorName,\n isNetworkError,\n isUnauthorizedError,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n EnvironmentType,\n NewEnvironmentType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientLaunchMethodType,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n ClientEventPayloadError,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n UNKNOWN_ERROR,\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n NETWORK_ERROR,\n AUTHENTICATION_FAILED_CODE,\n} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n clientLaunchMethod?: ClientLaunchMethodType;\n environment?: EnvironmentType;\n newEnvironment?: NewEnvironmentType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n preLoginId?: string;\n globalMeetingId?: string;\n webexConferenceIdStr?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n private logger: any; // to avoid adding @ts-ignore everywhere\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Returns if the meeting has converged architecture enabled\n * @param options.meetingId\n */\n getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n return meeting?.meetingInfo?.enableConvergedArchitecture;\n }\n\n return undefined;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n // @ts-ignore\n const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;\n // @ts-ignore\n const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;\n\n let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};\n\n // sdk version split doesn't really make sense for now...\n if (providedClientVersion) {\n versionMetadata = extractVersionMetadata(providedClientVersion);\n }\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.config?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n clientVersion: providedClientVersion || defaultSDKClientVersion,\n ...versionMetadata,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n if (options?.environment) {\n origin.environment = options.environment;\n }\n\n if (options?.newEnvironment) {\n origin.newEnvironment = options.newEnvironment;\n }\n\n if (options?.clientLaunchMethod) {\n origin.clientInfo.clientLaunchMethod = options.clientLaunchMethod;\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {\n meeting,\n mediaConnections,\n correlationId,\n webexConferenceIdStr,\n globalMeetingId,\n preLoginId,\n } = options;\n const identifiers: Event['event']['identifiers'] = {\n correlationId: 'unknown',\n };\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId || preLoginId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (meeting?.meetingInfo?.confID) {\n identifiers.webexConferenceIdStr = meeting.meetingInfo?.confID;\n }\n\n if (meeting?.meetingInfo?.meetingId) {\n identifiers.globalMeetingId = meeting.meetingInfo?.meetingId;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {\n identifiers.webexConferenceIdStr = webexConferenceIdStr;\n }\n\n if (!identifiers?.globalMeetingId && globalMeetingId) {\n identifiers.globalMeetingId = globalMeetingId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections, webexConferenceIdStr, globalMeetingId} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n webexConferenceIdStr,\n globalMeetingId,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n serviceErrorName,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n serviceErrorName?: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n serviceErrorName ? {errorData: {errorName: serviceErrorName}} : {},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n if (rawError.name) {\n if (isBrowserMediaErrorName(rawError.name)) {\n return this.getErrorPayloadForClientErrorCode({\n serviceErrorCode: undefined,\n clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],\n serviceErrorName: rawError.name,\n });\n }\n }\n\n const serviceErrorCode =\n rawError?.error?.body?.errorCode ||\n rawError?.body?.errorCode ||\n rawError?.body?.code ||\n rawError?.body?.reason?.reasonCode;\n\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return new locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n }\n\n if (isMeetingInfoServiceError(rawError)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n if (isNetworkError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NETWORK_ERROR,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n if (isUnauthorizedError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: AUTHENTICATION_FAILED_CODE,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n // otherwise return unkown error\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: UNKNOWN_ERROR,\n serviceErrorCode: UNKNOWN_ERROR,\n });\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectInMeeting. Creating in meeting event object.',\n `name: ${name}`\n );\n const {meetingId, mediaConnections, globalMeetingId, webexConferenceIdStr} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `name: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n webexConferenceIdStr,\n globalMeetingId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({\n meetingId,\n }),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\n }\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectPreMeeting. Creating pre meeting event object.',\n `name: ${name}`\n );\n const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n preLoginId,\n globalMeetingId,\n webexConferenceIdStr,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n errors,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\n }\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId, rawError} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // check if we need to generate errors\n const errors: ClientEventPayloadError = [];\n\n if (rawError) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Error detected, attempting to map and attach it to the event...',\n `name: ${name}`,\n `rawError: ${generateCommonErrorMetadata(rawError)}`\n );\n\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',\n `generatedError: ${JSON.stringify(generatedError)}`\n );\n }\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options, errors});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options, errors});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n if (options?.preLoginId) {\n return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);\n }\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitToCallDiagnostics. Preparing to send the request',\n `finalEvent: ${JSON.stringify(finalEvent)}`\n );\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Pre login events are not batched. We make the request directly.\n * @param event\n * @param preLoginId\n * @returns\n */\n public submitToCallDiagnosticsPreLogin = (event: Event, preLoginId?: string): Promise<any> => {\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: event,\n type: ['diagnostic-event'],\n });\n\n // append sent timestamp\n diagnosticEvent.eventPayload.originTime.sent = new Date().toISOString();\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticMetrics: @submitToCallDiagnosticsPreLogin. Sending the request:`,\n `diagnosticEvent: ${JSON.stringify(diagnosticEvent)}`\n );\n\n // @ts-ignore\n return this.webex.internal.newMetrics.postPreLoginMetric(diagnosticEvent, preLoginId);\n };\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n const request = {\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n headers: {},\n };\n\n if (options.preLoginId) {\n request.headers = {\n authorization: false,\n 'x-prelogin-userid': options.preLoginId,\n };\n request.resource = 'clientmetrics-prelogin';\n }\n\n // @ts-ignore\n return this.webex.prepareFetchOptions(request);\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n const clientErrorPayload = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n return clientErrorPayload?.category === 'expected';\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","options","resolve","event","valid","preLoginId","diagnosticEvent","prepareDiagnosticMetricItem","webex","eventPayload","type","originTime","sent","Date","toISOString","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","internal","newMetrics","postPreLoginMetric","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","defaultClientType","config","metrics","clientType","defaultSubClientType","subClientType","providedClientVersion","clientVersion","defaultSDKClientVersion","CLIENT_NAME","version","versionMetadata","extractVersionMetadata","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","clientInfo","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","osVersion","os","getOSNameInternal","browser","browserVersion","environment","newEnvironment","clientLaunchMethod","Error","mediaConnections","correlationId","webexConferenceIdStr","globalMeetingId","identifiers","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","confID","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","eventId","uuid","v4","triggered","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","prepareDiagnosticEvent","validator","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","serviceErrorName","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","errorData","errorName","rawError","isBrowserMediaErrorName","getErrorPayloadForClientErrorCode","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","body","code","reason","reasonCode","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","isMeetingInfoServiceError","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","isNetworkError","NETWORK_ERROR","errorDescription","message","isUnauthorizedError","AUTHENTICATION_FAILED_CODE","UNKNOWN_ERROR","errors","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","rawErrorMessage","generateCommonErrorMetadata","generatedError","generateClientEventErrorPayload","push","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","submitToCallDiagnosticsPreLogin","finalEvent","request","clientEvent","method","service","resource","headers","waitForServiceTimeout","authorization","prepareFetchOptions","clientErrorPayload","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n extractVersionMetadata,\n isMeetingInfoServiceError,\n isBrowserMediaErrorName,\n isNetworkError,\n isUnauthorizedError,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n EnvironmentType,\n NewEnvironmentType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientLaunchMethodType,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n ClientEventPayloadError,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n UNKNOWN_ERROR,\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n NETWORK_ERROR,\n AUTHENTICATION_FAILED_CODE,\n} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n clientLaunchMethod?: ClientLaunchMethodType;\n environment?: EnvironmentType;\n newEnvironment?: NewEnvironmentType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n preLoginId?: string;\n globalMeetingId?: string;\n webexConferenceIdStr?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n private logger: any; // to avoid adding @ts-ignore everywhere\n // the default validator before piping an event to the batcher\n // this function can be overridden by the user\n public validator: (options: {\n type: 'mqe' | 'ce';\n event: Event;\n }) => Promise<{event: Event; valid: boolean}> = (options: {type: 'mqe' | 'ce'; event: Event}) =>\n Promise.resolve({event: options?.event, valid: true});\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Returns if the meeting has converged architecture enabled\n * @param options.meetingId\n */\n getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n return meeting?.meetingInfo?.enableConvergedArchitecture;\n }\n\n return undefined;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n // @ts-ignore\n const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;\n // @ts-ignore\n const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;\n\n let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};\n\n // sdk version split doesn't really make sense for now...\n if (providedClientVersion) {\n versionMetadata = extractVersionMetadata(providedClientVersion);\n }\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.config?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n clientVersion: providedClientVersion || defaultSDKClientVersion,\n ...versionMetadata,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n if (options?.environment) {\n origin.environment = options.environment;\n }\n\n if (options?.newEnvironment) {\n origin.newEnvironment = options.newEnvironment;\n }\n\n if (options?.clientLaunchMethod) {\n origin.clientInfo.clientLaunchMethod = options.clientLaunchMethod;\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {\n meeting,\n mediaConnections,\n correlationId,\n webexConferenceIdStr,\n globalMeetingId,\n preLoginId,\n } = options;\n const identifiers: Event['event']['identifiers'] = {\n correlationId: 'unknown',\n };\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId || preLoginId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (meeting?.meetingInfo?.confID) {\n identifiers.webexConferenceIdStr = `${meeting.meetingInfo?.confID}`;\n }\n\n if (meeting?.meetingInfo?.meetingId) {\n identifiers.globalMeetingId = meeting.meetingInfo?.meetingId;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {\n identifiers.webexConferenceIdStr = `${webexConferenceIdStr}`;\n }\n\n if (!identifiers?.globalMeetingId && globalMeetingId) {\n identifiers.globalMeetingId = globalMeetingId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections, webexConferenceIdStr, globalMeetingId} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n webexConferenceIdStr,\n globalMeetingId,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.validator({type: 'mqe', event: diagnosticEvent});\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n serviceErrorName,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n serviceErrorName?: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n serviceErrorName ? {errorData: {errorName: serviceErrorName}} : {},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n if (rawError.name) {\n if (isBrowserMediaErrorName(rawError.name)) {\n return this.getErrorPayloadForClientErrorCode({\n serviceErrorCode: undefined,\n clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],\n serviceErrorName: rawError.name,\n });\n }\n }\n\n const serviceErrorCode =\n rawError?.error?.body?.errorCode ||\n rawError?.body?.errorCode ||\n rawError?.body?.code ||\n rawError?.body?.reason?.reasonCode;\n\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return new locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n }\n\n if (isMeetingInfoServiceError(rawError)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n if (isNetworkError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NETWORK_ERROR,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n if (isUnauthorizedError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: AUTHENTICATION_FAILED_CODE,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n // otherwise return unkown error\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: UNKNOWN_ERROR,\n serviceErrorCode: UNKNOWN_ERROR,\n });\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectInMeeting. Creating in meeting event object.',\n `name: ${name}`\n );\n const {meetingId, mediaConnections, globalMeetingId, webexConferenceIdStr} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `name: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n webexConferenceIdStr,\n globalMeetingId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({\n meetingId,\n }),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\n }\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectPreMeeting. Creating pre meeting event object.',\n `name: ${name}`\n );\n const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n preLoginId,\n globalMeetingId,\n webexConferenceIdStr,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n errors,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\n }\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId, rawError} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // check if we need to generate errors\n const errors: ClientEventPayloadError = [];\n\n if (rawError) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Error detected, attempting to map and attach it to the event...',\n `name: ${name}`,\n `rawError: ${generateCommonErrorMetadata(rawError)}`\n );\n\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',\n `generatedError: ${JSON.stringify(generatedError)}`\n );\n }\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options, errors});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options, errors});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n if (options?.preLoginId) {\n return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);\n }\n\n this.validator({type: 'ce', event: diagnosticEvent});\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitToCallDiagnostics. Preparing to send the request',\n `finalEvent: ${JSON.stringify(finalEvent)}`\n );\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Pre login events are not batched. We make the request directly.\n * @param event\n * @param preLoginId\n * @returns\n */\n public submitToCallDiagnosticsPreLogin = (event: Event, preLoginId?: string): Promise<any> => {\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: event,\n type: ['diagnostic-event'],\n });\n\n // append sent timestamp\n diagnosticEvent.eventPayload.originTime.sent = new Date().toISOString();\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticMetrics: @submitToCallDiagnosticsPreLogin. Sending the request:`,\n `diagnosticEvent: ${JSON.stringify(diagnosticEvent)}`\n );\n\n // @ts-ignore\n return this.webex.internal.newMetrics.postPreLoginMetric(diagnosticEvent, preLoginId);\n };\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n const request = {\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n headers: {},\n // @ts-ignore\n waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout,\n };\n\n if (options.preLoginId) {\n request.headers = {\n authorization: false,\n 'x-prelogin-userid': options.preLoginId,\n };\n request.resource = 'clientmetrics-prelogin';\n }\n\n // @ts-ignore\n return this.webex.prepareFetchOptions(request);\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n const clientErrorPayload = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n return clientErrorPayload?.category === 'expected';\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ClientMetricsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareRequest","queue","submitHttpRequest","payload","webex","request","method","service","resource","body","metrics"],"sources":["client-metrics-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport Batcher from './batcher';\n\nconst ClientMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Add more defaults to payload when the clientmetrics endpoint evolves to support richer payloads\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(queue);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n });\n },\n});\n\nexport default ClientMetricsBatcher;\n"],"mappings":";;;;;;;;;AAIA;AAJA;AACA;AACA;;AAIA,IAAMA,oBAAoB,GAAGC,gBAAO,CAACC,MAAM,CAAC;EAC1CC,SAAS,EAAE,SAAS;EAEpBC,WAAW,uBAACC,IAAI,EAAE;IAChB;IACA,OAAO,iBAAQC,OAAO,CAACD,IAAI,CAAC;EAC9B,CAAC;EAEDE,cAAc,0BAACC,KAAK,EAAE;IACpB,OAAO,iBAAQF,OAAO,CAACE,KAAK,CAAC;EAC/B,CAAC;EAEDC,iBAAiB,6BAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEP;MACX;
|
|
1
|
+
{"version":3,"names":["ClientMetricsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareRequest","queue","submitHttpRequest","payload","webex","request","method","service","resource","body","metrics","waitForServiceTimeout","config"],"sources":["client-metrics-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport Batcher from './batcher';\n\nconst ClientMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Add more defaults to payload when the clientmetrics endpoint evolves to support richer payloads\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(queue);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n });\n },\n});\n\nexport default ClientMetricsBatcher;\n"],"mappings":";;;;;;;;;AAIA;AAJA;AACA;AACA;;AAIA,IAAMA,oBAAoB,GAAGC,gBAAO,CAACC,MAAM,CAAC;EAC1CC,SAAS,EAAE,SAAS;EAEpBC,WAAW,uBAACC,IAAI,EAAE;IAChB;IACA,OAAO,iBAAQC,OAAO,CAACD,IAAI,CAAC;EAC9B,CAAC;EAEDE,cAAc,0BAACC,KAAK,EAAE;IACpB,OAAO,iBAAQF,OAAO,CAACE,KAAK,CAAC;EAC/B,CAAC;EAEDC,iBAAiB,6BAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEP;MACX,CAAC;MACDQ,qBAAqB,EAAE,IAAI,CAACP,KAAK,CAACQ,MAAM,CAACF,OAAO,CAACC;IACnD,CAAC,CAAC;EACJ;AACF,CAAC,CAAC;AAAC,eAEYlB,oBAAoB;AAAA"}
|
package/dist/config.js
CHANGED
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["CLIENT_NAME","device","preDiscoveryServices","metricsServiceUrl","process","env","METRICS_SERVICE_URL","metrics","appType","inBrowser","batcherWait","batcherMaxCalls","batcherMaxWait","batcherRetryPlateau","OS_NAME","WINDOWS","MAC","IOS","ANDROID","CHROME","LINUX","OTHERS","OSMap","macOS","Windows","iOS","Android","Linux"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {inBrowser} from '@webex/common';\n\nexport const CLIENT_NAME = 'webex-js-sdk';\nexport default {\n device: {\n preDiscoveryServices: {\n metricsServiceUrl:\n process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n },\n },\n metrics: {\n appType: inBrowser ? 'browser' : 'nodejs',\n batcherWait: 500,\n batcherMaxCalls: 50,\n batcherMaxWait: 1500,\n batcherRetryPlateau: 32000,\n },\n};\n\nexport const OS_NAME = {\n WINDOWS: 'windows',\n MAC: 'mac',\n IOS: 'ios',\n ANDROID: 'android',\n CHROME: 'chrome',\n LINUX: 'linux',\n OTHERS: 'other',\n};\n\nexport const OSMap = {\n 'Chrome OS': OS_NAME.CHROME,\n macOS: OS_NAME.MAC,\n Windows: OS_NAME.WINDOWS,\n iOS: OS_NAME.IOS,\n Android: OS_NAME.ANDROID,\n Linux: OS_NAME.LINUX,\n};\n"],"mappings":";;;;;;;AAIA;AAJA;AACA;AACA;;AAIO,IAAMA,WAAW,GAAG,cAAc;AAAC;AAAA,eAC3B;EACbC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBC,iBAAiB,EACfC,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI,2CAA2C;MAChFC,OAAO,EAAEH,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI;IAC9C;EACF,CAAC;EACDC,OAAO,EAAE;IACPC,OAAO,EAAEC,iBAAS,GAAG,SAAS,GAAG,QAAQ;IACzCC,WAAW,EAAE,GAAG;IAChBC,eAAe,EAAE,EAAE;IACnBC,cAAc,EAAE,IAAI;IACpBC,mBAAmB,EAAE;
|
|
1
|
+
{"version":3,"names":["CLIENT_NAME","device","preDiscoveryServices","metricsServiceUrl","process","env","METRICS_SERVICE_URL","metrics","appType","inBrowser","batcherWait","batcherMaxCalls","batcherMaxWait","batcherRetryPlateau","waitForServiceTimeout","OS_NAME","WINDOWS","MAC","IOS","ANDROID","CHROME","LINUX","OTHERS","OSMap","macOS","Windows","iOS","Android","Linux"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {inBrowser} from '@webex/common';\n\nexport const CLIENT_NAME = 'webex-js-sdk';\nexport default {\n device: {\n preDiscoveryServices: {\n metricsServiceUrl:\n process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n },\n },\n metrics: {\n appType: inBrowser ? 'browser' : 'nodejs',\n batcherWait: 500,\n batcherMaxCalls: 50,\n batcherMaxWait: 1500,\n batcherRetryPlateau: 32000,\n waitForServiceTimeout: 15,\n },\n};\n\nexport const OS_NAME = {\n WINDOWS: 'windows',\n MAC: 'mac',\n IOS: 'ios',\n ANDROID: 'android',\n CHROME: 'chrome',\n LINUX: 'linux',\n OTHERS: 'other',\n};\n\nexport const OSMap = {\n 'Chrome OS': OS_NAME.CHROME,\n macOS: OS_NAME.MAC,\n Windows: OS_NAME.WINDOWS,\n iOS: OS_NAME.IOS,\n Android: OS_NAME.ANDROID,\n Linux: OS_NAME.LINUX,\n};\n"],"mappings":";;;;;;;AAIA;AAJA;AACA;AACA;;AAIO,IAAMA,WAAW,GAAG,cAAc;AAAC;AAAA,eAC3B;EACbC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBC,iBAAiB,EACfC,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI,2CAA2C;MAChFC,OAAO,EAAEH,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI;IAC9C;EACF,CAAC;EACDC,OAAO,EAAE;IACPC,OAAO,EAAEC,iBAAS,GAAG,SAAS,GAAG,QAAQ;IACzCC,WAAW,EAAE,GAAG;IAChBC,eAAe,EAAE,EAAE;IACnBC,cAAc,EAAE,IAAI;IACpBC,mBAAmB,EAAE,KAAK;IAC1BC,qBAAqB,EAAE;EACzB;AACF,CAAC;AAAA;AAEM,IAAMC,OAAO,GAAG;EACrBC,OAAO,EAAE,SAAS;EAClBC,GAAG,EAAE,KAAK;EACVC,GAAG,EAAE,KAAK;EACVC,OAAO,EAAE,SAAS;EAClBC,MAAM,EAAE,QAAQ;EAChBC,KAAK,EAAE,OAAO;EACdC,MAAM,EAAE;AACV,CAAC;AAAC;AAEK,IAAMC,KAAK,GAAG;EACnB,WAAW,EAAER,OAAO,CAACK,MAAM;EAC3BI,KAAK,EAAET,OAAO,CAACE,GAAG;EAClBQ,OAAO,EAAEV,OAAO,CAACC,OAAO;EACxBU,GAAG,EAAEX,OAAO,CAACG,GAAG;EAChBS,OAAO,EAAEZ,OAAO,CAACI,OAAO;EACxBS,KAAK,EAAEb,OAAO,CAACM;AACjB,CAAC;AAAC"}
|
package/dist/metrics.js
CHANGED
|
@@ -24,6 +24,13 @@ type GetIdentifiersOptions = {
|
|
|
24
24
|
export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
25
25
|
private callDiagnosticEventsBatcher;
|
|
26
26
|
private logger;
|
|
27
|
+
validator: (options: {
|
|
28
|
+
type: 'mqe' | 'ce';
|
|
29
|
+
event: Event;
|
|
30
|
+
}) => Promise<{
|
|
31
|
+
event: Event;
|
|
32
|
+
valid: boolean;
|
|
33
|
+
}>;
|
|
27
34
|
/**
|
|
28
35
|
* Constructor
|
|
29
36
|
* @param args
|
|
@@ -67,13 +74,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
67
74
|
macAddress?: string;
|
|
68
75
|
localNetworkPrefix?: string;
|
|
69
76
|
publicNetworkPrefix?: string;
|
|
70
|
-
browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient";
|
|
77
|
+
browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient" | "switch-to-web" | "switch-to-native";
|
|
71
78
|
clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch";
|
|
72
79
|
browser?: string;
|
|
73
80
|
browserVersion?: string;
|
|
74
81
|
clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC";
|
|
75
82
|
subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MOBILE_APP" | "MOBILE_NETWORK" | "VDI_APP" | "WEB_APP";
|
|
76
83
|
clientVersion?: string;
|
|
84
|
+
clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
|
|
77
85
|
localClientVersion?: string;
|
|
78
86
|
modelNumber?: string;
|
|
79
87
|
joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
|
package/dist/types/config.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-metrics",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.284",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
"build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@webex/common": "3.0.0-beta.
|
|
32
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
33
|
-
"@webex/event-dictionary-ts": "^1.0.
|
|
34
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
35
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
36
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
38
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
31
|
+
"@webex/common": "3.0.0-beta.284",
|
|
32
|
+
"@webex/common-timers": "3.0.0-beta.284",
|
|
33
|
+
"@webex/event-dictionary-ts": "^1.0.1313",
|
|
34
|
+
"@webex/internal-plugin-device": "3.0.0-beta.284",
|
|
35
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.284",
|
|
36
|
+
"@webex/test-helper-chai": "3.0.0-beta.284",
|
|
37
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.284",
|
|
38
|
+
"@webex/webex-core": "3.0.0-beta.284"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/batcher.js
CHANGED
|
@@ -82,6 +82,13 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
82
82
|
// @ts-ignore
|
|
83
83
|
private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;
|
|
84
84
|
private logger: any; // to avoid adding @ts-ignore everywhere
|
|
85
|
+
// the default validator before piping an event to the batcher
|
|
86
|
+
// this function can be overridden by the user
|
|
87
|
+
public validator: (options: {
|
|
88
|
+
type: 'mqe' | 'ce';
|
|
89
|
+
event: Event;
|
|
90
|
+
}) => Promise<{event: Event; valid: boolean}> = (options: {type: 'mqe' | 'ce'; event: Event}) =>
|
|
91
|
+
Promise.resolve({event: options?.event, valid: true});
|
|
85
92
|
|
|
86
93
|
/**
|
|
87
94
|
* Constructor
|
|
@@ -247,7 +254,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
247
254
|
}
|
|
248
255
|
|
|
249
256
|
if (meeting?.meetingInfo?.confID) {
|
|
250
|
-
identifiers.webexConferenceIdStr = meeting.meetingInfo?.confID
|
|
257
|
+
identifiers.webexConferenceIdStr = `${meeting.meetingInfo?.confID}`;
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
if (meeting?.meetingInfo?.meetingId) {
|
|
@@ -260,7 +267,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
260
267
|
}
|
|
261
268
|
|
|
262
269
|
if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {
|
|
263
|
-
identifiers.webexConferenceIdStr = webexConferenceIdStr
|
|
270
|
+
identifiers.webexConferenceIdStr = `${webexConferenceIdStr}`;
|
|
264
271
|
}
|
|
265
272
|
|
|
266
273
|
if (!identifiers?.globalMeetingId && globalMeetingId) {
|
|
@@ -389,6 +396,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
389
396
|
|
|
390
397
|
// append media quality event data to the call diagnostic event
|
|
391
398
|
const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);
|
|
399
|
+
this.validator({type: 'mqe', event: diagnosticEvent});
|
|
392
400
|
this.submitToCallDiagnostics(diagnosticEvent);
|
|
393
401
|
} else {
|
|
394
402
|
throw new Error(
|
|
@@ -721,6 +729,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
721
729
|
return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);
|
|
722
730
|
}
|
|
723
731
|
|
|
732
|
+
this.validator({type: 'ce', event: diagnosticEvent});
|
|
733
|
+
|
|
724
734
|
return this.submitToCallDiagnostics(diagnosticEvent);
|
|
725
735
|
}
|
|
726
736
|
|
|
@@ -815,6 +825,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
815
825
|
metrics: [diagnosticEvent],
|
|
816
826
|
},
|
|
817
827
|
headers: {},
|
|
828
|
+
// @ts-ignore
|
|
829
|
+
waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout,
|
|
818
830
|
};
|
|
819
831
|
|
|
820
832
|
if (options.preLoginId) {
|
package/src/config.js
CHANGED
|
@@ -37,6 +37,7 @@ describe('plugin-metrics', () => {
|
|
|
37
37
|
return Promise.resolve({
|
|
38
38
|
statusCode: 204,
|
|
39
39
|
body: undefined,
|
|
40
|
+
waitForServiceTimeout: 15,
|
|
40
41
|
options,
|
|
41
42
|
});
|
|
42
43
|
};
|
|
@@ -97,6 +98,7 @@ describe('plugin-metrics', () => {
|
|
|
97
98
|
return Promise.resolve({
|
|
98
99
|
statusCode: 204,
|
|
99
100
|
body: undefined,
|
|
101
|
+
waitForServiceTimeout: 15,
|
|
100
102
|
options,
|
|
101
103
|
});
|
|
102
104
|
});
|
|
@@ -9,7 +9,7 @@ import MockWebex from '@webex/test-helper-mock-webex';
|
|
|
9
9
|
import sinon from 'sinon';
|
|
10
10
|
import FakeTimers from '@sinonjs/fake-timers';
|
|
11
11
|
import {NewMetrics} from '@webex/internal-plugin-metrics';
|
|
12
|
-
import {
|
|
12
|
+
import {uniqueId} from 'lodash';
|
|
13
13
|
|
|
14
14
|
const flushPromises = () => new Promise(setImmediate);
|
|
15
15
|
|
|
@@ -24,14 +24,12 @@ function promiseTick(count) {
|
|
|
24
24
|
return promise;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
27
|
describe('plugin-metrics', () => {
|
|
29
28
|
describe('CallDiagnosticEventsBatcher', () => {
|
|
30
29
|
let webex;
|
|
31
30
|
let clock;
|
|
32
31
|
let now;
|
|
33
32
|
|
|
34
|
-
|
|
35
33
|
beforeEach(() => {
|
|
36
34
|
now = new Date();
|
|
37
35
|
clock = FakeTimers.install({now});
|
|
@@ -39,14 +37,15 @@ describe('plugin-metrics', () => {
|
|
|
39
37
|
//@ts-ignore
|
|
40
38
|
webex = new MockWebex({
|
|
41
39
|
children: {
|
|
42
|
-
newMetrics: NewMetrics
|
|
43
|
-
}
|
|
40
|
+
newMetrics: NewMetrics,
|
|
41
|
+
},
|
|
44
42
|
});
|
|
45
43
|
|
|
46
|
-
webex.request = (options) =>
|
|
44
|
+
webex.request = (options) =>
|
|
45
|
+
Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
|
|
47
46
|
sinon.spy(webex, 'request');
|
|
48
47
|
|
|
49
|
-
webex.emit(
|
|
48
|
+
webex.emit('ready');
|
|
50
49
|
|
|
51
50
|
webex.config.metrics = config.metrics;
|
|
52
51
|
});
|
|
@@ -70,7 +69,10 @@ describe('plugin-metrics', () => {
|
|
|
70
69
|
|
|
71
70
|
//@ts-ignore
|
|
72
71
|
assert.calledOnce(webex.request);
|
|
73
|
-
assert.lengthOf(
|
|
72
|
+
assert.lengthOf(
|
|
73
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
74
|
+
0
|
|
75
|
+
);
|
|
74
76
|
});
|
|
75
77
|
|
|
76
78
|
it('doesnt include any joinTimes for other events', async () => {
|
|
@@ -88,12 +90,19 @@ describe('plugin-metrics', () => {
|
|
|
88
90
|
assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
|
|
89
91
|
name: 'client.alert.displayed',
|
|
90
92
|
});
|
|
91
|
-
assert.lengthOf(
|
|
93
|
+
assert.lengthOf(
|
|
94
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
95
|
+
0
|
|
96
|
+
);
|
|
92
97
|
});
|
|
93
98
|
|
|
94
99
|
it('appends the correct join times to the request for client.interstitial-window.launched', async () => {
|
|
95
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
96
|
-
|
|
100
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
101
|
+
.stub()
|
|
102
|
+
.returns(10);
|
|
103
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
|
|
104
|
+
.stub()
|
|
105
|
+
.returns(10);
|
|
97
106
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
98
107
|
//@ts-ignore
|
|
99
108
|
{event: {name: 'client.interstitial-window.launched'}}
|
|
@@ -112,11 +121,16 @@ describe('plugin-metrics', () => {
|
|
|
112
121
|
meetingInfoReqResp: 10,
|
|
113
122
|
},
|
|
114
123
|
});
|
|
115
|
-
assert.lengthOf(
|
|
124
|
+
assert.lengthOf(
|
|
125
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
126
|
+
0
|
|
127
|
+
);
|
|
116
128
|
});
|
|
117
129
|
|
|
118
130
|
it('appends the correct join times to the request for client.call.initiated', async () => {
|
|
119
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
131
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
132
|
+
.stub()
|
|
133
|
+
.returns(10);
|
|
120
134
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
121
135
|
//@ts-ignore
|
|
122
136
|
{event: {name: 'client.call.initiated'}}
|
|
@@ -134,16 +148,27 @@ describe('plugin-metrics', () => {
|
|
|
134
148
|
showInterstitialTime: 10,
|
|
135
149
|
},
|
|
136
150
|
});
|
|
137
|
-
assert.lengthOf(
|
|
151
|
+
assert.lengthOf(
|
|
152
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
153
|
+
0
|
|
154
|
+
);
|
|
138
155
|
});
|
|
139
156
|
|
|
140
157
|
it('appends the correct join times to the request for client.locus.join.response', async () => {
|
|
141
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
142
|
-
|
|
158
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
159
|
+
.stub()
|
|
160
|
+
.returns(10);
|
|
161
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon
|
|
162
|
+
.stub()
|
|
163
|
+
.returns(20);
|
|
143
164
|
webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
|
|
144
165
|
webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
|
|
145
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
|
|
146
|
-
|
|
166
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
|
|
167
|
+
.stub()
|
|
168
|
+
.returns(10);
|
|
169
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon
|
|
170
|
+
.stub()
|
|
171
|
+
.returns(10);
|
|
147
172
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
148
173
|
//@ts-ignore
|
|
149
174
|
{event: {name: 'client.locus.join.response'}}
|
|
@@ -169,11 +194,16 @@ describe('plugin-metrics', () => {
|
|
|
169
194
|
clientJmt: 5,
|
|
170
195
|
},
|
|
171
196
|
});
|
|
172
|
-
assert.lengthOf(
|
|
197
|
+
assert.lengthOf(
|
|
198
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
199
|
+
0
|
|
200
|
+
);
|
|
173
201
|
});
|
|
174
202
|
|
|
175
203
|
it('appends the correct join times to the request for client.ice.end', async () => {
|
|
176
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
204
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
205
|
+
.stub()
|
|
206
|
+
.returns(10);
|
|
177
207
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
178
208
|
//@ts-ignore
|
|
179
209
|
{event: {name: 'client.ice.end'}}
|
|
@@ -194,11 +224,16 @@ describe('plugin-metrics', () => {
|
|
|
194
224
|
videoICESetupTime: 10,
|
|
195
225
|
},
|
|
196
226
|
});
|
|
197
|
-
assert.lengthOf(
|
|
227
|
+
assert.lengthOf(
|
|
228
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
229
|
+
0
|
|
230
|
+
);
|
|
198
231
|
});
|
|
199
232
|
|
|
200
233
|
it('appends the correct join times to the request for client.media.rx.start', async () => {
|
|
201
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
234
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
235
|
+
.stub()
|
|
236
|
+
.returns(10);
|
|
202
237
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
203
238
|
//@ts-ignore
|
|
204
239
|
{event: {name: 'client.media.rx.start'}}
|
|
@@ -216,13 +251,22 @@ describe('plugin-metrics', () => {
|
|
|
216
251
|
localSDPGenRemoteSDPRecv: 10,
|
|
217
252
|
},
|
|
218
253
|
});
|
|
219
|
-
assert.lengthOf(
|
|
254
|
+
assert.lengthOf(
|
|
255
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
256
|
+
0
|
|
257
|
+
);
|
|
220
258
|
});
|
|
221
259
|
|
|
222
260
|
it('appends the correct join times to the request for client.media-engine.ready', async () => {
|
|
223
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
224
|
-
|
|
225
|
-
|
|
261
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
262
|
+
.stub()
|
|
263
|
+
.returns(10);
|
|
264
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon
|
|
265
|
+
.stub()
|
|
266
|
+
.returns(10);
|
|
267
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
|
|
268
|
+
.stub()
|
|
269
|
+
.returns(10);
|
|
226
270
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
227
271
|
//@ts-ignore
|
|
228
272
|
{event: {name: 'client.media-engine.ready'}}
|
|
@@ -243,11 +287,16 @@ describe('plugin-metrics', () => {
|
|
|
243
287
|
stayLobbyTime: 10,
|
|
244
288
|
},
|
|
245
289
|
});
|
|
246
|
-
assert.lengthOf(
|
|
290
|
+
assert.lengthOf(
|
|
291
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
292
|
+
0
|
|
293
|
+
);
|
|
247
294
|
});
|
|
248
295
|
|
|
249
296
|
it('appends the correct audio and video setup delays to the request for client.mediaquality.event', async () => {
|
|
250
|
-
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
297
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
|
|
298
|
+
.stub()
|
|
299
|
+
.returns(10);
|
|
251
300
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
252
301
|
//@ts-ignore
|
|
253
302
|
{event: {name: 'client.mediaquality.event'}}
|
|
@@ -268,9 +317,12 @@ describe('plugin-metrics', () => {
|
|
|
268
317
|
videoSetupDelay: {
|
|
269
318
|
joinRespRxStart: 10,
|
|
270
319
|
joinRespTxStart: 10,
|
|
271
|
-
}
|
|
320
|
+
},
|
|
272
321
|
});
|
|
273
|
-
assert.lengthOf(
|
|
322
|
+
assert.lengthOf(
|
|
323
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
324
|
+
0
|
|
325
|
+
);
|
|
274
326
|
});
|
|
275
327
|
|
|
276
328
|
it('doesnt include audioSetup and videoSetup delays for other events', async () => {
|
|
@@ -285,10 +337,19 @@ describe('plugin-metrics', () => {
|
|
|
285
337
|
|
|
286
338
|
//@ts-ignore
|
|
287
339
|
assert.calledOnce(webex.request);
|
|
288
|
-
assert.deepEqual(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
340
|
+
assert.deepEqual(
|
|
341
|
+
webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.audioSetupDelay,
|
|
342
|
+
undefined
|
|
343
|
+
);
|
|
344
|
+
assert.deepEqual(
|
|
345
|
+
webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.videoSetupDelay,
|
|
346
|
+
undefined
|
|
347
|
+
);
|
|
348
|
+
assert.lengthOf(
|
|
349
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
350
|
+
0
|
|
351
|
+
);
|
|
352
|
+
});
|
|
292
353
|
});
|
|
293
354
|
|
|
294
355
|
describe('when the request fails', () => {
|
|
@@ -329,7 +390,10 @@ describe('plugin-metrics', () => {
|
|
|
329
390
|
// This is horrific, but stubbing lodash is proving difficult
|
|
330
391
|
const expectedBatchId = parseInt(uniqueId()) - 1;
|
|
331
392
|
|
|
332
|
-
assert.deepEqual(
|
|
393
|
+
assert.deepEqual(
|
|
394
|
+
JSON.stringify(loggerLogCalls[1].args),
|
|
395
|
+
`["call-diagnostic-events -> ","CallDiagnosticEventsBatcher: @submitHttpRequest#call-diagnostic-metrics-batch-${expectedBatchId}. Sending the request:","payload:",[{"eventPayload":{"event":"my.event","origin":{"buildType":"test","networkType":"unknown"}},"type":["diagnostic-event"]}]]`
|
|
396
|
+
);
|
|
333
397
|
|
|
334
398
|
// check that promise was rejected with the original error of the webex.request
|
|
335
399
|
assert.deepEqual(err, error);
|
|
@@ -340,7 +404,10 @@ describe('plugin-metrics', () => {
|
|
|
340
404
|
`CallDiagnosticEventsBatcher: @submitHttpRequest#call-diagnostic-metrics-batch-${expectedBatchId}. Request failed:`,
|
|
341
405
|
`error: formattedError`
|
|
342
406
|
);
|
|
343
|
-
assert.lengthOf(
|
|
407
|
+
assert.lengthOf(
|
|
408
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
|
|
409
|
+
0
|
|
410
|
+
);
|
|
344
411
|
});
|
|
345
412
|
});
|
|
346
413
|
});
|
|
@@ -349,10 +416,16 @@ describe('plugin-metrics', () => {
|
|
|
349
416
|
it('calls prepareDiagnosticMetricItem correctly', async () => {
|
|
350
417
|
// avoid setting .sent timestamp
|
|
351
418
|
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =
|
|
352
|
-
|
|
419
|
+
(q) => Promise.resolve(q);
|
|
353
420
|
|
|
354
|
-
const prepareItemSpy = sinon.spy(
|
|
355
|
-
|
|
421
|
+
const prepareItemSpy = sinon.spy(
|
|
422
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher,
|
|
423
|
+
'prepareItem'
|
|
424
|
+
);
|
|
425
|
+
const prepareDiagnosticMetricItemSpy = sinon.spy(
|
|
426
|
+
CallDiagnosticUtils,
|
|
427
|
+
'prepareDiagnosticMetricItem'
|
|
428
|
+
);
|
|
356
429
|
|
|
357
430
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics({
|
|
358
431
|
event: 'my.event',
|
|
@@ -374,8 +447,7 @@ describe('plugin-metrics', () => {
|
|
|
374
447
|
|
|
375
448
|
assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
|
|
376
449
|
|
|
377
|
-
|
|
378
|
-
const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls()
|
|
450
|
+
const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls();
|
|
379
451
|
|
|
380
452
|
// second argument (item) also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
|
|
381
453
|
assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[0], webex);
|
|
@@ -387,8 +459,7 @@ describe('plugin-metrics', () => {
|
|
|
387
459
|
},
|
|
388
460
|
});
|
|
389
461
|
assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
})
|
|
462
|
+
});
|
|
463
|
+
});
|
|
393
464
|
});
|
|
394
465
|
});
|
|
@@ -9,6 +9,7 @@ import {BrowserDetection} from '@webex/common';
|
|
|
9
9
|
import {getOSNameInternal} from '@webex/internal-plugin-metrics';
|
|
10
10
|
import uuid from 'uuid';
|
|
11
11
|
import {omit} from 'lodash';
|
|
12
|
+
import CONFIG from '../../../../src/config';
|
|
12
13
|
|
|
13
14
|
//@ts-ignore
|
|
14
15
|
global.window = {location: {hostname: 'whatever'}};
|
|
@@ -50,6 +51,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
50
51
|
},
|
|
51
52
|
metrics: {
|
|
52
53
|
submitClientMetrics: sinon.stub(),
|
|
54
|
+
config: {...CONFIG.metrics}
|
|
53
55
|
},
|
|
54
56
|
newMetrics: {
|
|
55
57
|
postPreLoginMetric: sinon.stub(),
|
|
@@ -102,6 +104,12 @@ describe('internal-plugin-metrics', () => {
|
|
|
102
104
|
sinon.restore();
|
|
103
105
|
});
|
|
104
106
|
|
|
107
|
+
describe('#validator', () => {
|
|
108
|
+
it('should have a validator function defined', () => {
|
|
109
|
+
assert.isDefined(cd.validator);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
105
113
|
describe('#getOrigin', () => {
|
|
106
114
|
it('should build origin correctly', () => {
|
|
107
115
|
sinon.stub(Utils, 'anonymizeIPAddress').returns('1.1.1.1');
|
|
@@ -408,6 +416,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
408
416
|
const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
|
|
409
417
|
const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
|
|
410
418
|
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
419
|
+
const validatorSpy = sinon.spy(cd, 'validator');
|
|
411
420
|
const options = {
|
|
412
421
|
meetingId: fakeMeeting.id,
|
|
413
422
|
mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
|
|
@@ -483,6 +492,39 @@ describe('internal-plugin-metrics', () => {
|
|
|
483
492
|
senderCountryCode: 'UK',
|
|
484
493
|
version: 1,
|
|
485
494
|
});
|
|
495
|
+
assert.calledWith(validatorSpy, {type: 'ce', event: {
|
|
496
|
+
event: {
|
|
497
|
+
canProceed: true,
|
|
498
|
+
eventData: {
|
|
499
|
+
webClientDomain: 'whatever',
|
|
500
|
+
},
|
|
501
|
+
identifiers: {
|
|
502
|
+
correlationId: 'correlationId',
|
|
503
|
+
deviceId: 'deviceUrl',
|
|
504
|
+
locusId: 'url',
|
|
505
|
+
locusStartTime: 'lastActive',
|
|
506
|
+
locusUrl: 'locus/url',
|
|
507
|
+
mediaAgentAlias: 'alias',
|
|
508
|
+
mediaAgentGroupId: '1',
|
|
509
|
+
orgId: 'orgId',
|
|
510
|
+
userId: 'userId',
|
|
511
|
+
},
|
|
512
|
+
loginType: 'login-ci',
|
|
513
|
+
name: 'client.alert.displayed',
|
|
514
|
+
userType: 'host',
|
|
515
|
+
isConvergedArchitectureEnabled: undefined,
|
|
516
|
+
},
|
|
517
|
+
eventId: 'my-fake-id',
|
|
518
|
+
origin: {
|
|
519
|
+
origin: 'fake-origin',
|
|
520
|
+
},
|
|
521
|
+
originTime: {
|
|
522
|
+
sent: 'not_defined_yet',
|
|
523
|
+
triggered: now.toISOString(),
|
|
524
|
+
},
|
|
525
|
+
senderCountryCode: 'UK',
|
|
526
|
+
version: 1,
|
|
527
|
+
}})
|
|
486
528
|
|
|
487
529
|
const webexLoggerLogCalls = webex.logger.log.getCalls();
|
|
488
530
|
assert.deepEqual(webexLoggerLogCalls[0].args, [
|
|
@@ -1211,6 +1253,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1211
1253
|
cd,
|
|
1212
1254
|
'getErrorPayloadForClientErrorCode'
|
|
1213
1255
|
);
|
|
1256
|
+
const validatorSpy = sinon.spy(cd, 'validator');
|
|
1214
1257
|
const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
|
|
1215
1258
|
sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
|
|
1216
1259
|
const options = {
|
|
@@ -1265,6 +1308,38 @@ describe('internal-plugin-metrics', () => {
|
|
|
1265
1308
|
options
|
|
1266
1309
|
);
|
|
1267
1310
|
|
|
1311
|
+
assert.calledWith(validatorSpy, {type: 'mqe', event: {
|
|
1312
|
+
eventId: 'my-fake-id',
|
|
1313
|
+
version: 1,
|
|
1314
|
+
origin: {origin: 'fake-origin'},
|
|
1315
|
+
originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
|
|
1316
|
+
senderCountryCode: 'UK',
|
|
1317
|
+
event: {
|
|
1318
|
+
name: 'client.mediaquality.event',
|
|
1319
|
+
canProceed: true,
|
|
1320
|
+
identifiers: {
|
|
1321
|
+
correlationId: 'correlationId',
|
|
1322
|
+
webexConferenceIdStr: 'webexConferenceIdStr1',
|
|
1323
|
+
globalMeetingId: 'globalMeetingId1',
|
|
1324
|
+
userId: 'userId',
|
|
1325
|
+
deviceId: 'deviceUrl',
|
|
1326
|
+
orgId: 'orgId',
|
|
1327
|
+
locusUrl: 'locus/url',
|
|
1328
|
+
locusId: 'url',
|
|
1329
|
+
locusStartTime: 'lastActive',
|
|
1330
|
+
},
|
|
1331
|
+
eventData: {webClientDomain: 'whatever'},
|
|
1332
|
+
intervals: [{}],
|
|
1333
|
+
sourceMetadata: {
|
|
1334
|
+
applicationSoftwareType: 'webex-js-sdk',
|
|
1335
|
+
applicationSoftwareVersion: 'webex-version',
|
|
1336
|
+
mediaEngineSoftwareType: 'browser',
|
|
1337
|
+
mediaEngineSoftwareVersion: getOSVersion(),
|
|
1338
|
+
startTime: now.toISOString(),
|
|
1339
|
+
},
|
|
1340
|
+
},
|
|
1341
|
+
}});
|
|
1342
|
+
|
|
1268
1343
|
assert.calledWith(submitToCallDiagnosticsSpy, {
|
|
1269
1344
|
eventId: 'my-fake-id',
|
|
1270
1345
|
version: 1,
|
|
@@ -1690,6 +1765,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
1690
1765
|
method: 'POST',
|
|
1691
1766
|
resource: 'clientmetrics-prelogin',
|
|
1692
1767
|
service: 'metrics',
|
|
1768
|
+
waitForServiceTimeout: CONFIG.metrics.waitForServiceTimeout,
|
|
1693
1769
|
headers: {
|
|
1694
1770
|
authorization: false,
|
|
1695
1771
|
'x-prelogin-userid': preLoginId,
|
|
@@ -1701,7 +1777,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
1701
1777
|
method: 'POST',
|
|
1702
1778
|
resource: 'clientmetrics',
|
|
1703
1779
|
service: 'metrics',
|
|
1704
|
-
headers: {}
|
|
1780
|
+
headers: {},
|
|
1781
|
+
waitForServiceTimeout: CONFIG.metrics.waitForServiceTimeout,
|
|
1705
1782
|
})
|
|
1706
1783
|
}
|
|
1707
1784
|
|
|
@@ -37,6 +37,7 @@ describe('plugin-metrics', () => {
|
|
|
37
37
|
return Promise.resolve({
|
|
38
38
|
statusCode: 204,
|
|
39
39
|
body: undefined,
|
|
40
|
+
waitForServiceTimeout: 15,
|
|
40
41
|
options,
|
|
41
42
|
});
|
|
42
43
|
};
|
|
@@ -97,6 +98,7 @@ describe('plugin-metrics', () => {
|
|
|
97
98
|
return Promise.resolve({
|
|
98
99
|
statusCode: 204,
|
|
99
100
|
body: undefined,
|
|
101
|
+
waitForServiceTimeout: 15,
|
|
100
102
|
options,
|
|
101
103
|
});
|
|
102
104
|
});
|