@sera4/essentia 1.0.25 → 1.0.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sera4/essentia",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "A library of utilities for Teleporte Web Services",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,6 +29,7 @@
29
29
  "async": "^2.6.1",
30
30
  "fast-safe-stringify": "^2.0.6",
31
31
  "git-rev": "^0.2.1",
32
+ "url-parse": "^1.4.7",
32
33
  "uuid": "^3.3.3",
33
34
  "winston": "^3.2.1",
34
35
  "winston-logstash": "^0.4.0"
package/package.tar.gz CHANGED
Binary file
package/queue/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  const amqp = require("amqplib/callback_api");
3
3
  const logger = require("./queue-logger");
4
+ const urlParse = require("url-parse");
4
5
  const { Publisher } = require("./publisher");
5
6
  const { Subscriber } = require("./subscriber");
6
7
 
@@ -37,7 +38,14 @@ class S4Queue {
37
38
  // when a callback isn't provided, therefore run
38
39
  // in a new Promise
39
40
  return new Promise((resolve, reject) => {
40
- amqp.connect(options.connectionUrl, (err, conn) => {
41
+ // We may run into issues with SNI TLS if
42
+ // we host with 3rd parties using our own certs.
43
+ // To avoid any issues, let's parse the url
44
+ // and provide the server name in the socket options
45
+ const urlParts = urlParse(options.connectionUrl);
46
+ const socketOptions = {servername: urlParts.hostname};
47
+
48
+ amqp.connect(options.connectionUrl, socketOptions, (err, conn) => {
41
49
 
42
50
  if (err) {
43
51
  return reject(err);
@@ -123,6 +131,22 @@ class S4Queue {
123
131
  this.pubs[name] = p;
124
132
  }
125
133
 
134
+ /**
135
+ * Registers a new topic publisher on the given exchange.
136
+ * If exchange doesn't exist, one will be created.
137
+ * @param {String} exchange the name of the exchange on AMQP service.
138
+ */
139
+ async registerTopicPublisher(exchange) {
140
+ const name = exchange;
141
+ if (Object.keys(this.pubs).includes(name)) {
142
+ throw new Error(`Publisher ${name} already registered`);
143
+ }
144
+
145
+ const p = new Publisher(exchange, 'topic', true, name);
146
+ await p.init(this.connection);
147
+ this.pubs[name] = p;
148
+ }
149
+
126
150
  /**
127
151
  * Registers a new direct subscriber on a given exchange and queue.
128
152
  * If exchange and queue don't exists, they'll be created
@@ -152,15 +176,15 @@ class S4Queue {
152
176
  const p = this.pubs[exchange];
153
177
 
154
178
  if (!key) {
155
- reject(new Error(`Direct message require a key`));
179
+ throw(new Error(`Direct message require a key`));
156
180
  }
157
181
 
158
182
  if (!p) {
159
- reject(new Error(`No PUB for ${exchange} found`));
183
+ throw(new Error(`No PUB for ${exchange} found`));
160
184
  }
161
185
 
162
186
  if (p.type !== 'direct') {
163
- reject(new Error(`PUB ${exchange} is not direct`));
187
+ throw(new Error(`PUB ${exchange} is not direct`));
164
188
  }
165
189
 
166
190
  let content = msg;
@@ -174,6 +198,38 @@ class S4Queue {
174
198
  return await p.publish({key, content});
175
199
  }
176
200
 
201
+ /**
202
+ * Publishes a message on a given exchange with a topic.
203
+ * @param {String} exchange the name of the exchange.
204
+ * @param {String} topic the name of the topic.
205
+ * @param {Object} msg a JSON object as the message.
206
+ */
207
+ async publishTopicMessage(exchange, topic, msg) {
208
+ const p = this.pubs[exchange];
209
+
210
+ if (!topic) {
211
+ throw(new Error(`Topic message require a topic`));
212
+ }
213
+
214
+ if (!p) {
215
+ throw(new Error(`No PUB for ${exchange} found`));
216
+ }
217
+
218
+ if (p.type !== 'topic') {
219
+ throw(new Error(`PUB ${exchange} is not topic`));
220
+ }
221
+
222
+ let content = msg;
223
+ if (content.constructor !== ({}).constructor) {
224
+ // if not in JSON format, let's make it so
225
+ content = {
226
+ msg: msg
227
+ }
228
+ }
229
+
230
+ return await p.publish({key: topic, content});
231
+ }
232
+
177
233
  /**
178
234
  * Adds a listener for a specific key.
179
235
  * If a subscriber that was regitered was found
@@ -27,7 +27,7 @@ class Publisher {
27
27
  * @param {Object} conn amqp connection object
28
28
  */
29
29
  async init (conn) {
30
- logger.debug(`Initializing PUB channel for ${this.name}`);
30
+ logger.debug(`Initializing PUB channel for ${this.name}. Type: ${this.type}`);
31
31
 
32
32
  if(this.channel) {
33
33
  logger.warn(`PUB channel for ${this.name} already initialized`);
@@ -67,7 +67,9 @@ class Publisher {
67
67
  tracking_id: uuidv4(),
68
68
  data: msg.content
69
69
  }
70
- logger.debug("Publishing message", parcel);
70
+ logger.debug("Publishing message");
71
+ logger.debug("Key", msg.key);
72
+ logger.debug("Data", parcel);
71
73
 
72
74
  const content = Buffer.from(JSON.stringify(parcel));
73
75
  const res = await this.channel.publish(this.exchange, msg.key, content, {persistent: true});