@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.0-test.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +23 -3
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +69 -9
- package/dist/constants.js.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/index.js +16 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +40 -11
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +15 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +42 -21
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +10 -6
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +13 -3
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +135 -330
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +4 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +2187 -1074
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +37 -25
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +34 -19
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +71 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +48 -23
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +25 -4
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +1 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +17 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +142 -57
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +2 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +11 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +17 -1
- package/dist/members/index.js.map +1 -1
- package/dist/members/types.js.map +1 -1
- package/dist/members/util.js +15 -4
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +15 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +16 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +222 -73
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +22 -0
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +262 -432
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +1 -1
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +113 -96
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +57 -25
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +5 -13
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +173 -81
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/index.js +68 -6
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +338 -289
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +296 -156
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +13 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/config.d.ts +1 -1
- package/dist/types/constants.d.ts +66 -13
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/locus-info/index.d.ts +1 -1
- package/dist/types/locus-info/parser.d.ts +3 -2
- package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
- package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
- package/dist/types/meeting/index.d.ts +285 -34
- package/dist/types/meeting/locusMediaRequest.d.ts +1 -2
- package/dist/types/meeting/muteState.d.ts +2 -8
- package/dist/types/meeting/request.d.ts +4 -1
- package/dist/types/meeting/util.d.ts +25 -1
- package/dist/types/meeting-info/index.d.ts +7 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +1 -0
- package/dist/types/meetings/collection.d.ts +9 -0
- package/dist/types/meetings/index.d.ts +42 -14
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/members/types.d.ts +1 -0
- package/dist/types/members/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +15 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +2 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +2 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +25 -1
- package/dist/types/multistream/sendSlotManager.d.ts +9 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +59 -112
- package/dist/types/reachability/request.d.ts +1 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +10 -0
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +2 -1
- package/dist/types/roap/turnDiscovery.d.ts +21 -4
- package/dist/types/rtcMetrics/index.d.ts +15 -1
- package/dist/types/statsAnalyzer/index.d.ts +28 -11
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +3 -2
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +19 -2
- package/src/common/logs/request.ts +5 -1
- package/src/config.ts +1 -1
- package/src/constants.ts +71 -6
- package/src/index.ts +5 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/index.ts +18 -1
- package/src/locus-info/index.ts +52 -16
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/parser.ts +47 -21
- package/src/media/index.ts +8 -6
- package/src/media/properties.ts +17 -2
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +1510 -529
- package/src/meeting/muteState.ts +34 -20
- package/src/meeting/request.ts +19 -1
- package/src/meeting/util.ts +97 -0
- package/src/meeting-info/index.ts +47 -20
- package/src/meeting-info/meeting-info-v2.ts +27 -5
- package/src/meeting-info/utilv2.ts +1 -1
- package/src/meetings/collection.ts +13 -0
- package/src/meetings/index.ts +112 -31
- package/src/meetings/util.ts +2 -8
- package/src/member/index.ts +9 -0
- package/src/member/util.ts +14 -0
- package/src/members/index.ts +29 -2
- package/src/members/types.ts +1 -0
- package/src/members/util.ts +15 -1
- package/src/metrics/constants.ts +14 -0
- package/src/multistream/mediaRequestManager.ts +4 -1
- package/src/multistream/remoteMediaGroup.ts +19 -0
- package/src/multistream/remoteMediaManager.ts +141 -18
- package/src/multistream/sendSlotManager.ts +29 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +221 -382
- package/src/reachability/request.ts +1 -1
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +87 -83
- package/src/roap/index.ts +60 -24
- package/src/roap/request.ts +3 -16
- package/src/roap/turnDiscovery.ts +112 -39
- package/src/rtcMetrics/index.ts +71 -5
- package/src/statsAnalyzer/index.ts +430 -427
- package/src/statsAnalyzer/mqaUtil.ts +317 -168
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +7 -7
- package/test/integration/spec/journey.js +86 -104
- package/test/integration/spec/space-meeting.js +9 -9
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/index.ts +36 -3
- package/test/unit/spec/locus-info/index.js +205 -12
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
- package/test/unit/spec/locus-info/parser.js +54 -13
- package/test/unit/spec/media/index.ts +20 -4
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
- package/test/unit/spec/meeting/index.js +4027 -1075
- package/test/unit/spec/meeting/muteState.js +219 -67
- package/test/unit/spec/meeting/request.js +63 -12
- package/test/unit/spec/meeting/utils.js +93 -0
- package/test/unit/spec/meeting-info/index.js +180 -61
- package/test/unit/spec/meeting-info/meetinginfov2.js +196 -53
- package/test/unit/spec/meetings/collection.js +12 -0
- package/test/unit/spec/meetings/index.js +619 -206
- package/test/unit/spec/meetings/utils.js +35 -12
- package/test/unit/spec/member/index.js +8 -7
- package/test/unit/spec/member/util.js +32 -0
- package/test/unit/spec/members/index.js +130 -17
- package/test/unit/spec/members/utils.js +26 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +80 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +210 -3
- package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +505 -135
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +74 -17
- package/test/unit/spec/roap/index.ts +181 -61
- package/test/unit/spec/roap/request.ts +27 -3
- package/test/unit/spec/roap/turnDiscovery.ts +362 -101
- package/test/unit/spec/rtcMetrics/index.ts +57 -3
- package/test/unit/spec/stats-analyzer/index.js +1225 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +4 -4
- package/test/utils/webex-test-users.js +12 -4
|
@@ -82,20 +82,23 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
82
82
|
* handles TURN_DISCOVERY_RESPONSE roap message
|
|
83
83
|
*
|
|
84
84
|
* @param {Object} roapMessage
|
|
85
|
+
* @param {string} from string to indicate how we got the response (used just for logging)
|
|
85
86
|
* @returns {void}
|
|
86
87
|
* @public
|
|
87
88
|
* @memberof Roap
|
|
88
89
|
*/
|
|
89
90
|
}, {
|
|
90
91
|
key: "handleTurnDiscoveryResponse",
|
|
91
|
-
value: function handleTurnDiscoveryResponse(roapMessage) {
|
|
92
|
+
value: function handleTurnDiscoveryResponse(roapMessage, from) {
|
|
92
93
|
var _this = this;
|
|
93
|
-
// @ts-ignore - Fix missing type
|
|
94
94
|
var headers = roapMessage.headers;
|
|
95
95
|
if (!this.defer) {
|
|
96
|
-
_loggerProxy.default.logger.warn(
|
|
96
|
+
_loggerProxy.default.logger.warn("Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response ".concat(from));
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
|
+
if (roapMessage.messageType !== _constants2.ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {
|
|
100
|
+
this.defer.reject(new Error("TURN_DISCOVERY_RESPONSE ".concat(from, " has unexpected messageType: ").concat((0, _stringify.default)(roapMessage))));
|
|
101
|
+
}
|
|
99
102
|
var expectedHeaders = [{
|
|
100
103
|
headerName: 'x-cisco-turn-url',
|
|
101
104
|
field: 'url'
|
|
@@ -119,14 +122,43 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
119
122
|
clearTimeout(this.responseTimer);
|
|
120
123
|
this.responseTimer = undefined;
|
|
121
124
|
if (foundHeaders !== expectedHeaders.length) {
|
|
122
|
-
_loggerProxy.default.logger.warn("Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ".concat((0, _stringify.default)(headers)));
|
|
123
|
-
this.defer.reject(new Error("TURN_DISCOVERY_RESPONSE missing some headers: ".concat((0, _stringify.default)(headers))));
|
|
125
|
+
_loggerProxy.default.logger.warn("Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received ".concat(from, ": ").concat((0, _stringify.default)(headers)));
|
|
126
|
+
this.defer.reject(new Error("TURN_DISCOVERY_RESPONSE ".concat(from, " missing some headers: ").concat((0, _stringify.default)(headers))));
|
|
124
127
|
} else {
|
|
125
|
-
_loggerProxy.default.logger.info("Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=".concat(this.turnInfo.url));
|
|
126
|
-
this.defer.resolve(
|
|
128
|
+
_loggerProxy.default.logger.info("Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response ".concat(from, ", url=").concat(this.turnInfo.url));
|
|
129
|
+
this.defer.resolve({
|
|
130
|
+
isOkRequired: !(headers !== null && headers !== void 0 && headers.includes('noOkInTransaction'))
|
|
131
|
+
});
|
|
127
132
|
}
|
|
128
133
|
}
|
|
129
134
|
|
|
135
|
+
/**
|
|
136
|
+
* handles TURN_DISCOVERY_RESPONSE roap message that came in http response
|
|
137
|
+
*
|
|
138
|
+
* @param {Object} roapMessage
|
|
139
|
+
* @returns {Promise}
|
|
140
|
+
* @memberof Roap
|
|
141
|
+
*/
|
|
142
|
+
}, {
|
|
143
|
+
key: "handleTurnDiscoveryResponseInHttpResponse",
|
|
144
|
+
value: function () {
|
|
145
|
+
var _handleTurnDiscoveryResponseInHttpResponse = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(roapMessage) {
|
|
146
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
147
|
+
while (1) switch (_context.prev = _context.next) {
|
|
148
|
+
case 0:
|
|
149
|
+
this.handleTurnDiscoveryResponse(roapMessage, 'in http response');
|
|
150
|
+
return _context.abrupt("return", this.defer.promise);
|
|
151
|
+
case 2:
|
|
152
|
+
case "end":
|
|
153
|
+
return _context.stop();
|
|
154
|
+
}
|
|
155
|
+
}, _callee, this);
|
|
156
|
+
}));
|
|
157
|
+
function handleTurnDiscoveryResponseInHttpResponse(_x) {
|
|
158
|
+
return _handleTurnDiscoveryResponseInHttpResponse.apply(this, arguments);
|
|
159
|
+
}
|
|
160
|
+
return handleTurnDiscoveryResponseInHttpResponse;
|
|
161
|
+
}()
|
|
130
162
|
/**
|
|
131
163
|
* sends the TURN_DISCOVERY_REQUEST roap request
|
|
132
164
|
*
|
|
@@ -147,7 +179,8 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
147
179
|
var roapMessage = {
|
|
148
180
|
messageType: _constants2.ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,
|
|
149
181
|
version: _constants2.ROAP.ROAP_VERSION,
|
|
150
|
-
seq: TURN_DISCOVERY_SEQ
|
|
182
|
+
seq: TURN_DISCOVERY_SEQ,
|
|
183
|
+
headers: ['includeAnswerInHttpResponse', 'noOkInTransaction']
|
|
151
184
|
};
|
|
152
185
|
_loggerProxy.default.logger.info('Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST');
|
|
153
186
|
return this.roapRequest.sendRoap({
|
|
@@ -160,11 +193,40 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
160
193
|
locusMediaRequest: meeting.locusMediaRequest,
|
|
161
194
|
// @ts-ignore - because of meeting.webex
|
|
162
195
|
ipVersion: _util.default.getIpVersion(meeting.webex)
|
|
163
|
-
}).then(function (
|
|
164
|
-
var mediaConnections =
|
|
196
|
+
}).then(function (response) {
|
|
197
|
+
var mediaConnections = response.mediaConnections;
|
|
198
|
+
var turnDiscoveryResponse;
|
|
165
199
|
if (mediaConnections) {
|
|
200
|
+
var _mediaConnections$;
|
|
166
201
|
meeting.updateMediaConnections(mediaConnections);
|
|
202
|
+
if ((_mediaConnections$ = mediaConnections[0]) !== null && _mediaConnections$ !== void 0 && _mediaConnections$.remoteSdp) {
|
|
203
|
+
var remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
|
|
204
|
+
if (remoteSdp.roapMessage) {
|
|
205
|
+
// yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...
|
|
206
|
+
var _remoteSdp$roapMessag = remoteSdp.roapMessage,
|
|
207
|
+
seq = _remoteSdp$roapMessag.seq,
|
|
208
|
+
messageType = _remoteSdp$roapMessag.messageType,
|
|
209
|
+
errorType = _remoteSdp$roapMessag.errorType,
|
|
210
|
+
errorCause = _remoteSdp$roapMessag.errorCause,
|
|
211
|
+
headers = _remoteSdp$roapMessag.headers;
|
|
212
|
+
turnDiscoveryResponse = {
|
|
213
|
+
seq: seq,
|
|
214
|
+
messageType: messageType,
|
|
215
|
+
errorType: errorType,
|
|
216
|
+
errorCause: errorCause,
|
|
217
|
+
headers: headers
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
167
221
|
}
|
|
222
|
+
if (!turnDiscoveryResponse) {
|
|
223
|
+
_metrics.default.sendBehavioralMetric(_constants.default.ROAP_HTTP_RESPONSE_MISSING, {
|
|
224
|
+
correlationId: meeting.correlationId,
|
|
225
|
+
messageType: 'TURN_DISCOVERY_RESPONSE',
|
|
226
|
+
isMultistream: meeting.isMultistream
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return turnDiscoveryResponse;
|
|
168
230
|
});
|
|
169
231
|
}
|
|
170
232
|
|
|
@@ -203,37 +265,30 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
203
265
|
}, {
|
|
204
266
|
key: "getSkipReason",
|
|
205
267
|
value: function () {
|
|
206
|
-
var _getSkipReason = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
207
|
-
var
|
|
208
|
-
return _regenerator.default.wrap(function
|
|
209
|
-
while (1) switch (
|
|
268
|
+
var _getSkipReason = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(meeting) {
|
|
269
|
+
var isAnyPublicClusterReachable;
|
|
270
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
271
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
210
272
|
case 0:
|
|
211
|
-
|
|
212
|
-
return meeting.webex.meetings.reachability.
|
|
273
|
+
_context2.next = 2;
|
|
274
|
+
return meeting.webex.meetings.reachability.isAnyPublicClusterReachable();
|
|
213
275
|
case 2:
|
|
214
|
-
|
|
215
|
-
if (!
|
|
216
|
-
|
|
276
|
+
isAnyPublicClusterReachable = _context2.sent;
|
|
277
|
+
if (!isAnyPublicClusterReachable) {
|
|
278
|
+
_context2.next = 6;
|
|
217
279
|
break;
|
|
218
280
|
}
|
|
219
281
|
_loggerProxy.default.logger.info('Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery');
|
|
220
|
-
return
|
|
282
|
+
return _context2.abrupt("return", 'reachability');
|
|
221
283
|
case 6:
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
_loggerProxy.default.logger.info('Roap:turnDiscovery#getSkipReason --> TURN discovery disabled in config, skipping it');
|
|
227
|
-
return _context.abrupt("return", 'config');
|
|
228
|
-
case 9:
|
|
229
|
-
return _context.abrupt("return", '');
|
|
230
|
-
case 10:
|
|
284
|
+
return _context2.abrupt("return", '');
|
|
285
|
+
case 7:
|
|
231
286
|
case "end":
|
|
232
|
-
return
|
|
287
|
+
return _context2.stop();
|
|
233
288
|
}
|
|
234
|
-
},
|
|
289
|
+
}, _callee2);
|
|
235
290
|
}));
|
|
236
|
-
function getSkipReason(
|
|
291
|
+
function getSkipReason(_x2) {
|
|
237
292
|
return _getSkipReason.apply(this, arguments);
|
|
238
293
|
}
|
|
239
294
|
return getSkipReason;
|
|
@@ -247,23 +302,23 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
247
302
|
}, {
|
|
248
303
|
key: "isSkipped",
|
|
249
304
|
value: function () {
|
|
250
|
-
var _isSkipped = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
305
|
+
var _isSkipped = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(meeting) {
|
|
251
306
|
var skipReason;
|
|
252
|
-
return _regenerator.default.wrap(function
|
|
253
|
-
while (1) switch (
|
|
307
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
308
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
254
309
|
case 0:
|
|
255
|
-
|
|
310
|
+
_context3.next = 2;
|
|
256
311
|
return this.getSkipReason(meeting);
|
|
257
312
|
case 2:
|
|
258
|
-
skipReason =
|
|
259
|
-
return
|
|
313
|
+
skipReason = _context3.sent;
|
|
314
|
+
return _context3.abrupt("return", !!skipReason);
|
|
260
315
|
case 4:
|
|
261
316
|
case "end":
|
|
262
|
-
return
|
|
317
|
+
return _context3.stop();
|
|
263
318
|
}
|
|
264
|
-
},
|
|
319
|
+
}, _callee3, this);
|
|
265
320
|
}));
|
|
266
|
-
function isSkipped(
|
|
321
|
+
function isSkipped(_x3) {
|
|
267
322
|
return _isSkipped.apply(this, arguments);
|
|
268
323
|
}
|
|
269
324
|
return isSkipped;
|
|
@@ -281,64 +336,101 @@ var TurnDiscovery = /*#__PURE__*/function () {
|
|
|
281
336
|
* so it works fine no matter if TURN discovery is done or not.
|
|
282
337
|
*
|
|
283
338
|
* @param {Meeting} meeting
|
|
284
|
-
* @param {Boolean} isReconnecting should be set to true if this is a new
|
|
339
|
+
* @param {Boolean} [isReconnecting] should be set to true if this is a new
|
|
285
340
|
* media connection just after a reconnection
|
|
341
|
+
* @param {Boolean} [isForced]
|
|
286
342
|
* @returns {Promise}
|
|
287
343
|
*/
|
|
288
344
|
}, {
|
|
289
345
|
key: "doTurnDiscovery",
|
|
290
346
|
value: function () {
|
|
291
|
-
var _doTurnDiscovery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function
|
|
292
|
-
var
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
while (1) switch (_context3.prev = _context3.next) {
|
|
347
|
+
var _doTurnDiscovery = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(meeting, isReconnecting, isForced) {
|
|
348
|
+
var turnDiscoverySkippedReason, httpResponse, _ref, isOkRequired;
|
|
349
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
350
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
296
351
|
case 0:
|
|
297
|
-
|
|
352
|
+
if (isForced) {
|
|
353
|
+
_context4.next = 4;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
_context4.next = 3;
|
|
298
357
|
return this.getSkipReason(meeting);
|
|
299
|
-
case
|
|
300
|
-
turnDiscoverySkippedReason =
|
|
358
|
+
case 3:
|
|
359
|
+
turnDiscoverySkippedReason = _context4.sent;
|
|
360
|
+
case 4:
|
|
301
361
|
if (!turnDiscoverySkippedReason) {
|
|
302
|
-
|
|
362
|
+
_context4.next = 6;
|
|
303
363
|
break;
|
|
304
364
|
}
|
|
305
|
-
return
|
|
365
|
+
return _context4.abrupt("return", {
|
|
306
366
|
turnServerInfo: undefined,
|
|
307
367
|
turnDiscoverySkippedReason: turnDiscoverySkippedReason
|
|
308
368
|
});
|
|
309
|
-
case 5:
|
|
310
|
-
return _context3.abrupt("return", this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting).then(function () {
|
|
311
|
-
return _this2.waitForTurnDiscoveryResponse();
|
|
312
|
-
}).then(function () {
|
|
313
|
-
return _this2.sendRoapOK(meeting);
|
|
314
|
-
}).then(function () {
|
|
315
|
-
_this2.defer = undefined;
|
|
316
|
-
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
|
|
317
|
-
return {
|
|
318
|
-
turnServerInfo: _this2.turnInfo,
|
|
319
|
-
turnDiscoverySkippedReason: undefined
|
|
320
|
-
};
|
|
321
|
-
}).catch(function (e) {
|
|
322
|
-
// we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
|
|
323
|
-
_loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(e));
|
|
324
|
-
_metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
|
|
325
|
-
correlation_id: meeting.correlationId,
|
|
326
|
-
locus_id: meeting.locusUrl.split('/').pop(),
|
|
327
|
-
reason: e.message,
|
|
328
|
-
stack: e.stack
|
|
329
|
-
});
|
|
330
|
-
return {
|
|
331
|
-
turnServerInfo: undefined,
|
|
332
|
-
turnDiscoverySkippedReason: undefined
|
|
333
|
-
};
|
|
334
|
-
}));
|
|
335
369
|
case 6:
|
|
370
|
+
_context4.prev = 6;
|
|
371
|
+
_context4.next = 9;
|
|
372
|
+
return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting);
|
|
373
|
+
case 9:
|
|
374
|
+
httpResponse = _context4.sent;
|
|
375
|
+
if (!httpResponse) {
|
|
376
|
+
_context4.next = 16;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
_context4.next = 13;
|
|
380
|
+
return this.handleTurnDiscoveryResponseInHttpResponse(httpResponse);
|
|
381
|
+
case 13:
|
|
382
|
+
_context4.t0 = _context4.sent;
|
|
383
|
+
_context4.next = 19;
|
|
384
|
+
break;
|
|
385
|
+
case 16:
|
|
386
|
+
_context4.next = 18;
|
|
387
|
+
return this.waitForTurnDiscoveryResponse();
|
|
388
|
+
case 18:
|
|
389
|
+
_context4.t0 = _context4.sent;
|
|
390
|
+
case 19:
|
|
391
|
+
_ref = _context4.t0;
|
|
392
|
+
isOkRequired = _ref.isOkRequired;
|
|
393
|
+
if (!isOkRequired) {
|
|
394
|
+
_context4.next = 26;
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
_context4.next = 24;
|
|
398
|
+
return this.sendRoapOK(meeting);
|
|
399
|
+
case 24:
|
|
400
|
+
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery response requires OK');
|
|
401
|
+
_metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_REQUIRES_OK, {
|
|
402
|
+
correlation_id: meeting.correlationId,
|
|
403
|
+
locus_id: meeting.locusUrl.split('/').pop()
|
|
404
|
+
});
|
|
405
|
+
case 26:
|
|
406
|
+
this.defer = undefined;
|
|
407
|
+
_loggerProxy.default.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');
|
|
408
|
+
return _context4.abrupt("return", {
|
|
409
|
+
turnServerInfo: this.turnInfo,
|
|
410
|
+
turnDiscoverySkippedReason: undefined
|
|
411
|
+
});
|
|
412
|
+
case 31:
|
|
413
|
+
_context4.prev = 31;
|
|
414
|
+
_context4.t1 = _context4["catch"](6);
|
|
415
|
+
// we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN
|
|
416
|
+
_loggerProxy.default.logger.info("Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ".concat(_context4.t1));
|
|
417
|
+
_metrics.default.sendBehavioralMetric(_constants.default.TURN_DISCOVERY_FAILURE, {
|
|
418
|
+
correlation_id: meeting.correlationId,
|
|
419
|
+
locus_id: meeting.locusUrl.split('/').pop(),
|
|
420
|
+
reason: _context4.t1.message,
|
|
421
|
+
stack: _context4.t1.stack
|
|
422
|
+
});
|
|
423
|
+
return _context4.abrupt("return", {
|
|
424
|
+
turnServerInfo: undefined,
|
|
425
|
+
turnDiscoverySkippedReason: undefined
|
|
426
|
+
});
|
|
427
|
+
case 36:
|
|
336
428
|
case "end":
|
|
337
|
-
return
|
|
429
|
+
return _context4.stop();
|
|
338
430
|
}
|
|
339
|
-
},
|
|
431
|
+
}, _callee4, this, [[6, 31]]);
|
|
340
432
|
}));
|
|
341
|
-
function doTurnDiscovery(
|
|
433
|
+
function doTurnDiscovery(_x4, _x5, _x6) {
|
|
342
434
|
return _doTurnDiscovery.apply(this, arguments);
|
|
343
435
|
}
|
|
344
436
|
return doTurnDiscovery;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscovery","roapRequest","turnInfo","url","username","password","defer","LoggerProxy","logger","warn","reject","Error","responseTimer","setTimeout","info","promise","roapMessage","headers","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","meeting","isReconnecting","Defer","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ipVersion","MeetingUtil","getIpVersion","webex","then","mediaConnections","updateMediaConnections","OK","meetings","reachability","isAnyClusterReachable","config","experimental","enableTurnDiscovery","getSkipReason","skipReason","turnDiscoverySkippedReason","turnServerInfo","sendRoapTurnDiscoveryRequest","waitForTurnDiscoveryResponse","sendRoapOK","catch","e","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","TURN_DISCOVERY_FAILURE","correlation_id","correlationId","locus_id","locusUrl","split","pop","reason","message","stack"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: {\n url: string;\n username: string;\n password: string;\n };\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse() {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message\n *\n * @param {Object} roapMessage\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: object) {\n // @ts-ignore - Fix missing type\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response'\n );\n\n return;\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(`TURN_DISCOVERY_RESPONSE missing some headers: ${JSON.stringify(headers)}`)\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response, url=${this.turnInfo.url}`\n );\n this.defer.resolve();\n }\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve();\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n // @ts-ignore - because of meeting.webex\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then(({mediaConnections}) => {\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n }\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Gets the reason why reachability is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped\n */\n private async getSkipReason(meeting: Meeting): Promise<string> {\n // @ts-ignore - fix type\n const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();\n\n if (isAnyClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'\n );\n\n return 'reachability';\n }\n\n // @ts-ignore - fix type\n if (!meeting.config.experimental.enableTurnDiscovery) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#getSkipReason --> TURN discovery disabled in config, skipping it'\n );\n\n return 'config';\n }\n\n return '';\n }\n\n /**\n * Checks if TURN discovery is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done\n */\n async isSkipped(meeting) {\n const skipReason = await this.getSkipReason(meeting);\n\n return !!skipReason;\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting should be set to true if this is a new\n * media connection just after a reconnection\n * @returns {Promise}\n */\n async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {\n const turnDiscoverySkippedReason = await this.getSkipReason(meeting);\n\n if (turnDiscoverySkippedReason) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason,\n };\n }\n\n return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)\n .then(() => this.waitForTurnDiscoveryResponse())\n .then(() => this.sendRoapOK(meeting))\n .then(() => {\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n })\n .catch((e) => {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack,\n });\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: undefined};\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AACA;AAEA;AACA;AACA;AACA;AAIA;AAVA;;AAYA,IAAMA,sBAAsB,GAAG,EAAE,CAAC,CAAC;;AAEnC;AACA;AACA;AACA;AACA,IAAMC,kBAAkB,GAAG,CAAC;;AAE5B;AACA;AACA;AACA;AAHA,IAIqBC,aAAa;EAGT;;EAUvB;AACF;AACA;AACA;AACA;EACE,uBAAYC,WAAwB,EAAE;IAAA;IAAA;IAAA;IAAA;IAAA;IACpC,IAAI,CAACA,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACC,QAAQ,GAAG;MACdC,GAAG,EAAE,EAAE;MACPC,QAAQ,EAAE,EAAE;MACZC,QAAQ,EAAE;IACZ,CAAC;EACH;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,wCAAuC;MACrC,IAAI,CAAC,IAAI,CAACC,KAAK,EAAE;QACfC,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,uFAAuF,CACxF;QAED,OAAO,iBAAQC,MAAM,CACnB,IAAIC,KAAK,CAAC,6EAA6E,CAAC,CACzF;MACH;MAEA,IAAOL,KAAK,GAAI,IAAI,CAAbA,KAAK;MAEZ,IAAI,CAACM,aAAa,GAAGC,UAAU,CAAC,YAAM;QACpCN,oBAAW,CAACC,MAAM,CAACC,IAAI,mGACsEX,sBAAsB,cAClH;QAEDQ,KAAK,CAACI,MAAM,CAAC,IAAIC,KAAK,CAAC,+CAA+C,CAAC,CAAC;MAC1E,CAAC,EAAEb,sBAAsB,GAAG,IAAI,CAAC;MAEjCS,oBAAW,CAACC,MAAM,CAACM,IAAI,CACrB,4FAA4F,CAC7F;MAED,OAAOR,KAAK,CAACS,OAAO;IACtB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EAPE;IAAA;IAAA,OAQA,qCAAmCC,WAAmB,EAAE;MAAA;MACtD;MACA,IAAOC,OAAO,GAAID,WAAW,CAAtBC,OAAO;MAEd,IAAI,CAAC,IAAI,CAACX,KAAK,EAAE;QACfC,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,uFAAuF,CACxF;QAED;MACF;MAEA,IAAMS,eAAe,GAAG,CACtB;QAACC,UAAU,EAAE,kBAAkB;QAAEC,KAAK,EAAE;MAAK,CAAC,EAC9C;QAACD,UAAU,EAAE,uBAAuB;QAAEC,KAAK,EAAE;MAAU,CAAC,EACxD;QAACD,UAAU,EAAE,uBAAuB;QAAEC,KAAK,EAAE;MAAU,CAAC,CACzD;MAED,IAAIC,YAAY,GAAG,CAAC;MAEpBJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEK,OAAO,CAAC,UAACC,cAAc,EAAK;QACnC;QACAL,eAAe,CAACI,OAAO,CAAC,UAACE,cAAc,EAAK;UAC1C,IAAID,cAAc,CAACE,UAAU,WAAID,cAAc,CAACL,UAAU,OAAI,EAAE;YAC9D,KAAI,CAACjB,QAAQ,CAACsB,cAAc,CAACJ,KAAK,CAAC,GAAGG,cAAc,CAACG,SAAS,CAC5DF,cAAc,CAACL,UAAU,CAACQ,MAAM,GAAG,CAAC,CACrC;YACDN,YAAY,IAAI,CAAC;UACnB;QACF,CAAC,CAAC;MACJ,CAAC,CAAC;MAEFO,YAAY,CAAC,IAAI,CAAChB,aAAa,CAAC;MAChC,IAAI,CAACA,aAAa,GAAGiB,SAAS;MAE9B,IAAIR,YAAY,KAAKH,eAAe,CAACS,MAAM,EAAE;QAC3CpB,oBAAW,CAACC,MAAM,CAACC,IAAI,8FACiE,wBACpFQ,OAAO,CACR,EACF;QACD,IAAI,CAACX,KAAK,CAACI,MAAM,CACf,IAAIC,KAAK,yDAAkD,wBAAeM,OAAO,CAAC,EAAG,CACtF;MACH,CAAC,MAAM;QACLV,oBAAW,CAACC,MAAM,CAACM,IAAI,6FACgE,IAAI,CAACZ,QAAQ,CAACC,GAAG,EACvG;QACD,IAAI,CAACG,KAAK,CAACwB,OAAO,EAAE;MACtB;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA,OASA,sCAA6BC,OAAgB,EAAEC,cAAuB,EAAE;MACtE,IAAI,IAAI,CAAC1B,KAAK,EAAE;QACdC,oBAAW,CAACC,MAAM,CAACC,IAAI,CACrB,yEAAyE,CAC1E;QAED,OAAO,iBAAQqB,OAAO,EAAE;MAC1B;MAEA,IAAI,CAACxB,KAAK,GAAG,IAAI2B,aAAK,EAAE;MAExB,IAAMjB,WAAW,GAAG;QAClBkB,WAAW,EAAEC,gBAAI,CAACC,UAAU,CAACC,sBAAsB;QACnDC,OAAO,EAAEH,gBAAI,CAACI,YAAY;QAC1BC,GAAG,EAAEzC;MACP,CAAC;MAEDQ,oBAAW,CAACC,MAAM,CAACM,IAAI,CACrB,oFAAoF,CACrF;MAED,OAAO,IAAI,CAACb,WAAW,CACpBwC,QAAQ,CAAC;QACRzB,WAAW,EAAXA,WAAW;QACX;QACA0B,YAAY,EAAEX,OAAO,CAACY,OAAO;QAC7B;QACAC,OAAO,EAAEZ,cAAc,GAAG,EAAE,GAAGD,OAAO,CAACa,OAAO;QAC9CC,SAAS,EAAEd,OAAO,CAACe,EAAE;QACrBC,iBAAiB,EAAEhB,OAAO,CAACgB,iBAAiB;QAC5C;QACAC,SAAS,EAAEC,aAAW,CAACC,YAAY,CAACnB,OAAO,CAACoB,KAAK;MACnD,CAAC,CAAC,CACDC,IAAI,CAAC,gBAAwB;QAAA,IAAtBC,gBAAgB,QAAhBA,gBAAgB;QACtB,IAAIA,gBAAgB,EAAE;UACpBtB,OAAO,CAACuB,sBAAsB,CAACD,gBAAgB,CAAC;QAClD;MACF,CAAC,CAAC;IACN;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,oBAAWtB,OAAgB,EAAE;MAC3BxB,oBAAW,CAACC,MAAM,CAACM,IAAI,CAAC,8CAA8C,CAAC;MAEvE,OAAO,IAAI,CAACb,WAAW,CAACwC,QAAQ,CAAC;QAC/BzB,WAAW,EAAE;UACXkB,WAAW,EAAEC,gBAAI,CAACC,UAAU,CAACmB,EAAE;UAC/BjB,OAAO,EAAEH,gBAAI,CAACI,YAAY;UAC1BC,GAAG,EAAEzC;QACP,CAAC;QACD;QACA2C,YAAY,EAAEX,OAAO,CAACY,OAAO;QAC7B;QACAC,OAAO,EAAEb,OAAO,CAACa,OAAO;QACxBC,SAAS,EAAEd,OAAO,CAACe,EAAE;QACrBC,iBAAiB,EAAEhB,OAAO,CAACgB;MAC7B,CAAC,CAAC;IACJ;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA;MAAA,6FAMA,iBAA4BhB,OAAgB;QAAA;QAAA;UAAA;YAAA;cAAA;cAAA,OAENA,OAAO,CAACoB,KAAK,CAACK,QAAQ,CAACC,YAAY,CAACC,qBAAqB,EAAE;YAAA;cAAzFA,qBAAqB;cAAA,KAEvBA,qBAAqB;gBAAA;gBAAA;cAAA;cACvBnD,oBAAW,CAACC,MAAM,CAACM,IAAI,CACrB,2FAA2F,CAC5F;cAAC,iCAEK,cAAc;YAAA;cAAA,IAIlBiB,OAAO,CAAC4B,MAAM,CAACC,YAAY,CAACC,mBAAmB;gBAAA;gBAAA;cAAA;cAClDtD,oBAAW,CAACC,MAAM,CAACM,IAAI,CACrB,qFAAqF,CACtF;cAAC,iCAEK,QAAQ;YAAA;cAAA,iCAGV,EAAE;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACV;MAAA;QAAA;MAAA;MAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA;MAAA,yFAMA,kBAAgBiB,OAAO;QAAA;QAAA;UAAA;YAAA;cAAA;cAAA,OACI,IAAI,CAAC+B,aAAa,CAAC/B,OAAO,CAAC;YAAA;cAA9CgC,UAAU;cAAA,kCAET,CAAC,CAACA,UAAU;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACpB;MAAA;QAAA;MAAA;MAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EAhBE;IAAA;IAAA;MAAA,+FAiBA,kBAAsBhC,OAAgB,EAAEC,cAAwB;QAAA;QAAA;QAAA;UAAA;YAAA;cAAA;cAAA,OACrB,IAAI,CAAC8B,aAAa,CAAC/B,OAAO,CAAC;YAAA;cAA9DiC,0BAA0B;cAAA,KAE5BA,0BAA0B;gBAAA;gBAAA;cAAA;cAAA,kCACrB;gBACLC,cAAc,EAAEpC,SAAS;gBACzBmC,0BAA0B,EAA1BA;cACF,CAAC;YAAA;cAAA,kCAGI,IAAI,CAACE,4BAA4B,CAACnC,OAAO,EAAEC,cAAc,CAAC,CAC9DoB,IAAI,CAAC;gBAAA,OAAM,MAAI,CAACe,4BAA4B,EAAE;cAAA,EAAC,CAC/Cf,IAAI,CAAC;gBAAA,OAAM,MAAI,CAACgB,UAAU,CAACrC,OAAO,CAAC;cAAA,EAAC,CACpCqB,IAAI,CAAC,YAAM;gBACV,MAAI,CAAC9C,KAAK,GAAGuB,SAAS;gBAEtBtB,oBAAW,CAACC,MAAM,CAACM,IAAI,CAAC,iEAAiE,CAAC;gBAE1F,OAAO;kBAACmD,cAAc,EAAE,MAAI,CAAC/D,QAAQ;kBAAE8D,0BAA0B,EAAEnC;gBAAS,CAAC;cAC/E,CAAC,CAAC,CACDwC,KAAK,CAAC,UAACC,CAAC,EAAK;gBACZ;gBACA/D,oBAAW,CAACC,MAAM,CAACM,IAAI,kGACqEwD,CAAC,EAC5F;gBAEDC,gBAAO,CAACC,oBAAoB,CAACC,kBAAkB,CAACC,sBAAsB,EAAE;kBACtEC,cAAc,EAAE5C,OAAO,CAAC6C,aAAa;kBACrCC,QAAQ,EAAE9C,OAAO,CAAC+C,QAAQ,CAACC,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,EAAE;kBAC3CC,MAAM,EAAEX,CAAC,CAACY,OAAO;kBACjBC,KAAK,EAAEb,CAAC,CAACa;gBACX,CAAC,CAAC;gBAEF,OAAO;kBAAClB,cAAc,EAAEpC,SAAS;kBAAEmC,0BAA0B,EAAEnC;gBAAS,CAAC;cAC3E,CAAC,CAAC;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACL;MAAA;QAAA;MAAA;MAAA;IAAA;EAAA;EAAA;AAAA;AAAA"}
|
|
1
|
+
{"version":3,"names":["TURN_DISCOVERY_TIMEOUT","TURN_DISCOVERY_SEQ","TurnDiscovery","roapRequest","turnInfo","url","username","password","defer","LoggerProxy","logger","warn","reject","Error","responseTimer","setTimeout","info","promise","roapMessage","from","headers","messageType","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","expectedHeaders","headerName","field","foundHeaders","forEach","receivedHeader","expectedHeader","startsWith","substring","length","clearTimeout","undefined","resolve","isOkRequired","includes","handleTurnDiscoveryResponse","meeting","isReconnecting","Defer","TURN_DISCOVERY_REQUEST","version","ROAP_VERSION","seq","sendRoap","locusSelfUrl","selfUrl","mediaId","meetingId","id","locusMediaRequest","ipVersion","MeetingUtil","getIpVersion","webex","then","response","mediaConnections","turnDiscoveryResponse","updateMediaConnections","remoteSdp","JSON","parse","errorType","errorCause","Metrics","sendBehavioralMetric","BEHAVIORAL_METRICS","ROAP_HTTP_RESPONSE_MISSING","correlationId","isMultistream","OK","meetings","reachability","isAnyPublicClusterReachable","getSkipReason","skipReason","isForced","turnDiscoverySkippedReason","turnServerInfo","sendRoapTurnDiscoveryRequest","httpResponse","handleTurnDiscoveryResponseInHttpResponse","waitForTurnDiscoveryResponse","sendRoapOK","TURN_DISCOVERY_REQUIRES_OK","correlation_id","locus_id","locusUrl","split","pop","TURN_DISCOVERY_FAILURE","reason","message","stack"],"sources":["turnDiscovery.ts"],"sourcesContent":["// @ts-ignore - Types not available for @webex/common\nimport {Defer} from '@webex/common';\n\nimport Metrics from '../metrics';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ROAP} from '../constants';\n\nimport RoapRequest from './request';\nimport Meeting from '../meeting';\nimport MeetingUtil from '../meeting/util';\n\nconst TURN_DISCOVERY_TIMEOUT = 10; // in seconds\n\n// Roap spec says that seq should start from 1, but TURN discovery works fine with seq=0\n// and this is handy for us, because TURN discovery is always done before the first SDP exchange,\n// so we can do it with seq=0 or not do it at all and then we create the RoapMediaConnection\n// and do the SDP offer with seq=1\nconst TURN_DISCOVERY_SEQ = 0;\n\n/**\n * Handles the process of finding out TURN server information from Linus.\n * This is achieved by sending a TURN_DISCOVERY_REQUEST.\n */\nexport default class TurnDiscovery {\n private roapRequest: RoapRequest;\n\n private defer?: Defer; // used for waiting for the response\n\n private turnInfo: {\n url: string;\n username: string;\n password: string;\n };\n\n private responseTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Constructor\n *\n * @param {RoapRequest} roapRequest\n */\n constructor(roapRequest: RoapRequest) {\n this.roapRequest = roapRequest;\n this.turnInfo = {\n url: '',\n username: '',\n password: '',\n };\n }\n\n /**\n * waits for TURN_DISCOVERY_RESPONSE message to arrive\n *\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n private waitForTurnDiscoveryResponse(): Promise<{isOkRequired: boolean}> {\n if (!this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress'\n );\n\n return Promise.reject(\n new Error('waitForTurnDiscoveryResponse() called before sendRoapTurnDiscoveryRequest()')\n );\n }\n\n const {defer} = this;\n\n this.responseTimer = setTimeout(() => {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#waitForTurnDiscoveryResponse --> timeout! no response arrived within ${TURN_DISCOVERY_TIMEOUT} seconds`\n );\n\n defer.reject(new Error('Timed out waiting for TURN_DISCOVERY_RESPONSE'));\n }, TURN_DISCOVERY_TIMEOUT * 1000);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#waitForTurnDiscoveryResponse --> waiting for TURN_DISCOVERY_RESPONSE...'\n );\n\n return defer.promise;\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message\n *\n * @param {Object} roapMessage\n * @param {string} from string to indicate how we got the response (used just for logging)\n * @returns {void}\n * @public\n * @memberof Roap\n */\n public handleTurnDiscoveryResponse(roapMessage: any, from: string) {\n const {headers} = roapMessage;\n\n if (!this.defer) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> unexpected TURN discovery response ${from}`\n );\n\n return;\n }\n\n if (roapMessage.messageType !== ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} has unexpected messageType: ${JSON.stringify(\n roapMessage\n )}`\n )\n );\n }\n\n const expectedHeaders = [\n {headerName: 'x-cisco-turn-url', field: 'url'},\n {headerName: 'x-cisco-turn-username', field: 'username'},\n {headerName: 'x-cisco-turn-password', field: 'password'},\n ];\n\n let foundHeaders = 0;\n\n headers?.forEach((receivedHeader) => {\n // check if it matches any of our expected headers\n expectedHeaders.forEach((expectedHeader) => {\n if (receivedHeader.startsWith(`${expectedHeader.headerName}=`)) {\n this.turnInfo[expectedHeader.field] = receivedHeader.substring(\n expectedHeader.headerName.length + 1\n );\n foundHeaders += 1;\n }\n });\n });\n\n clearTimeout(this.responseTimer);\n this.responseTimer = undefined;\n\n if (foundHeaders !== expectedHeaders.length) {\n LoggerProxy.logger.warn(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> missing some headers, received ${from}: ${JSON.stringify(\n headers\n )}`\n );\n this.defer.reject(\n new Error(\n `TURN_DISCOVERY_RESPONSE ${from} missing some headers: ${JSON.stringify(headers)}`\n )\n );\n } else {\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#handleTurnDiscoveryResponse --> received a valid response ${from}, url=${this.turnInfo.url}`\n );\n\n this.defer.resolve({isOkRequired: !headers?.includes('noOkInTransaction')});\n }\n }\n\n /**\n * handles TURN_DISCOVERY_RESPONSE roap message that came in http response\n *\n * @param {Object} roapMessage\n * @returns {Promise}\n * @memberof Roap\n */\n private async handleTurnDiscoveryResponseInHttpResponse(\n roapMessage: object\n ): Promise<{isOkRequired: boolean}> {\n this.handleTurnDiscoveryResponse(roapMessage, 'in http response');\n\n return this.defer.promise;\n }\n\n /**\n * sends the TURN_DISCOVERY_REQUEST roap request\n *\n * @param {Meeting} meeting\n * @param {Boolean} isReconnecting\n * @returns {Promise}\n * @private\n * @memberof Roap\n */\n sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {\n if (this.defer) {\n LoggerProxy.logger.warn(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> already in progress'\n );\n\n return Promise.resolve();\n }\n\n this.defer = new Defer();\n\n const roapMessage = {\n messageType: ROAP.ROAP_TYPES.TURN_DISCOVERY_REQUEST,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],\n };\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#sendRoapTurnDiscoveryRequest --> sending TURN_DISCOVERY_REQUEST'\n );\n\n return this.roapRequest\n .sendRoap({\n roapMessage,\n // @ts-ignore - Fix missing type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - Fix missing type\n mediaId: isReconnecting ? '' : meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n // @ts-ignore - because of meeting.webex\n ipVersion: MeetingUtil.getIpVersion(meeting.webex),\n })\n .then((response) => {\n const {mediaConnections} = response;\n\n let turnDiscoveryResponse;\n\n if (mediaConnections) {\n meeting.updateMediaConnections(mediaConnections);\n\n if (mediaConnections[0]?.remoteSdp) {\n const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);\n\n if (remoteSdp.roapMessage) {\n // yes, it's misleading that remoteSdp actually contains a TURN discovery response, but that's how the backend works...\n const {seq, messageType, errorType, errorCause, headers} = remoteSdp.roapMessage;\n\n turnDiscoveryResponse = {\n seq,\n messageType,\n errorType,\n errorCause,\n headers,\n };\n }\n }\n }\n\n if (!turnDiscoveryResponse) {\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {\n correlationId: meeting.correlationId,\n messageType: 'TURN_DISCOVERY_RESPONSE',\n isMultistream: meeting.isMultistream,\n });\n }\n\n return turnDiscoveryResponse;\n });\n }\n\n /**\n * Sends the OK message that server expects to receive\n * after it sends us TURN_DISCOVERY_RESPONSE\n *\n * @param {Meeting} meeting\n * @returns {Promise}\n */\n sendRoapOK(meeting: Meeting) {\n LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');\n\n return this.roapRequest.sendRoap({\n roapMessage: {\n messageType: ROAP.ROAP_TYPES.OK,\n version: ROAP.ROAP_VERSION,\n seq: TURN_DISCOVERY_SEQ,\n },\n // @ts-ignore - fix type\n locusSelfUrl: meeting.selfUrl,\n // @ts-ignore - fix type\n mediaId: meeting.mediaId,\n meetingId: meeting.id,\n locusMediaRequest: meeting.locusMediaRequest,\n });\n }\n\n /**\n * Gets the reason why reachability is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Promise<string>} Promise with empty string if reachability is not skipped or a reason if it is skipped\n */\n private async getSkipReason(meeting: Meeting): Promise<string> {\n const isAnyPublicClusterReachable =\n // @ts-ignore - fix type\n await meeting.webex.meetings.reachability.isAnyPublicClusterReachable();\n\n if (isAnyPublicClusterReachable) {\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'\n );\n\n return 'reachability';\n }\n\n return '';\n }\n\n /**\n * Checks if TURN discovery is skipped.\n *\n * @param {Meeting} meeting\n * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done\n */\n async isSkipped(meeting) {\n const skipReason = await this.getSkipReason(meeting);\n\n return !!skipReason;\n }\n\n /**\n * Retrieves TURN server information from the backend by doing\n * a roap message exchange:\n * client server\n * | -----TURN_DISCOVERY_REQUEST-----> |\n * | <----TURN_DISCOVERY_RESPONSE----- |\n * | --------------OK----------------> |\n *\n * This TURN discovery roap exchange is always done with seq=0.\n * The RoapMediaConnection SDP exchange always starts with seq=1,\n * so it works fine no matter if TURN discovery is done or not.\n *\n * @param {Meeting} meeting\n * @param {Boolean} [isReconnecting] should be set to true if this is a new\n * media connection just after a reconnection\n * @param {Boolean} [isForced]\n * @returns {Promise}\n */\n async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean, isForced?: boolean) {\n let turnDiscoverySkippedReason: string;\n\n if (!isForced) {\n turnDiscoverySkippedReason = await this.getSkipReason(meeting);\n }\n\n if (turnDiscoverySkippedReason) {\n return {\n turnServerInfo: undefined,\n turnDiscoverySkippedReason,\n };\n }\n\n try {\n const httpResponse = await this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting);\n\n // if we haven't got the response over http, we need to wait for it to come over the websocket via Mercury\n const {isOkRequired} = httpResponse\n ? await this.handleTurnDiscoveryResponseInHttpResponse(httpResponse)\n : await this.waitForTurnDiscoveryResponse();\n\n if (isOkRequired) {\n await this.sendRoapOK(meeting);\n\n LoggerProxy.logger.info(\n 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery response requires OK'\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_REQUIRES_OK, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n });\n }\n\n this.defer = undefined;\n\n LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery completed');\n\n return {turnServerInfo: this.turnInfo, turnDiscoverySkippedReason: undefined};\n } catch (e) {\n // we catch any errors and resolve with no turn information so that the normal call join flow can continue without TURN\n LoggerProxy.logger.info(\n `Roap:turnDiscovery#doTurnDiscovery --> TURN discovery failed, continuing without TURN: ${e}`\n );\n\n Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.TURN_DISCOVERY_FAILURE, {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusUrl.split('/').pop(),\n reason: e.message,\n stack: e.stack,\n });\n\n return {turnServerInfo: undefined, turnDiscoverySkippedReason: undefined};\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/rtcMetrics/index.js
CHANGED
|
@@ -6,10 +6,26 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
exports.default = void 0;
|
|
9
|
+
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
|
|
9
10
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
10
11
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
11
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
13
|
+
var _internalPluginMetrics = require("@webex/internal-plugin-metrics");
|
|
14
|
+
var _uuid = _interopRequireDefault(require("uuid"));
|
|
12
15
|
var _constants = _interopRequireDefault(require("./constants"));
|
|
16
|
+
/* eslint-disable class-methods-use-this */
|
|
17
|
+
|
|
18
|
+
var parseJsonPayload = function parseJsonPayload(payload) {
|
|
19
|
+
try {
|
|
20
|
+
if (payload && payload[0]) {
|
|
21
|
+
return JSON.parse(payload[0]);
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
} catch (_) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
13
29
|
/**
|
|
14
30
|
* Rtc Metrics
|
|
15
31
|
*/
|
|
@@ -32,13 +48,15 @@ var RtcMetrics = /*#__PURE__*/function () {
|
|
|
32
48
|
(0, _defineProperty2.default)(this, "webex", void 0);
|
|
33
49
|
(0, _defineProperty2.default)(this, "meetingId", void 0);
|
|
34
50
|
(0, _defineProperty2.default)(this, "correlationId", void 0);
|
|
51
|
+
(0, _defineProperty2.default)(this, "connectionId", void 0);
|
|
35
52
|
// `window` is used to prevent typescript from returning a NodeJS.Timer.
|
|
36
|
-
this.intervalId = window.setInterval(this.
|
|
53
|
+
this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);
|
|
37
54
|
this.meetingId = meetingId;
|
|
38
55
|
this.webex = webex;
|
|
39
56
|
this.correlationId = correlationId;
|
|
57
|
+
this.setNewConnectionId();
|
|
40
58
|
// Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.
|
|
41
|
-
setTimeout(this.
|
|
59
|
+
setTimeout(this.sendMetricsInQueue.bind(this), 5 * 1000);
|
|
42
60
|
}
|
|
43
61
|
|
|
44
62
|
/**
|
|
@@ -47,8 +65,8 @@ var RtcMetrics = /*#__PURE__*/function () {
|
|
|
47
65
|
* @returns {void}
|
|
48
66
|
*/
|
|
49
67
|
(0, _createClass2.default)(RtcMetrics, [{
|
|
50
|
-
key: "
|
|
51
|
-
value: function
|
|
68
|
+
key: "sendMetricsInQueue",
|
|
69
|
+
value: function sendMetricsInQueue() {
|
|
52
70
|
if (this.metricsQueue.length) {
|
|
53
71
|
this.sendMetrics();
|
|
54
72
|
this.metricsQueue = [];
|
|
@@ -66,7 +84,20 @@ var RtcMetrics = /*#__PURE__*/function () {
|
|
|
66
84
|
key: "addMetrics",
|
|
67
85
|
value: function addMetrics(data) {
|
|
68
86
|
if (data.payload.length) {
|
|
87
|
+
if (data.name === 'stats-report') {
|
|
88
|
+
data.payload = data.payload.map(this.anonymizeIp);
|
|
89
|
+
}
|
|
69
90
|
this.metricsQueue.push(data);
|
|
91
|
+
try {
|
|
92
|
+
// If a connection fails, send the rest of the metrics in queue and get a new connection id.
|
|
93
|
+
var parsedPayload = parseJsonPayload(data.payload);
|
|
94
|
+
if (data.name === 'onconnectionstatechange' && parsedPayload && parsedPayload.value === 'failed') {
|
|
95
|
+
this.sendMetricsInQueue();
|
|
96
|
+
this.setNewConnectionId();
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error(e);
|
|
100
|
+
}
|
|
70
101
|
}
|
|
71
102
|
}
|
|
72
103
|
|
|
@@ -78,10 +109,40 @@ var RtcMetrics = /*#__PURE__*/function () {
|
|
|
78
109
|
}, {
|
|
79
110
|
key: "closeMetrics",
|
|
80
111
|
value: function closeMetrics() {
|
|
81
|
-
this.
|
|
112
|
+
this.sendMetricsInQueue();
|
|
82
113
|
clearInterval(this.intervalId);
|
|
83
114
|
}
|
|
84
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Anonymize IP addresses.
|
|
118
|
+
*
|
|
119
|
+
* @param {array} stats - An RTCStatsReport organized into an array of strings.
|
|
120
|
+
* @returns {string}
|
|
121
|
+
*/
|
|
122
|
+
}, {
|
|
123
|
+
key: "anonymizeIp",
|
|
124
|
+
value: function anonymizeIp(stats) {
|
|
125
|
+
var data = JSON.parse(stats);
|
|
126
|
+
// on local and remote candidates, anonymize the last 4 bits.
|
|
127
|
+
if (data.type === 'local-candidate' || data.type === 'remote-candidate') {
|
|
128
|
+
data.ip = _internalPluginMetrics.CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;
|
|
129
|
+
data.address = _internalPluginMetrics.CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;
|
|
130
|
+
data.relatedAddress = _internalPluginMetrics.CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;
|
|
131
|
+
}
|
|
132
|
+
return (0, _stringify.default)(data);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Set a new connection id.
|
|
137
|
+
*
|
|
138
|
+
* @returns {void}
|
|
139
|
+
*/
|
|
140
|
+
}, {
|
|
141
|
+
key: "setNewConnectionId",
|
|
142
|
+
value: function setNewConnectionId() {
|
|
143
|
+
this.connectionId = _uuid.default.v4();
|
|
144
|
+
}
|
|
145
|
+
|
|
85
146
|
/**
|
|
86
147
|
* Send metrics to the metrics service.
|
|
87
148
|
*
|
|
@@ -101,10 +162,11 @@ var RtcMetrics = /*#__PURE__*/function () {
|
|
|
101
162
|
body: {
|
|
102
163
|
metrics: [{
|
|
103
164
|
type: 'webrtc',
|
|
104
|
-
version: '1.0
|
|
165
|
+
version: '1.1.0',
|
|
105
166
|
userId: this.webex.internal.device.userId,
|
|
106
167
|
meetingId: this.meetingId,
|
|
107
168
|
correlationId: this.correlationId,
|
|
169
|
+
connectionId: this.connectionId,
|
|
108
170
|
data: this.metricsQueue
|
|
109
171
|
}]
|
|
110
172
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RtcMetrics","webex","meetingId","correlationId","intervalId","window","setInterval","
|
|
1
|
+
{"version":3,"names":["parseJsonPayload","payload","JSON","parse","_","RtcMetrics","webex","meetingId","correlationId","intervalId","window","setInterval","sendMetricsInQueue","bind","setNewConnectionId","setTimeout","metricsQueue","length","sendMetrics","data","name","map","anonymizeIp","push","parsedPayload","value","e","console","error","clearInterval","stats","type","ip","CallDiagnosticUtils","anonymizeIPAddress","undefined","address","relatedAddress","connectionId","uuid","v4","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics","version","userId","internal","device"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';\nimport uuid from 'uuid';\nimport RTC_METRICS from './constants';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId: string;\n\n correlationId: string;\n\n connectionId: string;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {string} meetingId - The meeting id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, meetingId, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.setNewConnectionId();\n // Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.\n setTimeout(this.sendMetricsInQueue.bind(this), 5 * 1000);\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.setNewConnectionId();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private setNewConnectionId() {\n this.connectionId = uuid.v4();\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [\n {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n meetingId: this.meetingId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n },\n ],\n },\n });\n }\n}\n"],"mappings":"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"}
|