comprodls-sdk 2.86.2-valky → 2.89.0

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.
@@ -207,18 +207,6 @@ exports.REALM_HOSTS = {
207
207
  ANALYTICS: 'http://dls-asgard-thor-1453383019.us-west-2.elb.amazonaws.com/lb-analytics',
208
208
  INTEGRATION: 'http://dls-asgard-thor-1453383019.us-west-2.elb.amazonaws.com/lb-integrations',
209
209
  DRIVE: 'http://dls-asgard-thor-1453383019.us-west-2.elb.amazonaws.com/lb-drive'
210
- },
211
- VALKY: {
212
- PUB: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-pub',
213
- AUTH: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-auth',
214
- AUTHEXTN: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-authextn',
215
- PUSHX: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-pushx',
216
- XAPI: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-xapi',
217
- ATTEMPTS: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-attempts',
218
- PRODUCT: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-product',
219
- ANALYTICS: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-analytics',
220
- INTEGRATION: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-integrations',
221
- DRIVE: 'http://internal-dls-asgard-valky-1830585247.us-west-2.elb.amazonaws.com/lb-drive'
222
210
  }
223
211
  },
224
212
  CUP: {
@@ -935,9 +923,7 @@ function validateGenericAPICaller(apiName, method, url, params) {
935
923
  var ERROR_TYPES = {
936
924
  "API_ERROR": "API_ERROR",
937
925
  "SDK_ERROR": "SDK_ERROR",
938
- "CHANNEL_SUBSCRIPTION": "CHANNEL_SUBSCRIPTION",
939
- "UNEXPECTED_ERROR": "UNEXPECTED_ERROR",
940
- "POLLING_INITIATION": "POLLING_INITIATION"
926
+ "CHANNEL_SUBSCRIPTION": "CHANNEL_SUBSCRIPTION"
941
927
  };
942
928
 
943
929
  var ERROR_CATEGORY = {
@@ -13006,7 +12992,10 @@ function _connect(pubnubCW, options) {
13006
12992
  'subscribeKey': options.subscribeKey,
13007
12993
  'ssl': true,
13008
12994
  'suppressLeaveEvents': true
13009
- }
12995
+ },
12996
+ 'pollingEndpoint': options.pollingEndpoint,
12997
+ 'pollingIterations': options.pollingIterations || 10, // Default polling iterations is 10
12998
+ 'pollingInterval': options.pollingInterval, // Default polling interval is exponential backoff
13010
12999
  });
13011
13000
  }
13012
13001
 
@@ -13178,6 +13167,7 @@ function getPushedEvents(options) {
13178
13167
 
13179
13168
  },{"../../helpers":3,"./pubnubClientWrapper":26,"agentkeepalive":36,"q":42,"superagent":45}],26:[function(require,module,exports){
13180
13169
  var pubNub = require("pubnub");
13170
+ var request = require('superagent');
13181
13171
  var EventEmitter = require("events").EventEmitter;
13182
13172
  var helpers = require('../../helpers');
13183
13173
 
@@ -13200,6 +13190,13 @@ module.exports = function () {
13200
13190
  var _globalSubscription = [];
13201
13191
  var _globalSubscriptionStatus = {};
13202
13192
  var bStatusSubscribed = false;
13193
+ /** ID of the setTimeout - used for Polling events when PubNub fails */
13194
+ var _setTimeoutIDForPolling;
13195
+ /** Timestamp from when the events need to be fetched */
13196
+ var _startTimestampForPolling;
13197
+ /** Counter for polling */
13198
+ var _pollingCounter;
13199
+ var bPollingInitiated = false;
13203
13200
 
13204
13201
  /** ###### END OF MODULE GLOBALS */
13205
13202
 
@@ -13215,6 +13212,9 @@ module.exports = function () {
13215
13212
  //Returning the adaptor (Plain Javascript object)
13216
13213
  return {
13217
13214
  "on": function (channelObj, handler) {
13215
+ // If PubNub fails, we will fetch the events from this timestamp
13216
+ _startTimestampForPolling = Date.now();
13217
+
13218
13218
  var pubNubChannel;
13219
13219
  var channelContext = [];
13220
13220
 
@@ -13243,6 +13243,9 @@ module.exports = function () {
13243
13243
  _eventEmitter.on(channelObj.channel, handler);
13244
13244
  bStatusSubscribed = true;
13245
13245
  }
13246
+
13247
+ // Clean up the old events
13248
+ _checkOldBubbledEvents();
13246
13249
  },
13247
13250
  "getMySubscriptionStatus": __getMySubscriptionStatus
13248
13251
  };
@@ -13256,6 +13259,10 @@ module.exports = function () {
13256
13259
 
13257
13260
  var _translatePubnubStatus = function(status, options) {
13258
13261
  var channels = [], error, successObj;
13262
+
13263
+ // If polling has been initiated, ignore all punnub status
13264
+ if (bPollingInitiated) return;
13265
+
13259
13266
  switch (status.category) {
13260
13267
  case "PNConnectedCategory":
13261
13268
  if(status.operation === "PNSubscribeOperation") {
@@ -13317,11 +13324,10 @@ module.exports = function () {
13317
13324
  break;
13318
13325
  case "PNNetworkIssuesCategory":
13319
13326
  if(status.operation === 'PNSubscribeOperation') {
13320
- if(!options.accountId) {
13327
+ if(!options.accountId || !_userOptions.pollingEndpoint) {
13321
13328
  error = {
13322
- message: "Missing mandatory parameters to initiate polling operation - accountId",
13323
- status: status.statusCode,
13324
- type: helpers.errors.ERROR_TYPES.POLLING_INITIATION,
13329
+ message: "Polling initiation error: Missing mandatory parameters to initiate polling operation - [accountId, pollingEndpoint]",
13330
+ status: status.statusCode
13325
13331
  };
13326
13332
  error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
13327
13333
  _eventEmitter.emit('pushx_status', error);
@@ -13335,6 +13341,9 @@ module.exports = function () {
13335
13341
  * The wrapper supports multiple channels, but the APP currently uses a single channel only.
13336
13342
  * Polling will also limited to a single channel.
13337
13343
  */
13344
+ _pollingCounter = 0;
13345
+ _pollForEvents();
13346
+ bPollingInitiated = true;
13338
13347
  }
13339
13348
  }
13340
13349
  else {
@@ -13347,9 +13356,8 @@ module.exports = function () {
13347
13356
  default:
13348
13357
  // Emit error for other status-category received from pubnub
13349
13358
  error = {
13350
- message: "PushX Error",
13359
+ message: "PushX Error: unexpected error",
13351
13360
  status: status.statusCode,
13352
- type: helpers.errors.ERROR_TYPES.UNEXPECTED_ERROR,
13353
13361
  pushXError: status
13354
13362
  };
13355
13363
  error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
@@ -13386,6 +13394,7 @@ module.exports = function () {
13386
13394
  * @returns PROMISE.
13387
13395
  */
13388
13396
  var __setup = function (userOptions) {
13397
+
13389
13398
  var pubnubConfig = userOptions.pubnub;
13390
13399
  pubnubConfig.uuid = userOptions.userid;
13391
13400
  var accountId = userOptions.accountid;
@@ -13424,8 +13433,169 @@ module.exports = function () {
13424
13433
  _globalSubscription = [];
13425
13434
  bStatusSubscribed = false;
13426
13435
  _globalSubscriptionStatus = {};
13436
+ bPollingInitiated = false;
13427
13437
  }
13428
13438
  _pubnubClient = undefined;
13439
+
13440
+ // Clear the Polling
13441
+ if (_setTimeoutIDForPolling) {
13442
+ clearTimeout(_setTimeoutIDForPolling);
13443
+ // Setting the start time to now to clear the old events
13444
+ _startTimestampForPolling = Date.now();
13445
+ _checkOldBubbledEvents();
13446
+ _setTimeoutIDForPolling = undefined;
13447
+ _pollingCounter = undefined;
13448
+ _startTimestampForPolling = undefined;
13449
+ }
13450
+ };
13451
+
13452
+ /**
13453
+ * Polling function
13454
+ */
13455
+ var _pollForEvents = function () {
13456
+ // Setup request params
13457
+ var params = {
13458
+ accountid: _userOptions.accountid,
13459
+ channelname: _globalSubscription[0],
13460
+ starttime: _startTimestampForPolling,
13461
+ endtime: Date.now()
13462
+ };
13463
+
13464
+ // Safe check to avoid poll for events if the channel name or start time is not set
13465
+ // This handles an edge condition where the clearTimeout doesn't work as expected
13466
+ if (!params.channelname || !params.starttime) {
13467
+ return;
13468
+ }
13469
+
13470
+ var requestAPI = request.get(_userOptions.pollingEndpoint).query(params);
13471
+
13472
+ requestAPI
13473
+ .end(function(error, response) {
13474
+
13475
+ if (!error) {
13476
+ // Bubble the connected status
13477
+ if (_pollingCounter === 0) {
13478
+ // Set the status of the channel to subscribed
13479
+ if(_globalSubscriptionStatus[_globalSubscription[0]]) {
13480
+ _globalSubscriptionStatus[_globalSubscription[0]].status = 'subscribed';
13481
+ }
13482
+
13483
+ var successObj = {
13484
+ category: 'PUSHX',
13485
+ type: 'CHANNEL_SUBSCRIPTION',
13486
+ status: 'SUCCESS',
13487
+ message: 'Success: Subscribed successfully.',
13488
+ httpcode: 200,
13489
+ data: {
13490
+ payload: {
13491
+ channels: _globalSubscription
13492
+ },
13493
+ message: 'Success: Subscribed successfully.'
13494
+ }
13495
+ };
13496
+ _eventEmitter.emit('pushx_status', successObj);
13497
+ }
13498
+
13499
+ // Bubble the received events
13500
+ _bubblePolledEvents(response.body);
13501
+
13502
+ // Increase the counter
13503
+ _pollingCounter++;
13504
+ }
13505
+
13506
+ // Polling will be done only for specific number of times
13507
+ if (_pollingCounter > _userOptions.pollingIterations) {
13508
+ var error = {
13509
+ message: "Polling error: Polling limit exceeded",
13510
+ status: 429
13511
+ };
13512
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
13513
+ _eventEmitter.emit('pushx_status', error);
13514
+ } else {
13515
+ var timeoutDelay;
13516
+
13517
+ // If the polling interval is provided, use that
13518
+ if (_userOptions.pollingInterval) {
13519
+ timeoutDelay = _userOptions.pollingInterval * 60 * 1000;
13520
+ } else {
13521
+ // Else, use exponential backoff
13522
+ timeoutDelay = parseInt(Math.pow(1.3, _pollingCounter) * 10 * 1000, 10);
13523
+ }
13524
+
13525
+ // Set timeout for next poll
13526
+ if (timeoutDelay) {
13527
+ _setTimeoutIDForPolling = setTimeout(_pollForEvents, timeoutDelay);
13528
+ }
13529
+ }
13530
+ });
13531
+ };
13532
+
13533
+ /**
13534
+ * Bubble the polled events to the FE APP
13535
+ * @param {*} events - Events recieved from the polling endpoint
13536
+ */
13537
+ var _bubblePolledEvents = function (events) {
13538
+ // Load the old events from the session storage
13539
+ var oldEventData = _checkOldBubbledEvents();
13540
+
13541
+ var oldEvents = oldEventData.events;
13542
+ var sessionStorageKey = oldEventData.key;
13543
+
13544
+ for (var i = 0; i < events.entities.length; i++) {
13545
+ var event = events.entities[i];
13546
+ var eventId = event.pk + '_' + event.sk;
13547
+
13548
+ // Check if the event is already emitted
13549
+ if (!oldEvents[eventId]) {
13550
+ oldEvents[eventId] = event.context.start_time;
13551
+
13552
+ // Emit the event
13553
+ _eventEmitter.emit(_globalSubscription[0], event);
13554
+ }
13555
+ }
13556
+
13557
+ // Save the bubbled events to session storage
13558
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
13559
+ };
13560
+
13561
+ /**
13562
+ * Check the old bubbled events and remove the events that are older than the start timestamp
13563
+ * @returns {object} - Object containing the key and the events
13564
+ */
13565
+ var _checkOldBubbledEvents = function () {
13566
+ var sessionStorageKey = 'comprodls.old_pushx_events.' + _userOptions.userid + '.' + _globalSubscription[0];
13567
+ var oldEvents = sessionStorage.getItem(sessionStorageKey);
13568
+
13569
+ if (oldEvents) {
13570
+ try {
13571
+ oldEvents = JSON.parse(oldEvents);
13572
+ } catch (e) {
13573
+ oldEvents = {};
13574
+ }
13575
+
13576
+ var oldEventIds = Object.keys(oldEvents);
13577
+
13578
+ // Remove the events that are older than the start timestamp
13579
+ for (var i = 0; i < oldEventIds.length; i++) {
13580
+ var oldEventId = oldEventIds[i];
13581
+
13582
+ if (oldEvents[oldEventId] < _startTimestampForPolling) {
13583
+ delete oldEvents[oldEventId];
13584
+ }
13585
+ }
13586
+
13587
+ // If the number of events has changed, save the events
13588
+ if (oldEventIds.length !== Object.keys(oldEvents).length) {
13589
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
13590
+ }
13591
+ } else {
13592
+ oldEvents = {};
13593
+ }
13594
+
13595
+ return {
13596
+ key: sessionStorageKey,
13597
+ events: oldEvents
13598
+ };
13429
13599
  };
13430
13600
 
13431
13601
  return { // Return public methods for the wrapper
@@ -13435,7 +13605,7 @@ module.exports = function () {
13435
13605
 
13436
13606
  }; //End of Client Wrapper module
13437
13607
 
13438
- },{"../../helpers":3,"events":38,"pubnub":41}],27:[function(require,module,exports){
13608
+ },{"../../helpers":3,"events":38,"pubnub":41,"superagent":45}],27:[function(require,module,exports){
13439
13609
  /*************************************************************************
13440
13610
  *
13441
13611
  * COMPRO CONFIDENTIAL