@nebulae/event-store-tpi-rx6 1.1.2
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/.env +0 -0
- package/.jshintrc +4 -0
- package/.vscode/settings.json +6 -0
- package/README.md +23 -0
- package/docs/images/microservices_platform.png +0 -0
- package/docs/images/nebula.png +0 -0
- package/docs/images/read_workflow.png +0 -0
- package/docs/images/service_interaction.png +0 -0
- package/docs/images/shell_composition.png +0 -0
- package/docs/images/write_workflow_crud_es.png +0 -0
- package/docs/images/write_workflow_pure_cqrs_es.png +0 -0
- package/docs/tmp/microservices_platform.png +0 -0
- package/docs/tmp/ms-dashboard-devices_intro.png +0 -0
- package/docs/tmp/ms-devices-location-dev-env.png +0 -0
- package/docs/tmp/nebula.png +0 -0
- package/docs/tmp/read_workflow.png +0 -0
- package/docs/tmp/service_interaction.png +0 -0
- package/docs/tmp/shell_composition.png +0 -0
- package/docs/tmp/write_workflow_crud_es.png +0 -0
- package/docs/tmp/write_workflow_pure_cqrs_es.png +0 -0
- package/index.js +9 -0
- package/lib/EventStore.js +172 -0
- package/lib/broker/MqttBroker.js +116 -0
- package/lib/broker/PubSubBroker.js +144 -0
- package/lib/entities/Event.js +47 -0
- package/lib/store/MongoStore.js +455 -0
- package/package.json +68 -0
- package/test/EventStore.js +114 -0
- package/test/broker/MqttBroker.js +129 -0
- package/test/broker/PubSubBroker.js +125 -0
- package/test/store/MongoStore.js +509 -0
package/.env
ADDED
|
File without changes
|
package/.jshintrc
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Event Store
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Installation
|
|
5
|
+
|
|
6
|
+
Assuming that Node.js is already installed & running,
|
|
7
|
+
|
|
8
|
+
## Install as dependency
|
|
9
|
+
```sh
|
|
10
|
+
$ npm install @nebulae/event-store-tpi-rx6
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
# usage
|
|
14
|
+
## Author & Contributors
|
|
15
|
+
|
|
16
|
+
Developed & maintained by authors: <b>Sebastian Molano & Esteban Zapata on behalf of Nebula Engineering SAS</b><br>
|
|
17
|
+
Follow Nebula Engineering at: <a href="https://github.com/NebulaEngineering" target="_blank">github</a>
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
The MIT License (MIT)
|
|
22
|
+
|
|
23
|
+
Copyright (c) 2018 Nebula Engineering SAS
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Rx = require('rxjs');
|
|
4
|
+
const { filter, map, concatMap, switchMap } = require('rxjs/operators');
|
|
5
|
+
const EventResult = require('./entities/Event');
|
|
6
|
+
|
|
7
|
+
class EventStore {
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a new EventStore
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} brokerConfig
|
|
14
|
+
* {
|
|
15
|
+
* type,
|
|
16
|
+
* eventsTopic,
|
|
17
|
+
* brokerUrl,
|
|
18
|
+
* eventsTopicSubscription,
|
|
19
|
+
* projectId,
|
|
20
|
+
* }
|
|
21
|
+
* @param {Object} storeConfig
|
|
22
|
+
* {
|
|
23
|
+
* type,
|
|
24
|
+
* url,
|
|
25
|
+
* eventStoreDbName,
|
|
26
|
+
* aggregatesDbName
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
constructor(brokerConfig, storeConfig) {
|
|
30
|
+
switch (brokerConfig.type) {
|
|
31
|
+
case "PUBSUB":
|
|
32
|
+
const PubSubBroker = require('./broker/PubSubBroker');
|
|
33
|
+
this.broker = new PubSubBroker(brokerConfig);
|
|
34
|
+
break;
|
|
35
|
+
case "MQTT":
|
|
36
|
+
const MqttBroker = require('./broker/MqttBroker');
|
|
37
|
+
this.broker = new MqttBroker(brokerConfig);
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
throw new Error(`Invalid EventStore broker type: ${brokerConfig.type} `);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
switch (storeConfig.type) {
|
|
44
|
+
case "MONGO":
|
|
45
|
+
const MongoStore = require('./store/MongoStore');
|
|
46
|
+
this.storeDB = new MongoStore(storeConfig);
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Invalid EventStore store type: ${storeConfig.type} `);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Starts Event Broker + Store
|
|
55
|
+
*/
|
|
56
|
+
start$() {
|
|
57
|
+
return Rx.merge(
|
|
58
|
+
this.broker.start$(),
|
|
59
|
+
this.storeDB.start$()
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Stops Event Broker + Store
|
|
65
|
+
*/
|
|
66
|
+
stop$() {
|
|
67
|
+
return Rx.merge(
|
|
68
|
+
this.broker.stop$(),
|
|
69
|
+
this.storeDB.stop$()
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Appends and emit a new Event
|
|
75
|
+
*
|
|
76
|
+
* @param {Event} event Event to store and emit
|
|
77
|
+
*
|
|
78
|
+
* Returns an obseravable that resolves to:
|
|
79
|
+
* {
|
|
80
|
+
* storeResult : {aggregate,event,versionTimeStr},
|
|
81
|
+
* brokerResult: { messageId }
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* where:
|
|
85
|
+
* - aggregate = current aggregate state
|
|
86
|
+
* - event = persisted event
|
|
87
|
+
* - versionTimeStr = EventStore date index where the event was store
|
|
88
|
+
* - messageId: sent message ID
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
emitEvent$(event) {
|
|
92
|
+
return this.storeDB.pushEvent$(event)
|
|
93
|
+
.pipe(
|
|
94
|
+
concatMap((storeResult) =>
|
|
95
|
+
this.broker.publish$(storeResult.event)
|
|
96
|
+
.pipe(map(messageId => {
|
|
97
|
+
return { storeResult, brokerResult: { messageId } };
|
|
98
|
+
}))
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Find all events of an especific aggregate
|
|
105
|
+
* @param {String} aggregateType Aggregate type
|
|
106
|
+
* @param {String} aggregateId Aggregate Id
|
|
107
|
+
* @param {number} version version to recover from (exclusive), defualt = 0
|
|
108
|
+
* @param {limit} limit max number of events to return, default = 20
|
|
109
|
+
*
|
|
110
|
+
* Returns an Observable that emits each found event one by one
|
|
111
|
+
*/
|
|
112
|
+
retrieveEvents$(aggregateType, aggregateId, version = 0, limit = 20) {
|
|
113
|
+
return this.storeDB.getEvents$(aggregateType, aggregateId, version, limit)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Find all events of an especific aggregate having taken place but not acknowledged,
|
|
118
|
+
* @param {String} aggregateType Aggregate type
|
|
119
|
+
* @param {string} key process key (eg. microservice name) that acknowledged the events
|
|
120
|
+
*
|
|
121
|
+
* Returns an Observable that emits each found event one by one
|
|
122
|
+
*/
|
|
123
|
+
retrieveUnacknowledgedEvents$(aggregateType, key) {
|
|
124
|
+
return this.storeDB.retrieveUnacknowledgedEvents$(aggregateType, key);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Find Aggregates that were created after the given date
|
|
129
|
+
*
|
|
130
|
+
* @param {string} type
|
|
131
|
+
* @param {number} createTimestamp
|
|
132
|
+
* @param {Object} ops {offset,pageSize}
|
|
133
|
+
*
|
|
134
|
+
* Returns an observable that publish every found aggregate
|
|
135
|
+
*/
|
|
136
|
+
findAgregatesCreatedAfter$(type, createTimestamp = 0) {
|
|
137
|
+
return this.storeDB.findAgregatesCreatedAfter$(type, createTimestamp);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Returns an Observable that will emit any event related to the given aggregateType
|
|
142
|
+
* @param {string} aggregateType
|
|
143
|
+
*/
|
|
144
|
+
getEventListener$(aggregateType, key, ignoreSelfEvents = true) {
|
|
145
|
+
return this.storeDB.findLatestAcknowledgedTimestamp$(aggregateType, key).pipe(
|
|
146
|
+
switchMap(latestTimeStamp => {
|
|
147
|
+
//this will ignore all queued messages that were already processed
|
|
148
|
+
return this.broker.getEventListener$(aggregateType, ignoreSelfEvents)
|
|
149
|
+
.pipe(filter(evt => evt.timestamp > latestTimeStamp))
|
|
150
|
+
})
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {Event} event event to acknowledge
|
|
156
|
+
* @param {string} key process key (eg. microservice name) that is acknowledging the event
|
|
157
|
+
*/
|
|
158
|
+
acknowledgeEvent$(event, key) {
|
|
159
|
+
return this.storeDB.acknowledgeEvent$(event, key);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Ensure the existence of a registry on the ack database for an aggregate type
|
|
164
|
+
* @param {string} aggregateType
|
|
165
|
+
* @param {string} key backend key
|
|
166
|
+
*/
|
|
167
|
+
ensureAcknowledgeRegistry$(aggregateType, key) {
|
|
168
|
+
return this.storeDB.ensureAcknowledgeRegistry$(aggregateType, key);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = EventStore;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Rx = require('rxjs');
|
|
4
|
+
const { filter, mapTo, map} = require('rxjs/operators');
|
|
5
|
+
const uuidv4 = require('uuid/v4');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MqttBroker {
|
|
10
|
+
|
|
11
|
+
constructor({ eventsTopic, brokerUrl }) {
|
|
12
|
+
|
|
13
|
+
this.topicName = eventsTopic;
|
|
14
|
+
this.mqttServerUrl = brokerUrl;
|
|
15
|
+
this.senderId = uuidv4();
|
|
16
|
+
/**
|
|
17
|
+
* Rx Subject for Incoming events
|
|
18
|
+
*/
|
|
19
|
+
this.incomingEvents$ = new Rx.BehaviorSubject();
|
|
20
|
+
this.orderedIncomingEvents$ = this.incomingEvents$.pipe(
|
|
21
|
+
filter(msg => msg)
|
|
22
|
+
)
|
|
23
|
+
// .groupBy(msg => msg.data.at)
|
|
24
|
+
// .mergeMap(groupStream =>
|
|
25
|
+
// groupStream.bufferWhen(() => groupStream.debounceTime(250))
|
|
26
|
+
// .filter(bufferedArray => bufferedArray && bufferedArray.length > 0)
|
|
27
|
+
// .map(bufferedArray => bufferedArray.sort((o1, o2) => { return o1.data.av - o2.data.av }))
|
|
28
|
+
// .mergeMap(bufferedArray => Rx.Observable.from(bufferedArray))
|
|
29
|
+
// )
|
|
30
|
+
;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* MQTT Client
|
|
34
|
+
*/
|
|
35
|
+
this.mqtt = require("async-mqtt");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Starts Broker connections
|
|
40
|
+
* Returns an Obserable that resolves to each connection result
|
|
41
|
+
*/
|
|
42
|
+
start$() {
|
|
43
|
+
return Rx.Observable.create(observer => {
|
|
44
|
+
this.mqttClient = this.mqtt.connect(this.mqttServerUrl);
|
|
45
|
+
observer.next('MQTT broker connecting ...');
|
|
46
|
+
this.mqttClient.on('connect', () => {
|
|
47
|
+
observer.next('MQTT broker connected');
|
|
48
|
+
this.mqttClient.subscribe(this.topicName);
|
|
49
|
+
observer.next(`MQTT broker listening messages`);
|
|
50
|
+
observer.complete();
|
|
51
|
+
});
|
|
52
|
+
this.mqttClient.on('message', (topic, message) => {
|
|
53
|
+
const envelope = JSON.parse(message);
|
|
54
|
+
//console.log(`**************** Received message id: ${envelope.id}`);
|
|
55
|
+
// message is Buffer
|
|
56
|
+
this.incomingEvents$.next(
|
|
57
|
+
{
|
|
58
|
+
id: envelope.id,
|
|
59
|
+
data: envelope.data,
|
|
60
|
+
attributes: envelope.attributes,
|
|
61
|
+
correlationId: envelope.attributes.correlationId
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Disconnect the broker and return an observable that completes when disconnected
|
|
74
|
+
*/
|
|
75
|
+
stop$() {
|
|
76
|
+
return Rx.defer(() => this.mqttClient.end());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Publish data throught the events topic
|
|
82
|
+
* Returns an Observable that resolves to the sent message ID
|
|
83
|
+
* @param {string} topicName
|
|
84
|
+
* @param {Object} data
|
|
85
|
+
*/
|
|
86
|
+
publish$(data) {
|
|
87
|
+
const uuid = uuidv4();
|
|
88
|
+
const dataBuffer = JSON.stringify(
|
|
89
|
+
{
|
|
90
|
+
id: uuid,
|
|
91
|
+
data,
|
|
92
|
+
attributes: {
|
|
93
|
+
senderId: this.senderId
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
return Rx.defer(() => this.mqttClient.publish(`${this.topicName}`, dataBuffer, { qos: 1 }))
|
|
98
|
+
.pipe(mapTo(uuid));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns an Observable that will emit any event related to the given aggregateType
|
|
103
|
+
* @param {string} aggregateType
|
|
104
|
+
*/
|
|
105
|
+
getEventListener$(aggregateType, ignoreSelfEvents = true) {
|
|
106
|
+
return this.orderedIncomingEvents$.pipe(
|
|
107
|
+
filter(msg => msg)
|
|
108
|
+
,filter(msg => !ignoreSelfEvents || msg.attributes.senderId !== this.senderId)
|
|
109
|
+
,map(msg => msg.data)
|
|
110
|
+
,filter(evt => evt.at === aggregateType || aggregateType == "*" )
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = MqttBroker;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Rx = require('rxjs');
|
|
4
|
+
const { filter, map} = require('rxjs/operators');
|
|
5
|
+
// Imports the Google Cloud client library
|
|
6
|
+
const uuidv4 = require('uuid/v4');
|
|
7
|
+
const PubSub = require('@google-cloud/pubsub');
|
|
8
|
+
|
|
9
|
+
class PubSubBroker {
|
|
10
|
+
|
|
11
|
+
constructor({ eventsTopic, eventsTopicSubscription }) {
|
|
12
|
+
//this.projectId = projectId;
|
|
13
|
+
this.eventsTopic = eventsTopic;
|
|
14
|
+
this.eventsTopicSubscription = eventsTopicSubscription;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Rx Subject for every incoming event
|
|
18
|
+
*/
|
|
19
|
+
this.incomingEvents$ = new Rx.BehaviorSubject();
|
|
20
|
+
this.orderedIncomingEvents$ = this.incomingEvents$.pipe(
|
|
21
|
+
filter(msg => msg)
|
|
22
|
+
)
|
|
23
|
+
// .groupBy(msg => msg.data.at)
|
|
24
|
+
// .mergeMap(groupStream =>
|
|
25
|
+
// groupStream.bufferWhen(() => groupStream.debounceTime(250))
|
|
26
|
+
// .filter(bufferedArray => bufferedArray && bufferedArray.length > 0)
|
|
27
|
+
// .map(bufferedArray => bufferedArray.sort((o1, o2) => { return o1.data.av - o2.data.av }))
|
|
28
|
+
// .mergeMap(bufferedArray => Rx.Observable.from(bufferedArray))
|
|
29
|
+
// );
|
|
30
|
+
this.senderId = uuidv4();
|
|
31
|
+
|
|
32
|
+
this.pubsubClient = new PubSub({
|
|
33
|
+
//projectId: projectId,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.topic = this.pubsubClient.topic(eventsTopic);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Starts Broker connections
|
|
41
|
+
* Returns an Obserable that resolves to each connection result
|
|
42
|
+
*/
|
|
43
|
+
start$() {
|
|
44
|
+
return Rx.Observable.create(observer => {
|
|
45
|
+
this.startMessageListener();
|
|
46
|
+
observer.next(`Event Store PubSub Broker listening: Topic=${this.eventsTopic}, subscriptionName=${this.eventsTopicSubscription}`);
|
|
47
|
+
observer.complete();
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Disconnect the broker and return an observable that completes when disconnected
|
|
53
|
+
*/
|
|
54
|
+
stop$() {
|
|
55
|
+
return Rx.Observable.create(observer => {
|
|
56
|
+
this.getSubscription$().subscribe(
|
|
57
|
+
(subscription) => {
|
|
58
|
+
subscription.removeListener(`message`, this.onMessage);
|
|
59
|
+
observer.next(`Event Store PubSub Broker removed listener: Topic=${this.eventsTopic}, subscriptionName=${subscription}`);
|
|
60
|
+
},
|
|
61
|
+
(error) => observer.error(error),
|
|
62
|
+
() => {
|
|
63
|
+
this.messageListenerSubscription.unsubscribe();
|
|
64
|
+
observer.complete();
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Publish data throught the events topic
|
|
74
|
+
* Returns an Observable that resolves to the sent message ID
|
|
75
|
+
* @param {string} topicName
|
|
76
|
+
* @param {Object} data
|
|
77
|
+
*/
|
|
78
|
+
publish$(data) {
|
|
79
|
+
const dataBuffer = Buffer.from(JSON.stringify(data));
|
|
80
|
+
return Rx.defer(() =>
|
|
81
|
+
this.topic.publisher().publish(
|
|
82
|
+
dataBuffer,
|
|
83
|
+
{ senderId: this.senderId }))
|
|
84
|
+
//.do(messageId => console.log(`PubSub Message published through ${this.topic.name}, Message=${JSON.stringify(data)}`))
|
|
85
|
+
;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns an Observable that will emit any event related to the given aggregateType
|
|
90
|
+
* @param {string} aggregateType
|
|
91
|
+
*/
|
|
92
|
+
getEventListener$(aggregateType, ignoreSelfEvents = true) {
|
|
93
|
+
return this.orderedIncomingEvents$.pipe(
|
|
94
|
+
filter(msg => msg)
|
|
95
|
+
,filter(msg => !ignoreSelfEvents || msg.attributes.senderId !== this.senderId)
|
|
96
|
+
,map(msg => msg.data)
|
|
97
|
+
,filter(evt => evt.at === aggregateType || aggregateType == "*")
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns an Observable that resolves to the subscription
|
|
104
|
+
*/
|
|
105
|
+
getSubscription$() {
|
|
106
|
+
return Rx.defer(() =>
|
|
107
|
+
this.topic.subscription(this.eventsTopicSubscription)
|
|
108
|
+
.get({ autoCreate: true })).pipe(
|
|
109
|
+
map(results => results[0])
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Starts to listen messages
|
|
115
|
+
*/
|
|
116
|
+
startMessageListener() {
|
|
117
|
+
this.messageListenerSubscription = this.getSubscription$()
|
|
118
|
+
.subscribe(
|
|
119
|
+
(pubSubSubscription) => {
|
|
120
|
+
this.onMessage = message => {
|
|
121
|
+
message.ack();
|
|
122
|
+
//console.log(`Received message ${message.id}:`);
|
|
123
|
+
this.incomingEvents$.next({
|
|
124
|
+
data: JSON.parse(message.data),
|
|
125
|
+
id: message.id,
|
|
126
|
+
attributes: message.attributes,
|
|
127
|
+
correlationId: message.attributes.correlationId
|
|
128
|
+
});
|
|
129
|
+
//console.log(`Execute ack message ${message.id}:`);
|
|
130
|
+
};
|
|
131
|
+
pubSubSubscription.on(`message`, this.onMessage);
|
|
132
|
+
},
|
|
133
|
+
(err) => {
|
|
134
|
+
console.error('Failed to obtain EventStore subscription', err);
|
|
135
|
+
},
|
|
136
|
+
() => {
|
|
137
|
+
console.log('GatewayEvents listener has completed!');
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = PubSubBroker;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Rx = require('rxjs');
|
|
4
|
+
|
|
5
|
+
class Event {
|
|
6
|
+
constructor({ eventType, eventTypeVersion, aggregateType, aggregateId, data, user, aggregateVersion, ephemeral = false }) {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Event type
|
|
10
|
+
*/
|
|
11
|
+
this.et = eventType;
|
|
12
|
+
/**
|
|
13
|
+
* Event type version
|
|
14
|
+
*/
|
|
15
|
+
this.etv = eventTypeVersion;
|
|
16
|
+
/**
|
|
17
|
+
* Aggregate Type
|
|
18
|
+
*/
|
|
19
|
+
this.at = aggregateType;
|
|
20
|
+
/**
|
|
21
|
+
* Aggregate ID
|
|
22
|
+
*/
|
|
23
|
+
this.aid = aggregateId;
|
|
24
|
+
/**
|
|
25
|
+
* Event data
|
|
26
|
+
*/
|
|
27
|
+
this.data = data;
|
|
28
|
+
/**
|
|
29
|
+
* Responsible user
|
|
30
|
+
*/
|
|
31
|
+
this.user = user;
|
|
32
|
+
/**
|
|
33
|
+
* TimeStamp
|
|
34
|
+
*/
|
|
35
|
+
this.timestamp = (new Date).getTime();
|
|
36
|
+
/**
|
|
37
|
+
* Aggregate version
|
|
38
|
+
*/
|
|
39
|
+
this.av = aggregateVersion;
|
|
40
|
+
/**
|
|
41
|
+
* if ephemeral is true, this event will not be stored
|
|
42
|
+
*/
|
|
43
|
+
this.ephemeral = ephemeral;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = Event;
|