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.
- package/README.md +0 -5
- package/cloudcms-server.iml +1 -0
- package/index.js +58 -32
- package/middleware/authentication/authentication.js +40 -12
- package/middleware/authentication/providers/saml.js +8 -4
- package/middleware/awareness/awareness.js +8 -7
- package/middleware/awareness/plugins/api_event.js +105 -0
- package/middleware/awareness/plugins/editorial.js +54 -3
- package/middleware/awareness/plugins/resources.js +13 -5
- package/middleware/config/adapter.js +0 -44
- package/middleware/deployment/deployment.js +22 -24
- package/middleware/driver/driver.js +24 -1
- package/middleware/driver-config/driver-config.js +0 -6
- package/middleware/modules/modules.js +11 -5
- package/middleware/perf/perf.js +3 -2
- package/middleware/registration/registration.js +0 -5
- package/middleware/stores/engines/empty.js +0 -4
- package/middleware/stores/engines/fs-caching-adapter.js +0 -5
- package/middleware/stores/engines/fs.js +0 -9
- package/middleware/stores/engines/s3.js +0 -5
- package/middleware/stores/engines/s3fs.js +0 -5
- package/middleware/stores/multistore.js +0 -29
- package/middleware/stores/store.js +0 -10
- package/middleware/stores/stores.js +2 -2
- package/middleware/virtual-config/virtual-config.js +253 -206
- package/middleware/virtual-files/virtual-files.js +0 -3
- package/middleware/welcome/welcome.js +0 -3
- package/notifications/notifications.js +72 -10
- package/notifications/providers/kafka.js +182 -0
- package/notifications/providers/stomp.js +4 -0
- package/package.json +40 -56
- package/server/index.js +216 -123
- package/server/standalone.js +1 -6
- package/util/auth.js +10 -4
- package/util/cloudcms.js +77 -35
- package/util/loaders.js +113 -0
- package/util/proxy-factory.js +143 -168
- package/util/request.js +6 -2
- package/util/workqueue.js +111 -0
- package/.last_command +0 -7
- package/duster/helpers/core/cloudcms/associations.js +0 -34
- package/duster/helpers/core/cloudcms/beta/markdown.js +0 -46
- package/duster/helpers/core/cloudcms/beta/nodeAttachmentText.js +0 -46
- package/duster/helpers/core/cloudcms/beta/params.js +0 -33
- package/duster/helpers/core/cloudcms/beta/processTemplate.js +0 -82
- package/duster/helpers/core/cloudcms/content.js +0 -34
- package/duster/helpers/core/cloudcms/expand.js +0 -38
- package/duster/helpers/core/cloudcms/form.js +0 -34
- package/duster/helpers/core/cloudcms/query.js +0 -34
- package/duster/helpers/core/cloudcms/queryOne.js +0 -34
- package/duster/helpers/core/cloudcms/relatives.js +0 -34
- package/duster/helpers/core/cloudcms/search.js +0 -34
- package/duster/helpers/core/cloudcms/searchOne.js +0 -34
- package/duster/helpers/core/cloudcms/wcm/dependency.js +0 -83
- package/duster/helpers/core/cloudcms/wcm/fragment.js +0 -34
- package/duster/helpers/core/dev/debug.js +0 -42
- package/duster/helpers/core/dom/block.js +0 -49
- package/duster/helpers/core/dom/include.js +0 -38
- package/duster/helpers/core/dom/layout.js +0 -49
- package/duster/helpers/core/dom/link.js +0 -81
- package/duster/helpers/core/dom/resource.js +0 -77
- package/duster/helpers/core/engine.js +0 -1580
- package/duster/helpers/core/ice/value.js +0 -65
- package/duster/helpers/core/index.js +0 -49
- package/duster/helpers/core/operators/if.js +0 -64
- package/duster/helpers/core/operators/iter.js +0 -45
- package/duster/helpers/core/operators/iterate.js +0 -129
- package/duster/helpers/sample/nyt.js +0 -114
- package/duster/index.js +0 -319
- package/duster/support.js +0 -436
- package/duster/tracker.js +0 -262
- package/middleware/authentication/providers/cas.js +0 -73
- package/middleware/authentication/providers/facebook.js +0 -120
- package/middleware/authentication/providers/github.js +0 -88
- package/middleware/authentication/providers/linkedin.js +0 -112
- package/middleware/authentication/providers/twitter.js +0 -120
- package/middleware/server-tags/server-tags.js +0 -113
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
486
|
+
|
|
487
|
+
stream.on('data', function (chunk) {
|
|
462
488
|
body += chunk;
|
|
463
489
|
});
|
|
464
|
-
|
|
465
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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);
|
package/util/loaders.js
ADDED
|
@@ -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
|
+
};
|