@webex/webex-core 3.12.0-next.9 → 3.12.0-webex-services-ready.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/dist/credentials-config.js +12 -0
- package/dist/credentials-config.js.map +1 -1
- package/dist/lib/batcher.js +23 -7
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/credentials/credentials.js +48 -4
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/token.js +1 -1
- package/dist/lib/services/services.js +109 -29
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +108 -26
- package/dist/lib/services-v2/services-v2.js.map +1 -1
- package/dist/plugins/logger.js +1 -1
- package/dist/webex-core.js +2 -2
- package/dist/webex-core.js.map +1 -1
- package/package.json +13 -13
- package/src/credentials-config.js +13 -0
- package/src/lib/batcher.js +25 -10
- package/src/lib/credentials/credentials.js +50 -3
- package/src/lib/services/services.js +86 -12
- package/src/lib/services-v2/services-v2.ts +85 -10
- package/test/integration/spec/services/service-catalog.js +6 -7
- package/test/integration/spec/services/services.js +17 -6
- package/test/integration/spec/services-v2/services-v2.js +17 -6
- package/test/unit/spec/credentials/credentials.js +133 -2
- package/test/unit/spec/lib/batcher.js +56 -0
- package/test/unit/spec/services/services.js +342 -122
- package/test/unit/spec/services-v2/services-v2.ts +236 -63
- package/test/unit/spec/webex-core.js +2 -0
- package/test/unit/spec/webex-internal-core.js +2 -0
|
@@ -31,7 +31,7 @@ var _serviceState = _interopRequireDefault(require("./service-state"));
|
|
|
31
31
|
var _serviceFedRamp = _interopRequireDefault(require("./service-fed-ramp"));
|
|
32
32
|
var _constants = require("../constants");
|
|
33
33
|
function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
34
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
34
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable no-console */
|
|
35
35
|
var trailingSlashes = /(?:^\/)|(?:\/$)/;
|
|
36
36
|
|
|
37
37
|
// The default cluster when one is not provided (usually as 'US' from hydra)
|
|
@@ -43,6 +43,12 @@ var DEFAULT_CLUSTER_IDENTIFIER = process.env.WEBEX_CONVERSATION_DEFAULT_CLUSTER
|
|
|
43
43
|
var CATALOG_CACHE_KEY_V1 = 'services.v1.u2cHostMap';
|
|
44
44
|
var CATALOG_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
45
45
|
|
|
46
|
+
// Maximum time we will wait for the initial catalog collection before letting
|
|
47
|
+
// `services.ready` (and therefore `webex.ready`) fire anyway. A hung request
|
|
48
|
+
// must never leave the app on a permanent spinner - past this point downstream
|
|
49
|
+
// consumers must fall through to their normal error/login paths.
|
|
50
|
+
var SERVICES_INIT_TIMEOUT_MS = 15000;
|
|
51
|
+
|
|
46
52
|
/* eslint-disable no-underscore-dangle */
|
|
47
53
|
/**
|
|
48
54
|
* @class
|
|
@@ -73,6 +79,19 @@ var Services = _webexPlugin.default.extend({
|
|
|
73
79
|
validateDomains: ['boolean', false, true],
|
|
74
80
|
initFailed: ['boolean', false, false]
|
|
75
81
|
},
|
|
82
|
+
session: {
|
|
83
|
+
/**
|
|
84
|
+
* Becomes `true` once service catalog initialization has completed.
|
|
85
|
+
* Blocks `webex.ready` until services are initialized.
|
|
86
|
+
* @instance
|
|
87
|
+
* @memberof Services
|
|
88
|
+
* @type {boolean}
|
|
89
|
+
*/
|
|
90
|
+
ready: {
|
|
91
|
+
default: false,
|
|
92
|
+
type: 'boolean'
|
|
93
|
+
}
|
|
94
|
+
},
|
|
76
95
|
_catalogs: new _weakMap.default(),
|
|
77
96
|
_serviceUrls: null,
|
|
78
97
|
_hostCatalog: null,
|
|
@@ -1378,6 +1397,43 @@ var Services = _webexPlugin.default.extend({
|
|
|
1378
1397
|
return _promise.default.resolve();
|
|
1379
1398
|
});
|
|
1380
1399
|
},
|
|
1400
|
+
/**
|
|
1401
|
+
* Await any in-flight credentials refresh, then flip `services.ready` so
|
|
1402
|
+
* `webex.ready` can fire. Closes the parallel-refresh window: if a credential
|
|
1403
|
+
* refresh is in flight when initial catalog collection settles, we must not
|
|
1404
|
+
* signal ready until the refresh has resolved - otherwise downstream
|
|
1405
|
+
* consumers may observe `canAuthorize`/token state that is about to change
|
|
1406
|
+
* under them.
|
|
1407
|
+
*
|
|
1408
|
+
* @private
|
|
1409
|
+
* @returns {Promise<void>}
|
|
1410
|
+
*/
|
|
1411
|
+
_finalizeReady: function _finalizeReady() {
|
|
1412
|
+
var _this1 = this;
|
|
1413
|
+
return (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
1414
|
+
var credentials;
|
|
1415
|
+
return _regenerator.default.wrap(function (_context4) {
|
|
1416
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
1417
|
+
case 0:
|
|
1418
|
+
credentials = _this1.webex.credentials;
|
|
1419
|
+
if (!(credentials && credentials.isRefreshing)) {
|
|
1420
|
+
_context4.next = 1;
|
|
1421
|
+
break;
|
|
1422
|
+
}
|
|
1423
|
+
_context4.next = 1;
|
|
1424
|
+
return new _promise.default(function (resolve) {
|
|
1425
|
+
credentials.once('change:isRefreshing', resolve);
|
|
1426
|
+
});
|
|
1427
|
+
case 1:
|
|
1428
|
+
_this1.ready = true;
|
|
1429
|
+
_this1.trigger('services:initialized');
|
|
1430
|
+
case 2:
|
|
1431
|
+
case "end":
|
|
1432
|
+
return _context4.stop();
|
|
1433
|
+
}
|
|
1434
|
+
}, _callee4);
|
|
1435
|
+
}))();
|
|
1436
|
+
},
|
|
1381
1437
|
/**
|
|
1382
1438
|
* Initializer
|
|
1383
1439
|
*
|
|
@@ -1386,7 +1442,7 @@ var Services = _webexPlugin.default.extend({
|
|
|
1386
1442
|
* @returns {Services}
|
|
1387
1443
|
*/
|
|
1388
1444
|
initialize: function initialize() {
|
|
1389
|
-
var
|
|
1445
|
+
var _this10 = this;
|
|
1390
1446
|
var catalog = new _serviceCatalog.default();
|
|
1391
1447
|
var registry = new _serviceRegistry.default();
|
|
1392
1448
|
var state = new _serviceState.default();
|
|
@@ -1396,54 +1452,78 @@ var Services = _webexPlugin.default.extend({
|
|
|
1396
1452
|
|
|
1397
1453
|
// Listen for configuration changes once.
|
|
1398
1454
|
this.listenToOnce(this.webex, 'change:config', function () {
|
|
1399
|
-
|
|
1455
|
+
_this10.initConfig();
|
|
1400
1456
|
});
|
|
1401
1457
|
|
|
1402
|
-
//
|
|
1403
|
-
//
|
|
1404
|
-
//
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
while (1) switch (_context4.prev = _context4.next) {
|
|
1458
|
+
// Wait for storage to be loaded before attempting to update the service catalogs.
|
|
1459
|
+
// We listen for 'loaded' instead of 'ready' because services.ready is a dependency
|
|
1460
|
+
// of webex.ready - listening to 'ready' would cause a deadlock.
|
|
1461
|
+
this.listenToOnce(this.webex, 'loaded', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee5() {
|
|
1462
|
+
var cachedCatalog, supertoken, timeout, email;
|
|
1463
|
+
return _regenerator.default.wrap(function (_context5) {
|
|
1464
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1410
1465
|
case 0:
|
|
1411
|
-
|
|
1412
|
-
return
|
|
1466
|
+
_context5.next = 1;
|
|
1467
|
+
return _this10._loadCatalogFromCache();
|
|
1413
1468
|
case 1:
|
|
1414
|
-
cachedCatalog =
|
|
1469
|
+
cachedCatalog = _context5.sent;
|
|
1415
1470
|
if (!cachedCatalog) {
|
|
1416
|
-
|
|
1471
|
+
_context5.next = 3;
|
|
1417
1472
|
break;
|
|
1418
1473
|
}
|
|
1419
1474
|
catalog.isReady = true;
|
|
1420
|
-
|
|
1475
|
+
_context5.next = 2;
|
|
1476
|
+
return _this10._finalizeReady();
|
|
1421
1477
|
case 2:
|
|
1422
|
-
|
|
1478
|
+
return _context5.abrupt("return");
|
|
1479
|
+
case 3:
|
|
1480
|
+
supertoken = _this10.webex.credentials.supertoken; // Race init against a hard timeout so a hung request never leaves
|
|
1481
|
+
// `services.ready` false forever - that would stall `webex.ready` and
|
|
1482
|
+
// leave the app on a permanent spinner.
|
|
1483
|
+
timeout = new _promise.default(function (_, reject) {
|
|
1484
|
+
setTimeout(function () {
|
|
1485
|
+
return reject(new Error("services: init timed out after ".concat(SERVICES_INIT_TIMEOUT_MS, "ms")));
|
|
1486
|
+
}, SERVICES_INIT_TIMEOUT_MS);
|
|
1487
|
+
}); // Validate if the supertoken exists.
|
|
1423
1488
|
if (supertoken && supertoken.access_token) {
|
|
1424
|
-
|
|
1489
|
+
_promise.default.race([_this10.initServiceCatalogs(), timeout]).then(function () {
|
|
1425
1490
|
catalog.isReady = true;
|
|
1426
1491
|
}).catch(function (error) {
|
|
1427
|
-
|
|
1428
|
-
|
|
1492
|
+
_this10.initFailed = true;
|
|
1493
|
+
_this10.logger.error("services: failed to init initial services when credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1494
|
+
}).finally(function () {
|
|
1495
|
+
return _this10._finalizeReady();
|
|
1429
1496
|
});
|
|
1430
1497
|
} else {
|
|
1431
|
-
email =
|
|
1432
|
-
|
|
1498
|
+
email = _this10.webex.config.email;
|
|
1499
|
+
_promise.default.race([_this10.collectPreauthCatalog(email ? {
|
|
1433
1500
|
email: email
|
|
1434
|
-
} : undefined).catch(function (error) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1501
|
+
} : undefined), timeout]).catch(function (error) {
|
|
1502
|
+
_this10.initFailed = true;
|
|
1503
|
+
_this10.logger.error("services: failed to init initial services when no credentials available, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1504
|
+
}).finally(function () {
|
|
1505
|
+
return _this10._finalizeReady();
|
|
1506
|
+
});
|
|
1507
|
+
// Listen for when credentials become available to fetch the full catalog.
|
|
1508
|
+
// This handles fresh login where 'loaded' fires before OAuth completes.
|
|
1509
|
+
_this10.listenToOnce(_this10.webex, 'change:canAuthorize', function () {
|
|
1510
|
+
if (_this10.webex.canAuthorize && !catalog.status.postauth.ready) {
|
|
1511
|
+
_this10.initServiceCatalogs().then(function () {
|
|
1512
|
+
catalog.isReady = true;
|
|
1513
|
+
}).catch(function (error) {
|
|
1514
|
+
_this10.logger.error("services: failed to init service catalogs after auth, ".concat(error === null || error === void 0 ? void 0 : error.message));
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1437
1517
|
});
|
|
1438
1518
|
}
|
|
1439
|
-
case
|
|
1519
|
+
case 4:
|
|
1440
1520
|
case "end":
|
|
1441
|
-
return
|
|
1521
|
+
return _context5.stop();
|
|
1442
1522
|
}
|
|
1443
|
-
},
|
|
1523
|
+
}, _callee5);
|
|
1444
1524
|
})));
|
|
1445
1525
|
},
|
|
1446
|
-
version: "3.12.0-
|
|
1526
|
+
version: "3.12.0-webex-services-ready.1"
|
|
1447
1527
|
});
|
|
1448
1528
|
/* eslint-enable no-underscore-dangle */
|
|
1449
1529
|
var _default = exports.default = Services;
|