@sera4/essentia 1.1.66-rc.1 → 3.0.8
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 +352 -8
- package/dist/ts/index.d.ts +1 -1
- package/dist/ts/index.js +1 -1
- package/dist/ts/index.js.map +1 -1
- package/dist/ts/logger/s4-logger.js +0 -2
- package/dist/ts/logger/s4-logger.js.map +1 -1
- package/dist/ts/queue/index.d.ts +2 -38
- package/dist/ts/queue/index.js +67 -136
- package/dist/ts/queue/index.js.map +1 -1
- package/package.json +51 -12
- package/package.tar.gz +0 -0
- package/cache/index.js +0 -188
- package/constants/index.js +0 -9
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/configurations/index.html +0 -116
- package/coverage/configurations/server-config.ts.html +0 -94
- package/coverage/dns/DnsCache.ts.html +0 -598
- package/coverage/dns/index.html +0 -131
- package/coverage/dns/index.ts.html +0 -94
- package/coverage/favicon.png +0 -0
- package/coverage/health/index.html +0 -116
- package/coverage/health/index.ts.html +0 -778
- package/coverage/index.html +0 -161
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/configurations/index.html +0 -116
- package/coverage/lcov-report/configurations/server-config.ts.html +0 -94
- package/coverage/lcov-report/dns/DnsCache.ts.html +0 -598
- package/coverage/lcov-report/dns/index.html +0 -131
- package/coverage/lcov-report/dns/index.ts.html +0 -94
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/health/index.html +0 -116
- package/coverage/lcov-report/health/index.ts.html +0 -778
- package/coverage/lcov-report/index.html +0 -161
- package/coverage/lcov-report/logger/index.html +0 -131
- package/coverage/lcov-report/logger/index.ts.html +0 -94
- package/coverage/lcov-report/logger/s4-logger.ts.html +0 -514
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -747
- package/coverage/logger/index.html +0 -131
- package/coverage/logger/index.ts.html +0 -94
- package/coverage/logger/s4-logger.ts.html +0 -514
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/tmp/coverage-24302-1746472691313-0.json +0 -1
- package/coverage/tmp/coverage-24302-1746472691366-1.json +0 -1
- package/dist/cache/index.d.ts +0 -22
- package/dist/cache/index.js +0 -166
- package/dist/cache/index.js.map +0 -1
- package/dist/constants/index.d.ts +0 -6
- package/dist/constants/index.js +0 -9
- package/dist/constants/index.js.map +0 -1
- package/dist/coverage/block-navigation.d.ts +0 -1
- package/dist/coverage/block-navigation.js +0 -70
- package/dist/coverage/block-navigation.js.map +0 -1
- package/dist/coverage/lcov-report/block-navigation.d.ts +0 -1
- package/dist/coverage/lcov-report/block-navigation.js +0 -70
- package/dist/coverage/lcov-report/block-navigation.js.map +0 -1
- package/dist/coverage/lcov-report/prettify.d.ts +0 -0
- package/dist/coverage/lcov-report/prettify.js +0 -477
- package/dist/coverage/lcov-report/prettify.js.map +0 -1
- package/dist/coverage/lcov-report/sorter.d.ts +0 -1
- package/dist/coverage/lcov-report/sorter.js +0 -163
- package/dist/coverage/lcov-report/sorter.js.map +0 -1
- package/dist/coverage/prettify.d.ts +0 -0
- package/dist/coverage/prettify.js +0 -477
- package/dist/coverage/prettify.js.map +0 -1
- package/dist/coverage/sorter.d.ts +0 -1
- package/dist/coverage/sorter.js +0 -163
- package/dist/coverage/sorter.js.map +0 -1
- package/dist/formatter/index.d.ts +0 -37
- package/dist/formatter/index.js +0 -75
- package/dist/formatter/index.js.map +0 -1
- package/dist/hal/index.d.ts +0 -5
- package/dist/hal/index.js +0 -69
- package/dist/hal/index.js.map +0 -1
- package/dist/health/health-logger.d.ts +0 -9
- package/dist/health/health-logger.js +0 -34
- package/dist/health/health-logger.js.map +0 -1
- package/dist/health/index.d.ts +0 -19
- package/dist/health/index.js +0 -175
- package/dist/health/index.js.map +0 -1
- package/dist/helpers/index.d.ts +0 -1
- package/dist/helpers/index.js +0 -2
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/test-server-wrapper.d.ts +0 -120
- package/dist/helpers/test-server-wrapper.js +0 -165
- package/dist/helpers/test-server-wrapper.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +0 -1
- package/dist/last-commit.d.ts +0 -1
- package/dist/last-commit.js +0 -12
- package/dist/last-commit.js.map +0 -1
- package/dist/last_commit/index.d.ts +0 -7
- package/dist/last_commit/index.js +0 -83
- package/dist/last_commit/index.js.map +0 -1
- package/dist/paginator/s4-pagination.d.ts +0 -9
- package/dist/paginator/s4-pagination.js +0 -49
- package/dist/paginator/s4-pagination.js.map +0 -1
- package/dist/paginator/sql-pagination.d.ts +0 -27
- package/dist/paginator/sql-pagination.js +0 -166
- package/dist/paginator/sql-pagination.js.map +0 -1
- package/dist/paper-trail/helpers.d.ts +0 -11
- package/dist/paper-trail/helpers.js +0 -74
- package/dist/paper-trail/helpers.js.map +0 -1
- package/dist/paper-trail/index.d.ts +0 -13
- package/dist/paper-trail/index.js +0 -662
- package/dist/paper-trail/index.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -14
- package/dist/prompts/index.js +0 -63
- package/dist/prompts/index.js.map +0 -1
- package/dist/queue/index.d.ts +0 -166
- package/dist/queue/index.js +0 -371
- package/dist/queue/index.js.map +0 -1
- package/dist/queue/publisher.d.ts +0 -31
- package/dist/queue/publisher.js +0 -84
- package/dist/queue/publisher.js.map +0 -1
- package/dist/queue/queue-logger.d.ts +0 -9
- package/dist/queue/queue-logger.js +0 -35
- package/dist/queue/queue-logger.js.map +0 -1
- package/dist/queue/subscriber.d.ts +0 -39
- package/dist/queue/subscriber.js +0 -97
- package/dist/queue/subscriber.js.map +0 -1
- package/dist/safe_proxy/index.d.ts +0 -13
- package/dist/safe_proxy/index.js +0 -54
- package/dist/safe_proxy/index.js.map +0 -1
- package/dist/serializer/index.d.ts +0 -5
- package/dist/serializer/index.js +0 -83
- package/dist/serializer/index.js.map +0 -1
- package/dist/test/debug-array.d.ts +0 -0
- package/dist/test/debug-array.js +0 -1
- package/dist/test/debug-array.js.map +0 -1
- package/dist/test/debug-setJSONB.d.ts +0 -0
- package/dist/test/debug-setJSONB.js +0 -1
- package/dist/test/debug-setJSONB.js.map +0 -1
- package/dist/test/prompt.test.d.ts +0 -1
- package/dist/test/prompt.test.js +0 -74
- package/dist/test/prompt.test.js.map +0 -1
- package/dist/test/s4-formatter.spec.d.ts +0 -1
- package/dist/test/s4-formatter.spec.js +0 -67
- package/dist/test/s4-formatter.spec.js.map +0 -1
- package/dist/test/s4-pagination.spec.d.ts +0 -1
- package/dist/test/s4-pagination.spec.js +0 -170
- package/dist/test/s4-pagination.spec.js.map +0 -1
- package/dist/test/safe-proxy.spec.d.ts +0 -1
- package/dist/test/safe-proxy.spec.js +0 -252
- package/dist/test/safe-proxy.spec.js.map +0 -1
- package/dist/test/serializer.spec.d.ts +0 -1
- package/dist/test/serializer.spec.js +0 -27
- package/dist/test/serializer.spec.js.map +0 -1
- package/dist/test/utils.spec.d.ts +0 -1
- package/dist/test/utils.spec.js +0 -446
- package/dist/test/utils.spec.js.map +0 -1
- package/dist/ts/task-scheduler/index.d.ts +0 -130
- package/dist/ts/task-scheduler/index.js +0 -259
- package/dist/ts/task-scheduler/index.js.map +0 -1
- package/formatter/index.js +0 -81
- package/hal/README.md +0 -54
- package/hal/index.js +0 -75
- package/health/health-logger.js +0 -40
- package/health/index.js +0 -188
- package/helpers/index.js +0 -1
- package/helpers/test-server-wrapper.js +0 -196
- package/last-commit.js +0 -12
- package/last_commit/index.js +0 -82
- package/logger/s4-logger.js +0 -128
- package/paginator/README.md +0 -183
- package/paginator/s4-pagination.js +0 -51
- package/paginator/sql-pagination.js +0 -178
- package/paper-trail/README.md +0 -68
- package/paper-trail/helpers.js +0 -99
- package/paper-trail/index.js +0 -843
- package/prompts/index.js +0 -78
- package/queue/index.js +0 -402
- package/queue/publisher.js +0 -96
- package/queue/queue-logger.js +0 -40
- package/queue/subscriber.js +0 -107
- package/safe_proxy/index.js +0 -61
- package/scripts/publish.sh +0 -46
- package/serializer/index.js +0 -90
- package/test/health.spec.js +0 -213
- package/test/prompt.test.js +0 -91
- package/test/s4-formatter.spec.js +0 -80
- package/test/s4-pagination.spec.js +0 -196
- package/test/serializer.spec.js +0 -34
- package/test/utils.spec.js +0 -145
- package/utils/index.js +0 -74
package/prompts/index.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/* Essentia Common Prompt Functions */
|
|
2
|
-
// This file contains common prompt functions that are used in CLI scripts
|
|
3
|
-
// that are run in the each project. These functions are used to
|
|
4
|
-
// prompt the user for input and to wait for the user to press enter
|
|
5
|
-
// before continuing. This is useful for scripts that are run in the
|
|
6
|
-
// command line and need to wait for the user to do something before
|
|
7
|
-
// continuing.
|
|
8
|
-
|
|
9
|
-
import logger from "../logger/s4-logger.js";
|
|
10
|
-
import { ArgumentParser } from 'argparse'
|
|
11
|
-
import prompt from "prompt";
|
|
12
|
-
|
|
13
|
-
// New common argument parser which makes parsing and setting up commandline options easier
|
|
14
|
-
const setupCLIParser = (description) => {
|
|
15
|
-
logger.info(description)
|
|
16
|
-
return new ArgumentParser({ description });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// a common init function which waits for the command prompt to be delivered
|
|
20
|
-
// a common use is for the awaiting of the queues to initialize before running
|
|
21
|
-
const commonCLIInit = async(options) => {
|
|
22
|
-
//add in defaults to options if they have not been specified or object is {}
|
|
23
|
-
options = { asyncFcns: [], extraFcns: [], sleepTime: 1000, ...options };
|
|
24
|
-
|
|
25
|
-
// Sleep for 1 second to allow the prompt to be displayed
|
|
26
|
-
// at the end of bootstrap logs
|
|
27
|
-
await cliSleep(options.sleepTime);
|
|
28
|
-
|
|
29
|
-
options.extraFcns.forEach(fcn => {
|
|
30
|
-
fcn();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
for (const fcn of options.asyncFcns) {
|
|
34
|
-
await fcn();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const promptCLIAsync = async (options) => {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
prompt.start();
|
|
41
|
-
prompt.get(options, (err, res) => {
|
|
42
|
-
if (err) {
|
|
43
|
-
reject(err);
|
|
44
|
-
} else {
|
|
45
|
-
resolve(res);
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// A predefined waitPrompt for use at the end of the scripts that use
|
|
52
|
-
// message queues. Message Queues often take a bit to fire
|
|
53
|
-
const waitCLIPrompt = {
|
|
54
|
-
"Push <enter> when done" : {
|
|
55
|
-
type: "boolean"
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const continueCLIPrompt = {
|
|
60
|
-
"Push <enter> to continue" : {
|
|
61
|
-
type: "boolean"
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const cliSleep = async(ms) => {
|
|
66
|
-
return new Promise((resolve) => {
|
|
67
|
-
setTimeout(resolve, ms);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export {
|
|
72
|
-
commonCLIInit,
|
|
73
|
-
continueCLIPrompt,
|
|
74
|
-
promptCLIAsync,
|
|
75
|
-
setupCLIParser,
|
|
76
|
-
cliSleep,
|
|
77
|
-
waitCLIPrompt
|
|
78
|
-
};
|
package/queue/index.js
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import amqp from "amqplib";
|
|
3
|
-
import logger from "./queue-logger.js";
|
|
4
|
-
import urlParse from "url-parse";
|
|
5
|
-
import { Publisher } from "./publisher.js";
|
|
6
|
-
import { Subscriber } from "./subscriber.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* An interface to AMQP service
|
|
10
|
-
*/
|
|
11
|
-
class S4Queue {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.connection = null;
|
|
14
|
-
this.connectionTestChannel = null;
|
|
15
|
-
this.retry = 10;
|
|
16
|
-
this.pubs = {};
|
|
17
|
-
this.subs = {};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Tests the connection to the service.
|
|
22
|
-
* Internally, the same connection is used for test
|
|
23
|
-
* and production code, but a separate channel is opened.
|
|
24
|
-
* Once the channel is obtained, there is an assert on the
|
|
25
|
-
* existence of a topic exchange called '--health-check--'.
|
|
26
|
-
* The following must be satisfied for the test to pass
|
|
27
|
-
* 1. must be connected
|
|
28
|
-
* 2. must have a test channel
|
|
29
|
-
* 3. must assert the exchange
|
|
30
|
-
*/
|
|
31
|
-
async testConnection() {
|
|
32
|
-
if (!this.isConnected()) {
|
|
33
|
-
this.connectionTestChannel = null;
|
|
34
|
-
throw new Error("queue service not connected");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!this.connectionTestChannel) {
|
|
38
|
-
const ch = await this.connection.createChannel();
|
|
39
|
-
if (!ch) {
|
|
40
|
-
throw new Error("queue service failed to obtain a channel");
|
|
41
|
-
}
|
|
42
|
-
ch.on("error", () => { this.connectionTestChannel = null; });
|
|
43
|
-
ch.on("close", () => { this.connectionTestChannel = null; });
|
|
44
|
-
this.connectionTestChannel = ch;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
await this.connectionTestChannel.assertExchange("--health-check--", "topic", { durable: false });
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Opens a connection to AMQP server.
|
|
52
|
-
* @param {Object} options Connection parameters. At the very least options.connectionUrl must be present.
|
|
53
|
-
*/
|
|
54
|
-
async openConnection(options) {
|
|
55
|
-
logger.setEnabled(options.logEnabled);
|
|
56
|
-
|
|
57
|
-
if (this.connection) {
|
|
58
|
-
logger.warn("Already initialized");
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const retry = parseInt(options.retryInterval);
|
|
63
|
-
this.retry = retry || 10;
|
|
64
|
-
|
|
65
|
-
// We may run into issues with SNI TLS if
|
|
66
|
-
// we host with 3rd parties using our own certs.
|
|
67
|
-
// To avoid any issues, let's parse the url
|
|
68
|
-
// and provide the server name in the socket options
|
|
69
|
-
const urlParts = urlParse(options.connectionUrl);
|
|
70
|
-
const socketOptions = { servername: urlParts.hostname };
|
|
71
|
-
|
|
72
|
-
return new Promise((resolve) => {
|
|
73
|
-
const attempt = async () => {
|
|
74
|
-
logger.debug("Attempting connection...");
|
|
75
|
-
try {
|
|
76
|
-
const conn = await amqp.connect(options.connectionUrl, socketOptions);
|
|
77
|
-
|
|
78
|
-
this.connection = conn;
|
|
79
|
-
this.updatePubsAndSubsConnectionRef(conn);
|
|
80
|
-
|
|
81
|
-
this.connection.on("error", (err) => {
|
|
82
|
-
logger.error("connection error", err);
|
|
83
|
-
// Do not attempt to reconnect as the
|
|
84
|
-
// 'close' event will also be emitted
|
|
85
|
-
// if this error closes the connection
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
this.connection.on("close", (err) => {
|
|
89
|
-
logger.error("connection closed");
|
|
90
|
-
this.connection = null;
|
|
91
|
-
this.connectionTestChannel = null;
|
|
92
|
-
if (err) {
|
|
93
|
-
logger.error("connection closed due to error:", err);
|
|
94
|
-
logger.error("Reconnecting in", this.retry, "seconds");
|
|
95
|
-
setTimeout(attempt, this.retry * 1000);
|
|
96
|
-
} else {
|
|
97
|
-
logger.debug("Will not re-attempt");
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
logger.debug("Connected");
|
|
102
|
-
resolve();
|
|
103
|
-
} catch (err) {
|
|
104
|
-
logger.error("Error while connecting", err);
|
|
105
|
-
logger.error("Attempting again in", this.retry, "seconds");
|
|
106
|
-
setTimeout(attempt, this.retry * 1000);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
attempt();
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Closes the connection to AMQP server
|
|
115
|
-
* and clears the registered publishers
|
|
116
|
-
* and subscribers
|
|
117
|
-
*/
|
|
118
|
-
async closeConnection() {
|
|
119
|
-
if (!this.connection) return;
|
|
120
|
-
await this.connection.close();
|
|
121
|
-
this.subs = {};
|
|
122
|
-
this.pubs = {};
|
|
123
|
-
this.connectionTestChannel = null;
|
|
124
|
-
this.connection = null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Returns whether we have an active connection
|
|
129
|
-
* or not.
|
|
130
|
-
*/
|
|
131
|
-
isConnected() {
|
|
132
|
-
return this.connection != null && typeof(this.connection) != 'undefined';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* @deprecated Use registerPublisher
|
|
137
|
-
* Registers a new direct publisher on the given exchange.
|
|
138
|
-
* If exchange doesn't exist, one will be created.
|
|
139
|
-
* @param {String} exchange the name of the exchange on AMQP service.
|
|
140
|
-
*/
|
|
141
|
-
async registerDirectPublisher(exchange) {
|
|
142
|
-
return this.registerPublisher({exchange: {name: exchange, type: "direct"}});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* @deprecated Use registerPublisher
|
|
147
|
-
* Registers a new topic publisher on the given exchange.
|
|
148
|
-
* If exchange doesn't exist, one will be created.
|
|
149
|
-
* @param {String} exchange the name of the exchange on AMQP service.
|
|
150
|
-
*/
|
|
151
|
-
async registerTopicPublisher(exchange) {
|
|
152
|
-
return this.registerPublisher({exchange: {name: exchange, type: "topic"}});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @deprecated Use registerPublisher
|
|
157
|
-
* Registers a new fanout publisher on the given exchange.
|
|
158
|
-
* If exchange doesn't exist, one will be created.
|
|
159
|
-
* @param {String} exchange the name of the exchange on AMQP service.
|
|
160
|
-
*/
|
|
161
|
-
async registerFanoutPublisher(exchange) {
|
|
162
|
-
return this.registerPublisher({exchange: {name: exchange, type: "fanout"}});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Registers a new publisher
|
|
167
|
-
* @param {Object} options connection options.
|
|
168
|
-
*/
|
|
169
|
-
async registerPublisher(options) {
|
|
170
|
-
const { exchange } = options;
|
|
171
|
-
const { name } = exchange;
|
|
172
|
-
if (Object.keys(this.pubs).includes(name)) {
|
|
173
|
-
throw new Error(`Publisher ${name} already registered`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const p = new Publisher(exchange, name);
|
|
177
|
-
await p.init(this.connection);
|
|
178
|
-
this.pubs[name] = p;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Checks whether or not a publisher with given parameters
|
|
183
|
-
* has been registered already
|
|
184
|
-
* @param {String} exchange the name of the exchange.
|
|
185
|
-
* @returns true if registered already, false otherwise
|
|
186
|
-
*/
|
|
187
|
-
hasPublisher(exchange) {
|
|
188
|
-
return Object.keys(this.pubs).includes(exchange);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Removes a previously registered publisher
|
|
193
|
-
* @param {Object} options
|
|
194
|
-
*/
|
|
195
|
-
async unregisterPublisher(options) {
|
|
196
|
-
const { exchange } = options;
|
|
197
|
-
const { name } = exchange;
|
|
198
|
-
if (!Object.keys(this.pubs).includes(name)) {
|
|
199
|
-
throw new Error(`Publisher ${name} not registered`);
|
|
200
|
-
}
|
|
201
|
-
const p = this.pubs[name];
|
|
202
|
-
await p.closeChannel();
|
|
203
|
-
|
|
204
|
-
delete this.pubs[name];
|
|
205
|
-
logger.debug("Unregistered publisher", name);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* @deprecated Use registerSubscriber
|
|
210
|
-
* Registers a new direct subscriber on a given exchange and queue.
|
|
211
|
-
* If exchange and queue don't exists, they'll be created
|
|
212
|
-
* and bound through the provided routing key.
|
|
213
|
-
* @param {String} exchange the name of the exchange.
|
|
214
|
-
* @param {String} queue the name of the queue.
|
|
215
|
-
* @param {String} key the name of the routing key.
|
|
216
|
-
*/
|
|
217
|
-
async registerDirectSubscriber(exchange, queue, key) {
|
|
218
|
-
const options = {
|
|
219
|
-
key,
|
|
220
|
-
exchange: { name: exchange, type: "direct" },
|
|
221
|
-
queue: { name: queue }
|
|
222
|
-
}
|
|
223
|
-
return this.registerSubscriber(options);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* @deprecated Use registerSubscriber
|
|
228
|
-
* Registers a new topic subscriber on a given exchange and queue.
|
|
229
|
-
* If exchange and queue don't exists, they'll be created
|
|
230
|
-
* and bound through the provided routing key.
|
|
231
|
-
* @param {String} exchange the name of the exchange.
|
|
232
|
-
* @param {String} queue the name of the queue.
|
|
233
|
-
* @param {String} key the name of the routing key.
|
|
234
|
-
*/
|
|
235
|
-
async registerTopicSubscriber(exchange, queue, key) {
|
|
236
|
-
const options = {
|
|
237
|
-
key,
|
|
238
|
-
exchange: { name: exchange, type: "topic" },
|
|
239
|
-
queue: { name: queue }
|
|
240
|
-
}
|
|
241
|
-
return this.registerSubscriber(options);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* An overloaded version of registering a subscriber
|
|
246
|
-
* allowing for more fine tuned parameters
|
|
247
|
-
* @param {Object} options subscribing options
|
|
248
|
-
*/
|
|
249
|
-
async registerSubscriber(options) {
|
|
250
|
-
const {exchange, queue, key} = options;
|
|
251
|
-
const name = `${exchange.name}-${queue.name}-${key}`;
|
|
252
|
-
|
|
253
|
-
if (Object.keys(this.subs).includes(name)) {
|
|
254
|
-
throw new Error(`Subscriber ${name} already registered`);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const s = new Subscriber(exchange, queue, key, name);
|
|
258
|
-
await s.init(this.connection);
|
|
259
|
-
this.subs[name] = s;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Checks whether or not a subscriber with given parameters
|
|
264
|
-
* has been registered already
|
|
265
|
-
* @param {String} exchange the name of the exchange.
|
|
266
|
-
* @param {String} queue the name of the queue.
|
|
267
|
-
* @param {String} key the name of the routing key.
|
|
268
|
-
* @returns true if registered already, false otherwise
|
|
269
|
-
*/
|
|
270
|
-
hasSubscriber(exchange, queue, key) {
|
|
271
|
-
const name = `${exchange}-${queue}-${key}`;
|
|
272
|
-
return Object.keys(this.subs).includes(name);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Removes a previously registered subscriber
|
|
277
|
-
* @param {OBject} options
|
|
278
|
-
*/
|
|
279
|
-
async unregisterSubscriber(options) {
|
|
280
|
-
const {exchange, queue, key} = options;
|
|
281
|
-
const name = `${exchange.name}-${queue.name}-${key}`;
|
|
282
|
-
|
|
283
|
-
if (!Object.keys(this.subs).includes(name)) {
|
|
284
|
-
throw new Error(`Subscriber ${name} not registered`);
|
|
285
|
-
}
|
|
286
|
-
const s = this.subs[name];
|
|
287
|
-
await s.closeChannel();
|
|
288
|
-
|
|
289
|
-
delete this.subs[name];
|
|
290
|
-
logger.debug("Unregistered subscriber", name);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Publishes a message on a given exchange with routing key.
|
|
295
|
-
* @param {String} exchange the name of the exchange.
|
|
296
|
-
* @param {String} key the name of the routing key.
|
|
297
|
-
* @param {Object} msg a JSON object as the message.
|
|
298
|
-
*/
|
|
299
|
-
async publishDirectMessage(exchange, key, msg) {
|
|
300
|
-
return this.publishMessage(exchange, key, msg)
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Publishes a message on a given exchange with a topic.
|
|
305
|
-
* @param {String} exchange the name of the exchange.
|
|
306
|
-
* @param {String} topic the name of the topic.
|
|
307
|
-
* @param {Object} msg a JSON object as the message.
|
|
308
|
-
*/
|
|
309
|
-
async publishTopicMessage(exchange, topic, msg) {
|
|
310
|
-
return this.publishMessage(exchange, topic, msg)
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Publish a message to the exchange
|
|
315
|
-
* @param {String} exchange name of exchange
|
|
316
|
-
* @param {String} key name of the key or topic
|
|
317
|
-
* @param {Object} msg payload to be published
|
|
318
|
-
*/
|
|
319
|
-
async publishMessage(exchange, key, msg) {
|
|
320
|
-
if (!key) {
|
|
321
|
-
throw(new Error(`Key argument not defined`));
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const p = this.pubs[exchange];
|
|
325
|
-
if (!p) {
|
|
326
|
-
throw(new Error(`No PUB for ${exchange} found`));
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
let content = msg;
|
|
330
|
-
if (content.constructor !== ({}).constructor) {
|
|
331
|
-
// if not in JSON format, let's make it so
|
|
332
|
-
content = {
|
|
333
|
-
msg: msg
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
return await p.publish({key, content});
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Binds an exchange to a queue
|
|
342
|
-
* @param {String} exchange the name of the exchange.
|
|
343
|
-
* @param {String} queue the name of the queue.
|
|
344
|
-
* @param {pattern} (optional) pattern for routing key
|
|
345
|
-
*/
|
|
346
|
-
async bindQueueToExchange(exchange, queue, pattern) {
|
|
347
|
-
const p = this.pubs[exchange];
|
|
348
|
-
|
|
349
|
-
if (!p) {
|
|
350
|
-
throw(new Error(`No PUB for ${exchange} found`));
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (!queue) {
|
|
354
|
-
throw(new Error(`Binding a queue requires a queue name`));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return await p.bindQueue(queue, pattern)
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Adds a listener for a specific key.
|
|
362
|
-
* If a subscriber that was regitered was found
|
|
363
|
-
* with that key, the listener is added, otherwise
|
|
364
|
-
* it's ignored
|
|
365
|
-
* @param {*} key AMQP routing key
|
|
366
|
-
* @param {*} listener callback
|
|
367
|
-
*/
|
|
368
|
-
addMessageListener(key, listener) {
|
|
369
|
-
Object.keys(this.subs).forEach(k => {
|
|
370
|
-
const s = this.subs[k];
|
|
371
|
-
if (s.key === key) {
|
|
372
|
-
s.registerCallback(listener);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Updates the connection reference to all the previously
|
|
379
|
-
* registered publishers and subscribers.
|
|
380
|
-
* After we successfully establish a connection and register pubs/subs,
|
|
381
|
-
* it's possible for the connection to break. This object will try
|
|
382
|
-
* to re-establish a new connection every 3 seconds (or whatever configuration is set)
|
|
383
|
-
* and if a new connection is established, we need to pass that connection to
|
|
384
|
-
* all our pubs/subs, otherwise they'll be operating with old/stale references
|
|
385
|
-
* @param {Object} connRef a new connection reference to the AMQP service
|
|
386
|
-
*/
|
|
387
|
-
updatePubsAndSubsConnectionRef(connRef) {
|
|
388
|
-
Object.keys(this.pubs).forEach(k => {
|
|
389
|
-
logger.debug(`Updating publisher ${k} with a new connection object`);
|
|
390
|
-
const p = this.pubs[k];
|
|
391
|
-
p.init(connRef);
|
|
392
|
-
});
|
|
393
|
-
Object.keys(this.subs).forEach(k => {
|
|
394
|
-
logger.debug(`Updating subscriber ${k} with a new connection object`);
|
|
395
|
-
const s = this.subs[k];
|
|
396
|
-
s.init(connRef);
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const queue = new S4Queue();
|
|
402
|
-
export default queue;
|
package/queue/publisher.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import logger from "./queue-logger.js";
|
|
2
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A publisher for AMQP service
|
|
6
|
-
*/
|
|
7
|
-
export class Publisher {
|
|
8
|
-
/**
|
|
9
|
-
* @param {Object} exchange AMQP exchange name.
|
|
10
|
-
* @param {String} name a name to identify this publisher in the logs.
|
|
11
|
-
*/
|
|
12
|
-
constructor(exchange, name) {
|
|
13
|
-
this.exchange = exchange;
|
|
14
|
-
this.name = name;
|
|
15
|
-
this.channel = null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Initializes this publisher with a connection
|
|
20
|
-
* and asserts the exchange exists
|
|
21
|
-
* @param {Object} conn amqp connection object
|
|
22
|
-
*/
|
|
23
|
-
async init (conn) {
|
|
24
|
-
logger.debug(`Initializing PUB channel for ${this.name}`);
|
|
25
|
-
|
|
26
|
-
if(this.channel) {
|
|
27
|
-
logger.warn(`PUB channel for ${this.name} already initialized`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
this.channel = await conn.createConfirmChannel();
|
|
32
|
-
if (!this.channel) {
|
|
33
|
-
throw(new Error(`Cannot create PUB channel for ${this.name}`));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
logger.debug(`Initialized PUB channel for ${this.name}`);
|
|
37
|
-
const {name, type, options} = this.exchange;
|
|
38
|
-
await this.channel.assertExchange(name, type, options);
|
|
39
|
-
|
|
40
|
-
this.channel.on("error", (err) => {
|
|
41
|
-
logger.debug(`Connection error for ${this.name}`, err);
|
|
42
|
-
this.channel = null;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
this.channel.on("close", () => {
|
|
46
|
-
logger.debug(`Connection closed for ${this.name}`);
|
|
47
|
-
this.channel = null;
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Publishes a message to AMQP
|
|
53
|
-
* @param {Object} msg A json object to be published to AMQP.
|
|
54
|
-
* A tracking uuid for the message will be returned.
|
|
55
|
-
*/
|
|
56
|
-
async publish(msg) {
|
|
57
|
-
if (!this.channel) {
|
|
58
|
-
throw(new Error(`No channel for ${this.name} to publish`));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const parcel = {
|
|
62
|
-
tracking_id: uuidv4(),
|
|
63
|
-
timestamp: new Date(),
|
|
64
|
-
data: msg.content
|
|
65
|
-
}
|
|
66
|
-
logger.debug("Publishing message");
|
|
67
|
-
logger.debug("Key", msg.key);
|
|
68
|
-
logger.debug("Data", parcel);
|
|
69
|
-
|
|
70
|
-
const content = Buffer.from(JSON.stringify(parcel));
|
|
71
|
-
const res = await this.channel.publish(this.exchange.name, msg.key, content, {persistent: true});
|
|
72
|
-
|
|
73
|
-
if (!res) {
|
|
74
|
-
throw(new Error("Channel write buffer is full"));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return parcel.tracking_id;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Closes the channel
|
|
82
|
-
* @returns promise
|
|
83
|
-
*/
|
|
84
|
-
async closeChannel() {
|
|
85
|
-
if (this.channel) {
|
|
86
|
-
logger.debug("Closing publishing channel", this.name);
|
|
87
|
-
return this.channel.close();
|
|
88
|
-
} else {
|
|
89
|
-
logger.error("Can't close a null publishing channel");
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async bindQueue(queue, pattern, args) {
|
|
94
|
-
await this.channel.bindQueue(queue, this.exchange, pattern, args)
|
|
95
|
-
}
|
|
96
|
-
}
|
package/queue/queue-logger.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import logger from "../logger/s4-logger.js";
|
|
2
|
-
let enabled = false;
|
|
3
|
-
|
|
4
|
-
const helpers = {
|
|
5
|
-
debug(...args) {
|
|
6
|
-
if (enabled) {
|
|
7
|
-
logger.debug(":: AMQP ::", args);
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
|
|
11
|
-
log(...args) {
|
|
12
|
-
if (enabled) {
|
|
13
|
-
logger.debug(":: AMQP ::", args);
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
warn(...args) {
|
|
18
|
-
if (enabled) {
|
|
19
|
-
logger.warn(":: AMQP ::", args);
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
info(...args) {
|
|
24
|
-
if (enabled) {
|
|
25
|
-
logger.info(":: AMQP ::", args);
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
error(...args) {
|
|
30
|
-
if (enabled) {
|
|
31
|
-
logger.error(":: AMQP ::", args);
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
setEnabled(e) {
|
|
36
|
-
enabled = e;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default helpers;
|