cloudcms-server 4.0.0-beta.2 → 4.0.0-beta.20

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.
Files changed (78) hide show
  1. package/README.md +0 -5
  2. package/cloudcms-server.iml +1 -0
  3. package/index.js +58 -32
  4. package/middleware/authentication/authentication.js +40 -12
  5. package/middleware/authentication/providers/saml.js +8 -4
  6. package/middleware/awareness/awareness.js +8 -7
  7. package/middleware/awareness/plugins/api_event.js +105 -0
  8. package/middleware/awareness/plugins/editorial.js +54 -3
  9. package/middleware/awareness/plugins/resources.js +13 -5
  10. package/middleware/config/adapter.js +0 -44
  11. package/middleware/deployment/deployment.js +22 -24
  12. package/middleware/driver/driver.js +24 -1
  13. package/middleware/driver-config/driver-config.js +0 -6
  14. package/middleware/modules/modules.js +11 -5
  15. package/middleware/perf/perf.js +3 -2
  16. package/middleware/registration/registration.js +0 -5
  17. package/middleware/stores/engines/empty.js +0 -4
  18. package/middleware/stores/engines/fs-caching-adapter.js +0 -5
  19. package/middleware/stores/engines/fs.js +0 -9
  20. package/middleware/stores/engines/s3.js +0 -5
  21. package/middleware/stores/engines/s3fs.js +0 -5
  22. package/middleware/stores/multistore.js +0 -29
  23. package/middleware/stores/store.js +0 -10
  24. package/middleware/stores/stores.js +2 -2
  25. package/middleware/virtual-config/virtual-config.js +253 -206
  26. package/middleware/virtual-files/virtual-files.js +0 -3
  27. package/middleware/welcome/welcome.js +0 -3
  28. package/notifications/notifications.js +72 -10
  29. package/notifications/providers/kafka.js +182 -0
  30. package/notifications/providers/stomp.js +4 -0
  31. package/package.json +40 -56
  32. package/server/index.js +216 -123
  33. package/server/standalone.js +1 -6
  34. package/util/auth.js +10 -4
  35. package/util/cloudcms.js +77 -35
  36. package/util/loaders.js +113 -0
  37. package/util/proxy-factory.js +143 -168
  38. package/util/request.js +6 -2
  39. package/util/workqueue.js +111 -0
  40. package/.last_command +0 -7
  41. package/duster/helpers/core/cloudcms/associations.js +0 -34
  42. package/duster/helpers/core/cloudcms/beta/markdown.js +0 -46
  43. package/duster/helpers/core/cloudcms/beta/nodeAttachmentText.js +0 -46
  44. package/duster/helpers/core/cloudcms/beta/params.js +0 -33
  45. package/duster/helpers/core/cloudcms/beta/processTemplate.js +0 -82
  46. package/duster/helpers/core/cloudcms/content.js +0 -34
  47. package/duster/helpers/core/cloudcms/expand.js +0 -38
  48. package/duster/helpers/core/cloudcms/form.js +0 -34
  49. package/duster/helpers/core/cloudcms/query.js +0 -34
  50. package/duster/helpers/core/cloudcms/queryOne.js +0 -34
  51. package/duster/helpers/core/cloudcms/relatives.js +0 -34
  52. package/duster/helpers/core/cloudcms/search.js +0 -34
  53. package/duster/helpers/core/cloudcms/searchOne.js +0 -34
  54. package/duster/helpers/core/cloudcms/wcm/dependency.js +0 -83
  55. package/duster/helpers/core/cloudcms/wcm/fragment.js +0 -34
  56. package/duster/helpers/core/dev/debug.js +0 -42
  57. package/duster/helpers/core/dom/block.js +0 -49
  58. package/duster/helpers/core/dom/include.js +0 -38
  59. package/duster/helpers/core/dom/layout.js +0 -49
  60. package/duster/helpers/core/dom/link.js +0 -81
  61. package/duster/helpers/core/dom/resource.js +0 -77
  62. package/duster/helpers/core/engine.js +0 -1580
  63. package/duster/helpers/core/ice/value.js +0 -65
  64. package/duster/helpers/core/index.js +0 -49
  65. package/duster/helpers/core/operators/if.js +0 -64
  66. package/duster/helpers/core/operators/iter.js +0 -45
  67. package/duster/helpers/core/operators/iterate.js +0 -129
  68. package/duster/helpers/sample/nyt.js +0 -114
  69. package/duster/index.js +0 -319
  70. package/duster/support.js +0 -436
  71. package/duster/tracker.js +0 -262
  72. package/middleware/authentication/providers/cas.js +0 -73
  73. package/middleware/authentication/providers/facebook.js +0 -120
  74. package/middleware/authentication/providers/github.js +0 -88
  75. package/middleware/authentication/providers/linkedin.js +0 -112
  76. package/middleware/authentication/providers/twitter.js +0 -120
  77. package/middleware/server-tags/server-tags.js +0 -113
  78. package/middleware/wcm/wcm.js +0 -1437
package/util/cloudcms.js CHANGED
@@ -7,8 +7,13 @@ var https = require("https");
7
7
 
8
8
  var request = require("./request");
9
9
 
10
+ var workQueueFactory = require("./workqueue");
11
+
10
12
  exports = module.exports = function()
11
13
  {
14
+ // ensures that we only load 5 preview icons at a time
15
+ var previewQueueFn = workQueueFactory("previewQueue", 5, false);
16
+
12
17
  var toCacheFilePath = function(filePath)
13
18
  {
14
19
  var filename = path.basename(filePath);
@@ -311,8 +316,13 @@ exports = module.exports = function()
311
316
  * @param filePath
312
317
  * @param callback
313
318
  */
314
- var writeToDisk = function(contentStore, gitana, uri, filePath, callback)
319
+ var writeToDisk = function(contentStore, gitana, uri, filePath, queueFn, callback)
315
320
  {
321
+ if (!callback) {
322
+ queueFn = callback;
323
+ queueFn = null;
324
+ }
325
+
316
326
  var _refreshAccessTokenAndRetry = function(contentStore, gitana, uri, filePath, attemptCount, maxAttemptsAllowed, previousError, cb)
317
327
  {
318
328
  // tell gitana driver to refresh access token
@@ -346,7 +356,8 @@ exports = module.exports = function()
346
356
  });
347
357
  }
348
358
 
349
- var failFast = function(contentStore, filePath, cb) {
359
+ var failFast = function(contentStore, filePath, cb)
360
+ {
350
361
  var triggered = false;
351
362
 
352
363
  return function(tempStream, err)
@@ -373,7 +384,7 @@ exports = module.exports = function()
373
384
  contentStore.writeStream(filePath, function(err, tempStream) {
374
385
 
375
386
  if (err) {
376
- return failFast(tempStream, err);
387
+ return failFast(tempStream, err, cb);
377
388
  }
378
389
 
379
390
  var cacheFilePath = toCacheFilePath(filePath);
@@ -396,10 +407,11 @@ exports = module.exports = function()
396
407
  "method": "GET",
397
408
  "url": URL,
398
409
  "qs": {},
410
+ "timeout": 3000,
399
411
  "headers": headers,
400
412
  "responseType": "stream"
401
- }, function(err, response) {
402
-
413
+ }, function(err, response, stream) {
414
+
403
415
  if (err) {
404
416
  closeWriteStream(tempStream);
405
417
  return cb(err);
@@ -407,34 +419,34 @@ exports = module.exports = function()
407
419
 
408
420
  if (response.status >= 200 && response.status <= 204)
409
421
  {
410
- response.data.pipe(tempStream).on("close", function (err) {
411
-
422
+ var handle = function (err) {
423
+
412
424
  if (err) {
413
425
  // some went wrong at disk io level?
414
- return failFast(tempStream, err);
426
+ return failFast(tempStream, err, cb);
415
427
  }
416
-
428
+
417
429
  contentStore.existsFile(filePath, function (exists) {
418
-
430
+
419
431
  if (exists) {
420
-
432
+
421
433
  // write cache file
422
434
  var cacheInfo = buildCacheInfo(response);
423
435
  if (!cacheInfo) {
424
436
  return cb(null, filePath, null);
425
437
  }
426
-
438
+
427
439
  contentStore.writeFile(cacheFilePath, JSON.stringify(cacheInfo, null, " "), function (err) {
428
-
440
+
429
441
  if (err) {
430
442
  // failed to write cache file, thus the whole thing is invalid
431
443
  return safeRemove(contentStore, cacheFilePath, function () {
432
444
  failFast(tempStream, {
433
445
  "message": "Failed to write cache file: " + cacheFilePath + ", err: " + JSON.stringify(err)
434
- });
446
+ }, cb);
435
447
  });
436
448
  }
437
-
449
+
438
450
  cb(null, filePath, cacheInfo);
439
451
  });
440
452
  } else {
@@ -443,13 +455,27 @@ exports = module.exports = function()
443
455
  safeRemove(contentStore, cacheFilePath, function () {
444
456
  failFast(tempStream, {
445
457
  "message": "Failed to verify written cached file: " + filePath
446
- });
458
+ }, cb);
447
459
  });
448
460
  }
449
461
  });
450
-
462
+ };
463
+
464
+ // stream.on("end", function() {
465
+ // console.log("g1");
466
+ // });
467
+ // stream.on("finish", function() {
468
+ // console.log("g2");
469
+ // });
470
+ stream.on("close", handle);
471
+
472
+ stream.pipe(tempStream).on("close", handle).on("end", function() {
473
+ //console.log("a4");
474
+ }).on("finish", function() {
475
+ //console.log("a5");
451
476
  }).on("error", function (err) {
452
- failFast(tempStream, err);
477
+ console.log("a3");
478
+ failFast(tempStream, err, cb);
453
479
  });
454
480
  }
455
481
  else
@@ -457,13 +483,13 @@ exports = module.exports = function()
457
483
  // some kind of http error (usually permission denied or invalid_token)
458
484
 
459
485
  var body = "";
460
-
461
- response.data.on('data', function (chunk) {
486
+
487
+ stream.on('data', function (chunk) {
462
488
  body += chunk;
463
489
  });
464
-
465
- response.data.on('end', function () {
466
-
490
+
491
+ stream.on('end', function () {
492
+
467
493
  var afterCleanup = function () {
468
494
 
469
495
  // see if it is "invalid_token"
@@ -505,11 +531,10 @@ exports = module.exports = function()
505
531
  });
506
532
  });
507
533
  });
508
-
509
534
  }
510
535
  });
511
536
  // }).on('error', function (e) {
512
- // failFast(tempStream, e);
537
+ // failFast(tempStream, e, cb);
513
538
  //
514
539
  // }).on('end', function (e) {
515
540
  //
@@ -522,7 +547,7 @@ exports = module.exports = function()
522
547
  process.log("Temp stream errored out");
523
548
  process.log(e);
524
549
 
525
- failFast(tempStream, e);
550
+ failFast(tempStream, e, cb);
526
551
 
527
552
  // ensure stream is closed
528
553
  //closeWriteStream(tempStream);
@@ -532,10 +557,27 @@ exports = module.exports = function()
532
557
 
533
558
  };
534
559
 
535
- _writeToDisk(contentStore, gitana, uri, filePath, 0, 2, null, function(err, filePath, cacheInfo) {
560
+ var workFn = function(contentStore, gitana, uri, filePath)
561
+ {
562
+ return function(done)
563
+ {
564
+ _writeToDisk(contentStore, gitana, uri, filePath, 0, 2, null, function(err, filePath, cacheInfo) {
565
+ done(err, filePath, cacheInfo);
566
+ });
567
+ }
568
+ }(contentStore, gitana, uri, filePath);
569
+
570
+ if (queueFn)
571
+ {
572
+ return queueFn(workFn, function(err, filePath, cacheInfo) {
573
+ callback(err, filePath, cacheInfo);
574
+ });
575
+ }
576
+
577
+ // otherwise, invoke right away
578
+ workFn(function(err, filePath, cacheInfo) {
536
579
  callback(err, filePath, cacheInfo);
537
580
  });
538
-
539
581
  };
540
582
 
541
583
  /**
@@ -555,7 +597,7 @@ exports = module.exports = function()
555
597
  var downloadNode = function(contentStore, gitana, repositoryId, branchId, nodeId, attachmentId, nodePath, locale, forceReload, callback)
556
598
  {
557
599
  // ensure path starts with "/"
558
- if (nodePath && nodePath.substring(0, 1) !== "/") {
600
+ if (nodePath && !nodePath.startsWith("/")) {
559
601
  nodePath = "/" + nodePath;
560
602
  }
561
603
 
@@ -601,7 +643,7 @@ exports = module.exports = function()
601
643
  }
602
644
 
603
645
  // grab from Cloud CMS and write to disk
604
- writeToDisk(contentStore, gitana, uri, filePath, function (err, filePath, cacheInfo) {
646
+ writeToDisk(contentStore, gitana, uri, filePath, null, function (err, filePath, cacheInfo) {
605
647
 
606
648
  if (err) {
607
649
  process.log("writeToDisk error, err: " + err.message + ", body: " + err.body);
@@ -666,7 +708,7 @@ exports = module.exports = function()
666
708
  }
667
709
 
668
710
  // ensure path starts with "/"
669
- if (nodePath && nodePath.substring(0, 1) !== "/") {
711
+ if (nodePath && !nodePath.startsWith("/")) {
670
712
  nodePath = "/" + nodePath;
671
713
  }
672
714
 
@@ -719,11 +761,11 @@ exports = module.exports = function()
719
761
  uri += "&mimetype=" + mimetype;
720
762
  }
721
763
 
722
- writeToDisk(contentStore, gitana, uri, filePath, function (err, filePath, responseHeaders) {
764
+ writeToDisk(contentStore, gitana, uri, filePath, previewQueueFn, function (err, filePath, responseHeaders) {
723
765
 
724
766
  if (err) {
725
767
 
726
- if (err.code === 404) {
768
+ if (err.status === 404) {
727
769
  return callback();
728
770
  }
729
771
 
@@ -876,7 +918,7 @@ exports = module.exports = function()
876
918
  uri += "?a=true";
877
919
 
878
920
  // grab from Cloud CMS and write to disk
879
- writeToDisk(contentStore, gitana, uri, filePath, function (err, filePath, cacheInfo) {
921
+ writeToDisk(contentStore, gitana, uri, filePath, null, function (err, filePath, cacheInfo) {
880
922
 
881
923
  if (err) {
882
924
  callback(err);
@@ -978,7 +1020,7 @@ exports = module.exports = function()
978
1020
  uri += "&mimetype=" + mimetype;
979
1021
  }
980
1022
 
981
- writeToDisk(contentStore, gitana, uri, filePath, function (err, filePath, responseHeaders) {
1023
+ writeToDisk(contentStore, gitana, uri, filePath, previewQueueFn, function (err, filePath, responseHeaders) {
982
1024
 
983
1025
  if (err) {
984
1026
  callback(err);
@@ -0,0 +1,113 @@
1
+ var exports = module.exports;
2
+
3
+ var AsyncLock = require("async-lock");
4
+
5
+ var SENTINEL_NOT_FOUND_VALUE = "null";
6
+
7
+ /**
8
+ * Applies caching to a loader.
9
+ *
10
+ * A loader function is invoked like:
11
+ *
12
+ * loader(function(err, value) {
13
+ *
14
+ * });
15
+ *
16
+ * Its job is to load something from a remote place and then fire the callback.
17
+ *
18
+ * This method wraps caching around the loader for the given key. It returns a new loader
19
+ * that checks a given cache (key) for a value ahead of invoking the actual underlying loader.
20
+ *
21
+ * @param loader
22
+ * @param cache
23
+ * @param key
24
+ */
25
+ var cached = exports.cached = function(loader, cache, key)
26
+ {
27
+ return function(callback)
28
+ {
29
+ cache.read(key, function(err, value) {
30
+
31
+ if (value === SENTINEL_NOT_FOUND_VALUE) {
32
+ return callback();
33
+ }
34
+
35
+ if (value) {
36
+ return callback(null, value);
37
+ }
38
+
39
+ loader(function(err, value) {
40
+
41
+ if (err) {
42
+ return callback(err);
43
+ }
44
+
45
+ if (!value) {
46
+ return cache.write(key, SENTINEL_NOT_FOUND_VALUE, function () {
47
+ callback();
48
+ });
49
+ }
50
+
51
+ // write to cache
52
+ return cache.write(key, value, function () {
53
+ callback.call(this, null, value);
54
+ });
55
+ });
56
+ });
57
+ };
58
+ };
59
+
60
+ var lock = new AsyncLock();
61
+
62
+ /**
63
+ * Applies caching to a loader.
64
+ *
65
+ * A loader function is invoked like:
66
+ *
67
+ * loader(function(err, value) {
68
+ *
69
+ * });
70
+ *
71
+ * Its job is to load something from a remote place and then fire the callback.
72
+ *
73
+ * This method wraps an exclusive mutex lock around the given loader. This makes it so that only one
74
+ * invocation of this loader may run per key within the event loop.
75
+ *
76
+ * @param loader
77
+ * @param key
78
+ */
79
+ var exclusive = exports.exclusive = function(loader, key, timeout)
80
+ {
81
+ return function(callback)
82
+ {
83
+ var opts = {};
84
+ // up to 50000 tasks in the queue
85
+ opts.maxPending = 50000;
86
+ if (timeout) {
87
+ opts.timeout = timeout;
88
+ }
89
+
90
+ lock.acquire(key, function(releaseFn) {
91
+ loader(function(err, value) {
92
+ setTimeout(function() {
93
+ releaseFn();
94
+ }, 0);
95
+ callback.call(this, err, value);
96
+ });
97
+ }, function(err, value) {
98
+ // lock was released
99
+ if (err) {
100
+ console.error("Failed to acquire lock for key: " + key + ", error: ", err, " return value: ", value);
101
+ }
102
+ }, opts);
103
+ };
104
+ };
105
+
106
+ var cachedExclusive = exports.cachedExclusive = function(loader, cache, key, timeout)
107
+ {
108
+ var cachedLoader1 = cached(loader, cache, key);
109
+ var exclusiveLoader = exclusive(cachedLoader1, key, timeout);
110
+ var cachedLoader2 = cached(exclusiveLoader, cache, key);
111
+
112
+ return cachedLoader2;
113
+ };