cloudcms-server 4.0.0-beta.1 → 4.0.0-beta.10

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.
@@ -3,6 +3,7 @@
3
3
  <component name="NewModuleRootManager" inherit-compiler-output="true">
4
4
  <exclude-output />
5
5
  <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="inheritedJdk" />
6
7
  <orderEntry type="sourceFolder" forTests="false" />
7
8
  </component>
8
9
  </module>
@@ -1,6 +1,6 @@
1
1
  //var auth = require("../../../util/auth");
2
2
 
3
- var SamlStrategy = require('passport-saml').Strategy;
3
+ var SamlStrategy = require('@node-saml/passport-saml').Strategy;
4
4
  var AbstractProvider = require("./abstract");
5
5
 
6
6
  if (!process.configuration) {
@@ -16,7 +16,8 @@ exports = module.exports = function()
16
16
 
17
17
  var pluginPaths = [
18
18
  "./plugins/editorial",
19
- "./plugins/resources"
19
+ "./plugins/resources",
20
+ "./plugins/api_event"
20
21
  ];
21
22
  var plugins = {};
22
23
 
@@ -149,21 +150,21 @@ exports = module.exports = function()
149
150
  var r = {};
150
151
 
151
152
  // allow plugins to bind on("connection") handlers
152
- r.bindOnSocketConnection = function(socket, provider, callback)
153
+ r.bindOnSocketConnection = function(socket, provider, io, callback)
153
154
  {
154
155
  var fns = [];
155
156
  for (var pluginPath in plugins)
156
157
  {
157
158
  var plugin = plugins[pluginPath];
158
159
 
159
- var fn = function(pluginPath, plugin, socket) {
160
+ var fn = function(pluginPath, plugin, socket, io) {
160
161
  return function(done) {
161
-
162
- plugin.bindSocket(socket, provider);
162
+
163
+ plugin.bindSocket(socket, provider, io);
163
164
 
164
165
  done();
165
166
  }
166
- }(pluginPath, plugin, socket);
167
+ }(pluginPath, plugin, socket, io);
167
168
  fns.push(fn);
168
169
  }
169
170
 
@@ -309,7 +310,7 @@ exports = module.exports = function()
309
310
  });
310
311
 
311
312
  // allow plugins to register more on() handlers if they wish
312
- pluginProxy.bindOnSocketConnection(socket, provider, function() {
313
+ pluginProxy.bindOnSocketConnection(socket, provider, io, function() {
313
314
  // done
314
315
  });
315
316
 
@@ -0,0 +1,105 @@
1
+ /*
2
+
3
+ this awareness plugin adds support for general purpose API events
4
+ the API in 4.0 supports passing API events forward via the message queue to the app server
5
+ the app server then converts these into notifications
6
+
7
+ the UI can register and event listener via socket.io ("onApiEvent").
8
+ a listener binds to an event type + an optional reference
9
+
10
+ when an event is received by the API, it triggers to socket.io emits (one for the general event and the other for the
11
+ event + the reference being acted upon)
12
+ */
13
+ exports = module.exports = {};
14
+
15
+ var util = require("../../../util/util");
16
+ var socketUtil = require("../../../util/socket");
17
+
18
+ var subscriptionsBound = false;
19
+
20
+ var bindSubscriptions = function(io)
21
+ {
22
+ if (subscriptionsBound) {
23
+ return;
24
+ }
25
+
26
+ subscriptionsBound = true;
27
+
28
+ // LISTEN: "api_event"
29
+ process.broadcast.subscribe("api_event", function (message, channel, done) {
30
+
31
+ if (!done) {
32
+ done = function () {};
33
+ }
34
+
35
+ // the message
36
+ // {
37
+ // "applicationId": applicationId,
38
+ // "deploymentKey": deploymentKey,
39
+ // "host": host,
40
+ // "eventType": eventType,
41
+ // "eventId": eventId,
42
+ // "objectType": objectType,
43
+ // "objectId": objectId,
44
+ // "objectRef": objectRef,
45
+ // "object": object.object
46
+ // };
47
+
48
+ var apiEvent = {};
49
+ apiEvent.type = message.eventType;
50
+ apiEvent.id = message.eventId;
51
+ apiEvent.objectType = message.objectType;
52
+ apiEvent.objectId = message.objectId;
53
+ apiEvent.objectRef = message.objectRef;
54
+ apiEvent.object = message.object;
55
+
56
+ // dispatch for event + reference
57
+ if (apiEvent.objectRef)
58
+ {
59
+ try {
60
+ apiEvent.channelId = "apiEvent-" + apiEvent.type + "_" + apiEvent.objectRef;
61
+ //console.log("api_event -> " + apiEvent.channelId);
62
+ io.to(apiEvent.channelId).emit("apiEvent", apiEvent);
63
+ } catch (e) {
64
+ console.log(e);
65
+ }
66
+ }
67
+
68
+ // dispatch for event
69
+ try {
70
+ apiEvent.channelId = "apiEvent-" + apiEvent.type;
71
+ //console.log("apiEvent -> " + apiEvent.channelId);
72
+ io.to(apiEvent.channelId).emit("apiEvent", apiEvent);
73
+ } catch (e) {
74
+ console.log(e);
75
+ }
76
+
77
+ done();
78
+ });
79
+ };
80
+
81
+ exports.bindSocket = function(socket, provider, io)
82
+ {
83
+ bindSubscriptions(io);
84
+
85
+ socketUtil.bindGitana(socket, function() {
86
+
87
+ socket.on("onApiEvent", function(eventName, reference, callback) {
88
+
89
+ if (eventName)
90
+ {
91
+ var channelId = "apiEvent-" + eventName;
92
+
93
+ if (reference)
94
+ {
95
+ channelId = eventName + "-" + reference;
96
+ }
97
+
98
+ // join room for this event
99
+ socket.join(channelId);
100
+ }
101
+
102
+ callback();
103
+ });
104
+ });
105
+ };
@@ -5,7 +5,7 @@ var socketUtil = require("../../../util/socket");
5
5
 
6
6
  var request = require("../../../util/request");
7
7
 
8
- exports.bindSocket = function(socket, provider)
8
+ exports.bindSocket = function(socket, provider, io)
9
9
  {
10
10
  socketUtil.bindGitana(socket, function() {
11
11
 
@@ -231,10 +231,11 @@ exports.bindSocket = function(socket, provider)
231
231
  var x1 = cookieValue.indexOf("GITANA_TICKET=");
232
232
  if (x1 > -1)
233
233
  {
234
- var x2 = cookieValue.indexOf(";", x1 + 14);
234
+ ticket = cookieValue.substring(x1 + 14);
235
+ var x2 = ticket.indexOf(";");
235
236
  if (x2 > -1)
236
237
  {
237
- ticket = cookieValue.substring(x1 + 14, x2);
238
+ ticket = ticket.substring(0, x2);
238
239
  }
239
240
  }
240
241
  }
@@ -5,7 +5,7 @@ var socketUtil = require("../../../util/socket");
5
5
 
6
6
  var subscriptionsBound = false;
7
7
 
8
- var bindSubscriptions = function()
8
+ var bindSubscriptions = function(io)
9
9
  {
10
10
  if (subscriptionsBound) {
11
11
  return;
@@ -43,19 +43,27 @@ var bindSubscriptions = function()
43
43
  };
44
44
 
45
45
  // fire to reference
46
- process.IO.to(reference).emit("watchResource", reference, watchObject);
46
+ try {
47
+ if (reference) {
48
+ io.to(reference).emit("watchResource", reference, watchObject);
49
+ }
50
+ } catch (e) { }
47
51
 
48
52
  // fire to head reference
49
- process.IO.to(headReference).emit("watchResource", headReference, watchObject);
53
+ try {
54
+ if (headReference) {
55
+ io.to(headReference).emit("watchResource", headReference, watchObject);
56
+ }
57
+ } catch (e) { }
50
58
  }
51
59
 
52
60
  done();
53
61
  });
54
62
  };
55
63
 
56
- exports.bindSocket = function(socket, provider)
64
+ exports.bindSocket = function(socket, provider, io)
57
65
  {
58
- bindSubscriptions();
66
+ bindSubscriptions(io);
59
67
 
60
68
  socketUtil.bindGitana(socket, function() {
61
69
 
@@ -1,10 +1,4 @@
1
- var path = require('path');
2
- var http = require('http');
3
- var request = require('request');
4
1
  var util = require("../../util/util");
5
- var Gitana = require("gitana");
6
-
7
- var fs = require("fs");
8
2
 
9
3
  /**
10
4
  * Retrieves local driver configuration for hosts from Cloud CMS.
@@ -55,14 +55,20 @@ exports = module.exports = function()
55
55
  });
56
56
  }
57
57
 
58
- if (!moduleConfig.source)
58
+ var source = moduleConfig.source40;
59
+ if (!source)
60
+ {
61
+ source = moduleConfig.source;
62
+ }
63
+
64
+ if (!source)
59
65
  {
60
66
  return callback({
61
67
  "message": "Missing module config source settings"
62
68
  });
63
69
  }
64
70
 
65
- var sourceType = moduleConfig.source.type;
71
+ var sourceType = source.type;
66
72
  if (!sourceType)
67
73
  {
68
74
  return callback({
@@ -70,7 +76,7 @@ exports = module.exports = function()
70
76
  });
71
77
  }
72
78
 
73
- var sourceUrl = moduleConfig.source.uri;
79
+ var sourceUrl = source.uri;
74
80
  if (!sourceUrl)
75
81
  {
76
82
  return callback({
@@ -78,12 +84,12 @@ exports = module.exports = function()
78
84
  });
79
85
  }
80
86
 
81
- var sourcePath = moduleConfig.source.path;
87
+ var sourcePath = source.path;
82
88
  if (!sourcePath) {
83
89
  sourcePath = "/";
84
90
  }
85
91
 
86
- var sourceBranch = moduleConfig.source.branch;
92
+ var sourceBranch = source.branch;
87
93
  if (!sourceBranch) {
88
94
  sourceBranch = "master";
89
95
  }
@@ -194,8 +194,9 @@ exports = module.exports = function()
194
194
  car = filename;
195
195
  }
196
196
  var regex1 = new RegExp("-[0-9a-f]{32}$"); // md5
197
- var regex2 = new RegExp("-[0-9]{13}$"); // timestamp
198
- if (regex1.test(car) || regex2.test(car))
197
+ var regex2 = new RegExp("-[0-9]{13}$"); // timestamp?
198
+ var regex3 = new RegExp("-[0-9]{10}$"); // epoch millis
199
+ if (regex1.test(car) || regex2.test(car) || regex3.test(car))
199
200
  {
200
201
  var x = car.lastIndexOf("-");
201
202
 
@@ -1,4 +1,3 @@
1
- var request = require('request');
2
1
  var path = require('path');
3
2
 
4
3
  var util = require("../../util/util");
@@ -417,7 +417,7 @@ exports = module.exports = function()
417
417
  var moduleStoreType = moduleDescriptors[i].store;
418
418
  var modulePath = moduleDescriptors[i].path;
419
419
 
420
- //console.log("Config Store - Module Path: " + modulePath + ", type: " + moduleStoreType);
420
+ console.log("Config Store - Module Path: " + modulePath + ", type: " + moduleStoreType);
421
421
 
422
422
  var storePath = path.join(modulePath, "config");
423
423
  if (moduleStoreType === "modules")
@@ -520,7 +520,7 @@ exports = module.exports = function()
520
520
  callback();
521
521
  });
522
522
  };
523
-
523
+
524
524
  process.cache.read("module-descriptors-" + host, function(err, moduleDescriptors) {
525
525
 
526
526
  moduleDescriptors = null;
@@ -1,6 +1,3 @@
1
- //var path = require('path');
2
- //var http = require('http');
3
- //var request = require('request');
4
1
  var util = require("../../util/util");
5
2
 
6
3
  /**
@@ -33,12 +30,12 @@ exports = module.exports = function()
33
30
  // force key to "virtualdriver"
34
31
  configuration.virtualDriver.key = VIRTUAL_DRIVER_CACHE_KEY;
35
32
 
36
- console.log("a1: " + JSON.stringify(configuration.virtualDriver, null, 2));
33
+ //console.log("a1: " + JSON.stringify(configuration.virtualDriver, null, 2));
37
34
 
38
35
  // either connect anew or re-use an existing connection to Cloud CMS for this application
39
36
  Gitana.connect(configuration.virtualDriver, function(err) {
40
37
 
41
- console.log("a2:" + err);
38
+ //console.log("a2:" + err);
42
39
  if (err)
43
40
  {
44
41
  return callback(err);
@@ -1,6 +1,3 @@
1
- var path = require('path');
2
- var http = require('http');
3
- var request = require('request');
4
1
  var util = require("../../util/util");
5
2
 
6
3
  /**
@@ -1,7 +1,4 @@
1
1
  var path = require('path');
2
- var fs = require('fs');
3
- var http = require('http');
4
- var request = require('request');
5
2
  var util = require("../../util/util");
6
3
 
7
4
  /**
@@ -72,11 +72,11 @@ var handleNotificationMessages = function(items, callback) {
72
72
  var fns = [];
73
73
  for (var i = 0; i < items.length; i++)
74
74
  {
75
- var fn = function(item, i) {
75
+ var fn = function(item, index) {
76
76
  return function(done) {
77
77
 
78
78
  //logFn("WORKING ON ITEM: " + i + ", item: " + JSON.stringify(item, null, " "));
79
- console.log("WORKING ON ITEM: " + i + ", item: " + JSON.stringify(item, null, " "));
79
+ console.log("WORKING ON ITEM: " + index + ", item: " + JSON.stringify(item, null, " "));
80
80
 
81
81
  var operation = item.operation;
82
82
 
@@ -540,6 +540,8 @@ var handleNotificationMessages = function(items, callback) {
540
540
 
541
541
  var host = determineHost(item);
542
542
 
543
+ var _fns = [];
544
+
543
545
  var deployments = item.deployments;
544
546
  if (deployments && deployments.length > 0)
545
547
  {
@@ -554,17 +556,77 @@ var handleNotificationMessages = function(items, callback) {
554
556
  "host": host,
555
557
  "deployment": deployment
556
558
  };
557
-
558
- // broadcast event
559
- process.broadcast.publish("deployment_synced", message, function(err) {
560
- if (err) {
561
- logInfo("published deployment_synced message. err:" + err + "\nmessage: " + JSON.stringify(message,null,2));
559
+
560
+ var _fn = function(message) {
561
+ return function(d) {
562
+ // broadcast event
563
+ process.broadcast.publish("deployment_synced", message, function(err) {
564
+ if (err) {
565
+ logInfo("published deployment_synced message. err:" + err + "\nmessage: " + JSON.stringify(message,null,2));
566
+ }
567
+ return done(err);
568
+ });
562
569
  }
563
- return done(err);
564
- });
565
-
570
+ }(message);
571
+ _fns.push(_fn);
566
572
  }
567
573
  }
574
+
575
+ async.parallelLimit(_fns, 4, function(err) {
576
+ done(err);
577
+ });
578
+ }
579
+ else if (operation === "api_event")
580
+ {
581
+ var eventType = item.type;
582
+ var eventId = item.id;
583
+ var objects = item.objects;
584
+
585
+ var host = determineHost(item);
586
+
587
+ var _fns = [];
588
+ if (objects && objects.length > 0)
589
+ {
590
+ for (var z = 0; z < objects.length; z++)
591
+ {
592
+ var object = objects[z];
593
+
594
+ var applicationId = object.applicationId;
595
+ var deploymentKey = item.deploymentKey;
596
+
597
+ var objectType = object.type; // sidekickMessage
598
+ var objectId = object.id;
599
+ var objectRef = object.ref;
600
+
601
+ var publishMessage = {
602
+ "applicationId": applicationId,
603
+ "deploymentKey": deploymentKey,
604
+ "host": host,
605
+ "eventType": eventType,
606
+ "eventId": eventId,
607
+ "objectType": objectType,
608
+ "objectId": objectId,
609
+ "objectRef": objectRef,
610
+ "object": object.object
611
+ };
612
+
613
+ var _fn = function(publishMessage) {
614
+ return function(d) {
615
+ // broadcast event
616
+ process.broadcast.publish("api_event", publishMessage, function(err) {
617
+ if (err) {
618
+ logInfo("published api_event message. err:" + err + "\nmessage: " + JSON.stringify(publishMessage,null,2));
619
+ }
620
+ return d(err);
621
+ });
622
+ }
623
+ }(publishMessage);
624
+ _fns.push(_fn);
625
+ }
626
+ }
627
+ async.parallelLimit(_fns, 4, function(err) {
628
+ done(err);
629
+ });
568
630
  }
569
631
  else
570
632
  {
@@ -0,0 +1,182 @@
1
+ const { Kafka } = require("kafkajs");
2
+ const util = require("../../util/util");
3
+
4
+ var holder = {};
5
+
6
+ module.exports = {};
7
+ module.exports.start = function(configuration, callback)
8
+ {
9
+ // clientId
10
+ if (!configuration.clientId)
11
+ {
12
+ if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_CLIENT_ID)
13
+ {
14
+ configuration.clientId = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_CLIENT_ID;
15
+ }
16
+ }
17
+ if (!configuration.clientId)
18
+ {
19
+ configuration.clientId = "cloudcms-ui-kafka-notifications-client";
20
+ }
21
+
22
+ // topic
23
+ if (!configuration.topic)
24
+ {
25
+ if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_TOPIC)
26
+ {
27
+ configuration.topic = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_TOPIC;
28
+ }
29
+ }
30
+ if (!configuration.topic)
31
+ {
32
+ configuration.topic = "cloudcms.ui.topic";
33
+ }
34
+
35
+ // group
36
+ if (!configuration.group)
37
+ {
38
+ if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_GROUP)
39
+ {
40
+ configuration.group = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_GROUP;
41
+ }
42
+ }
43
+ if (!configuration.group) {
44
+ configuration.group = "cloudcms-ui-kafka-notifications-group";
45
+ }
46
+
47
+ // brokers
48
+ if (!configuration.brokers)
49
+ {
50
+ if (process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_BROKERS)
51
+ {
52
+ configuration.brokers = process.env.CLOUDCMS_NOTIFICATIONS_KAFKA_BROKERS;
53
+ }
54
+ }
55
+
56
+ var clientId = configuration.clientId;
57
+ var brokers = configuration.brokers.split(",");
58
+ var topic = configuration.topic;
59
+ var group = configuration.group;
60
+
61
+ process.log("Connecting to kafka, client ID: " + clientId + ", brokers: " + brokers + ", topic: " + topic + ", group: " + group);
62
+
63
+ if (holder.consumer)
64
+ {
65
+ return callback();
66
+ }
67
+
68
+ // console.log("a1");
69
+ var kafka = new Kafka({
70
+ clientId: clientId,
71
+ brokers: brokers
72
+ });
73
+ // console.log("a2: " + kafka);
74
+ // console.log("a3: " + kafka.consumer);
75
+
76
+ var consumer = holder.consumer = kafka.consumer({ groupId: group });
77
+
78
+ // connect
79
+ (async function() {
80
+ await consumer.connect()
81
+ }());
82
+
83
+ (async function() {
84
+ await consumer.subscribe({topic: topic, fromBeginning: true})
85
+ }());
86
+
87
+ callback();
88
+ };
89
+
90
+ module.exports.process = function(callback)
91
+ {
92
+ var consumer = holder.consumer;
93
+ if (!consumer)
94
+ {
95
+ return callback();
96
+ }
97
+
98
+ (async function() {
99
+ await consumer.run({
100
+ eachMessage: async ({ topic, partition, message, heartbeat, pause }) => {
101
+ handleMessage(topic, partition, message, heartbeat, pause, callback);
102
+ }
103
+ });
104
+ }());
105
+ };
106
+
107
+ var handleMessage = function(topic, partition, messageObject, heartbeat, pause, callback)
108
+ {
109
+ // console.log("Topic: " + topic);
110
+ // console.log("Partition: " + partition);
111
+ // console.log("Message: " + JSON.stringify(messageObject, null, 2));
112
+
113
+ if (!messageObject || !messageObject.value)
114
+ {
115
+ return;
116
+ }
117
+
118
+ //var key = message.key.toString();
119
+ var valueString = messageObject.value.toString();
120
+ var headers = messageObject.headers || {};
121
+
122
+ var json = null;
123
+ if (valueString) {
124
+ json = JSON.parse("" + valueString);
125
+ }
126
+
127
+ // console.log("b1: " + valueString);
128
+ // console.log("b2: " + data);
129
+
130
+ if (json)
131
+ {
132
+ console.log("JSON: " + JSON.stringify(json));
133
+ console.log("HEADERS: " + JSON.stringify(headers));
134
+
135
+ /**
136
+ * kafka1-ui-1 | VAL: {"subject":"invalidate_objects:aea334cb8accb0bd698e","message":"","data":"{\"operation\":\"invalidate_objects\",\"invalidations\":[{\"applicationId\":\"1785c4b13f74b3aa4b31\",\"ref\":\"application://826a3ebefe4c1e006a60/1785c4b13f74b3aa4b31\",\"id\":\"1785c4b13f74b3aa4b31\",\"type\":\"application\",\"stackId\":\"a17879ca0923f6d9696b\",\"stackMembers\":{\"archives\":{\"typeId\":\"vault\",\"id\":\"385e37eb07bc3d16dca1\"},\"console\":{\"typeId\":\"application\",\"id\":\"1785c4b13f74b3aa4b31\"},\"content\":{\"typeId\":\"repository\",\"id\":\"9904550a6b2a2a71f015\"},\"hosting\":{\"typeId\":\"webhost\",\"id\":\"5d2db66ced26608dc355\"},\"oneteam\":{\"typeId\":\"application\",\"id\":\"8d5ba57420ce31a3172c\"},\"principals\":{\"typeId\":\"domain\",\"id\":\"32cbffafe9f2de4d1b9a\"},\"root\":{\"typeId\":\"directory\",\"id\":\"6db38348323d001c2c10\"}}}]}"}
137
+ * kafka1-ui-1 | HEADERS: [object Object]
138
+ * @type {*[]}
139
+ */
140
+
141
+ var subject = json.subject;
142
+ var message = json.message;
143
+
144
+ // build out the notification message items
145
+ var items = [];
146
+
147
+ if (json.data)
148
+ {
149
+ var data = JSON.parse("" + json.data);
150
+
151
+ // timestamp from headers
152
+ //var timestamp = parseInt(headers.timestamp);
153
+ var timestamp = new Date().getTime();
154
+
155
+ // copy data as item
156
+ var item = util.clone(data, true);
157
+ if (!item)
158
+ {
159
+ item = {};
160
+ }
161
+
162
+ // other properties
163
+ item.timestamp = timestamp;
164
+ item.sentTimestamp = timestamp;
165
+ item.subject = subject;
166
+
167
+ // raw message
168
+ item.rawMessage = json.data; // string
169
+
170
+ items.push(item);
171
+
172
+ //console.log("ITEM: " + JSON.stringify(item));
173
+ }
174
+ }
175
+
176
+ // call back to notifications engine to process these items
177
+ // when they're done processing, our callback is fired so that we can handle deletes and things
178
+ // we call the done() method when we're finished
179
+ callback(null, items, function(err, items, done) {
180
+ done(err, items, items);
181
+ });
182
+ };
@@ -63,6 +63,7 @@ module.exports.start = function(configuration, callback)
63
63
  var MessageConsumer = function MessageConsumer() { };
64
64
  MessageConsumer.prototype.init = function init(done) {
65
65
  console.log("STOMP client initializing to host: " + host + ", port: " + port);
66
+ var self = this;
66
67
  var stompClient = new Stomp({
67
68
  "host": host,
68
69
  "port": port,
@@ -85,6 +86,9 @@ module.exports.start = function(configuration, callback)
85
86
  });
86
87
 
87
88
  done();
89
+ }, function(err) {
90
+ console.error("STOMP Error: " + err);
91
+ done(err);
88
92
  });
89
93
  };
90
94
  holder.consumer = new MessageConsumer();