rascal 14.0.1 → 14.1.0
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/CHANGELOG.md +4 -0
- package/README.md +9 -0
- package/lib/amqp/Broker.js +10 -8
- package/lib/amqp/Vhost.js +4 -4
- package/lib/amqp/tasks/assertVhost.js +3 -1
- package/lib/amqp/tasks/checkVhost.js +3 -1
- package/lib/amqp/tasks/deleteVhost.js +2 -1
- package/lib/amqp/tasks/initVhosts.js +3 -3
- package/lib/management/Client.js +55 -0
- package/package.json +2 -1
- package/lib/management/client.js +0 -54
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -483,6 +483,15 @@ Rascal uses [superagent](https://github.com/visionmedia/superagent) under the ho
|
|
|
483
483
|
}
|
|
484
484
|
```
|
|
485
485
|
|
|
486
|
+
You can also supply your own agent via the broker components. Use this when you need to set [TLS options](https://visionmedia.github.io/superagent/#tls-options).
|
|
487
|
+
|
|
488
|
+
```js
|
|
489
|
+
const superagent = require('superagent-defaults');
|
|
490
|
+
const agent = superagent().on('request', (req) => console.log(req.url));
|
|
491
|
+
const components = { agent };
|
|
492
|
+
const broker = await Broker.create(config, components);
|
|
493
|
+
```
|
|
494
|
+
|
|
486
495
|
#### assert
|
|
487
496
|
|
|
488
497
|
When set to true, Rascal will create the vhost if one doesn't exist using the RabbitMQ management API. This requires the [management plugin](https://www.rabbitmq.com/management.html) to be installed on the broker and for the management user to have necessary permissions.
|
package/lib/amqp/Broker.js
CHANGED
|
@@ -18,9 +18,16 @@ const maxInterval = 2147483647;
|
|
|
18
18
|
module.exports = {
|
|
19
19
|
create: function create(config, components, next) {
|
|
20
20
|
if (arguments.length === 2) return create(config, {}, arguments[1]);
|
|
21
|
+
|
|
22
|
+
const counters = _.defaults({}, components.counters, {
|
|
23
|
+
stub,
|
|
24
|
+
inMemory,
|
|
25
|
+
inMemoryCluster,
|
|
26
|
+
});
|
|
27
|
+
|
|
21
28
|
preflight(_.cloneDeep(config), (err, config) => {
|
|
22
29
|
if (err) return next(err);
|
|
23
|
-
new Broker(config, components)._init(next);
|
|
30
|
+
new Broker(config, _.assign({}, components, { counters }))._init(next);
|
|
24
31
|
});
|
|
25
32
|
},
|
|
26
33
|
};
|
|
@@ -39,11 +46,6 @@ function Broker(config, components) {
|
|
|
39
46
|
const forewarnVhost = tasks.forewarnVhost;
|
|
40
47
|
const shutdownVhost = tasks.shutdownVhost;
|
|
41
48
|
const bounceVhost = tasks.bounceVhost;
|
|
42
|
-
const counters = _.defaults({}, components.counters, {
|
|
43
|
-
stub,
|
|
44
|
-
inMemory,
|
|
45
|
-
inMemoryCluster,
|
|
46
|
-
});
|
|
47
49
|
|
|
48
50
|
this.config = config;
|
|
49
51
|
this.promises = false;
|
|
@@ -54,7 +56,7 @@ function Broker(config, components) {
|
|
|
54
56
|
publications = {};
|
|
55
57
|
subscriptions = {};
|
|
56
58
|
sessions = [];
|
|
57
|
-
init(config, { broker: self, components
|
|
59
|
+
init(config, { broker: self, components }, (err) => {
|
|
58
60
|
self.keepActive = setInterval(_.noop, maxInterval);
|
|
59
61
|
setImmediate(() => {
|
|
60
62
|
next(err, self);
|
|
@@ -135,7 +137,7 @@ function Broker(config, components) {
|
|
|
135
137
|
async.eachSeries(
|
|
136
138
|
_.values(vhosts),
|
|
137
139
|
(vhost, callback) => {
|
|
138
|
-
nukeVhost(config, { vhost }, callback);
|
|
140
|
+
nukeVhost(config, { vhost, components }, callback);
|
|
139
141
|
},
|
|
140
142
|
(err) => {
|
|
141
143
|
if (err) return next(err);
|
package/lib/amqp/Vhost.js
CHANGED
|
@@ -11,14 +11,14 @@ const backoff = require('../backoff');
|
|
|
11
11
|
const setTimeoutUnref = require('../utils/setTimeoutUnref');
|
|
12
12
|
|
|
13
13
|
module.exports = {
|
|
14
|
-
create(config, next) {
|
|
15
|
-
new Vhost(config).init(next);
|
|
14
|
+
create(config, components, next) {
|
|
15
|
+
new Vhost(config, components).init(next);
|
|
16
16
|
},
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
inherits(Vhost, EventEmitter);
|
|
20
20
|
|
|
21
|
-
function Vhost(config) {
|
|
21
|
+
function Vhost(config, components) {
|
|
22
22
|
const self = this;
|
|
23
23
|
let connection;
|
|
24
24
|
let connectionConfig;
|
|
@@ -49,7 +49,7 @@ function Vhost(config) {
|
|
|
49
49
|
debug('Initialising vhost: %s', self.name);
|
|
50
50
|
pauseChannelAllocation();
|
|
51
51
|
|
|
52
|
-
init(config, { connectionIndex: self.connectionIndex }, (err, config, ctx) => {
|
|
52
|
+
init(config, { connectionIndex: self.connectionIndex, components }, (err, config, ctx) => {
|
|
53
53
|
if (err) return next(err);
|
|
54
54
|
|
|
55
55
|
connection = ctx.connection;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const debug = require('debug')('rascal:tasks:assertVhost');
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const async = require('async');
|
|
4
|
-
const
|
|
4
|
+
const Client = require('../../management/Client');
|
|
5
5
|
|
|
6
6
|
module.exports = _.curry((config, ctx, next) => {
|
|
7
7
|
if (!config.assert) return next(null, config, ctx);
|
|
8
|
+
|
|
8
9
|
const candidates = config.connections;
|
|
10
|
+
const client = new Client(ctx.components.agent);
|
|
9
11
|
|
|
10
12
|
async.retry(
|
|
11
13
|
candidates.length,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const debug = require('debug')('rascal:tasks:checkVhost');
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const async = require('async');
|
|
4
|
-
const
|
|
4
|
+
const Client = require('../../management/Client');
|
|
5
5
|
|
|
6
6
|
module.exports = _.curry((config, ctx, next) => {
|
|
7
7
|
if (!config.check) return next(null, config, ctx);
|
|
8
|
+
|
|
8
9
|
const candidates = config.connections;
|
|
10
|
+
const client = new Client(ctx.components.agent);
|
|
9
11
|
|
|
10
12
|
async.retry(
|
|
11
13
|
candidates.length,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
const debug = require('debug')('rascal:tasks:deleteVhost');
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const async = require('async');
|
|
4
|
-
const
|
|
4
|
+
const Client = require('../../management/Client');
|
|
5
5
|
|
|
6
6
|
module.exports = _.curry((config, ctx, next) => {
|
|
7
7
|
const vhostConfig = config.vhosts[ctx.vhost.name];
|
|
8
8
|
if (!vhostConfig.assert) return next(null, config, ctx);
|
|
9
9
|
|
|
10
10
|
const candidates = vhostConfig.connections;
|
|
11
|
+
const client = new Client(ctx.components.agent);
|
|
11
12
|
|
|
12
13
|
async.retry(
|
|
13
14
|
candidates.length,
|
|
@@ -9,7 +9,7 @@ module.exports = _.curry((config, ctx, next) => {
|
|
|
9
9
|
async.eachSeries(
|
|
10
10
|
_.values(config.vhosts),
|
|
11
11
|
(vhostConfig, callback) => {
|
|
12
|
-
initVhost(vhostConfig, (err, vhost) => {
|
|
12
|
+
initVhost(vhostConfig, ctx.components, (err, vhost) => {
|
|
13
13
|
if (err) return callback(err);
|
|
14
14
|
vhost.setMaxListeners(0);
|
|
15
15
|
forwardEvents(vhost, ctx.broker);
|
|
@@ -24,6 +24,6 @@ module.exports = _.curry((config, ctx, next) => {
|
|
|
24
24
|
);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
function initVhost(config, next) {
|
|
28
|
-
Vhost.create(config, next);
|
|
27
|
+
function initVhost(config, components, next) {
|
|
28
|
+
Vhost.create(config, components, next);
|
|
29
29
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const debug = require('debug')('rascal:management:client');
|
|
2
|
+
const format = require('util').format;
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const defaultAgent = require('superagent');
|
|
5
|
+
|
|
6
|
+
function Client(suppliedAgent) {
|
|
7
|
+
const agent = suppliedAgent || defaultAgent;
|
|
8
|
+
const self = this;
|
|
9
|
+
|
|
10
|
+
this.assertVhost = function (name, config, next) {
|
|
11
|
+
debug('Asserting vhost: %s', name);
|
|
12
|
+
const options = getVhostOptions(name, config);
|
|
13
|
+
self._request('put', options.url, options.timeout, (err) => {
|
|
14
|
+
if (!err) return next();
|
|
15
|
+
const message = err.status ? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
16
|
+
return next(new Error(message));
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
this.checkVhost = function (name, config, next) {
|
|
21
|
+
debug('Checking vhost: %s', name);
|
|
22
|
+
const options = getVhostOptions(name, config);
|
|
23
|
+
self._request('get', options.url, options.timeout, (err) => {
|
|
24
|
+
if (!err) return next();
|
|
25
|
+
const message = err.status ? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
26
|
+
return next(new Error(message));
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
this.deleteVhost = function (name, config, next) {
|
|
31
|
+
debug('Deleting vhost: %s', name);
|
|
32
|
+
const options = getVhostOptions(name, config);
|
|
33
|
+
self._request('delete', options.url, options.timeout, (err) => {
|
|
34
|
+
if (!err) return next();
|
|
35
|
+
const message = err.status ? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
36
|
+
return next(new Error(message));
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
this._request = function (method, url, timeout, next) {
|
|
41
|
+
agent[method](url)
|
|
42
|
+
.timeout({ deadline: timeout })
|
|
43
|
+
.then(() => {
|
|
44
|
+
next();
|
|
45
|
+
})
|
|
46
|
+
.catch(next);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function getVhostOptions(name, config) {
|
|
50
|
+
const url = format('%s/%s/%s', config.url, 'api/vhosts', name);
|
|
51
|
+
return _.defaultsDeep({ url }, config.options);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = Client;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rascal",
|
|
3
|
-
"version": "14.0
|
|
3
|
+
"version": "14.1.0",
|
|
4
4
|
"description": "A config driven wrapper for amqplib supporting multi-host connections, automatic error recovery, redelivery flood protection, transparent encryption / decryption, channel pooling and publication timeouts",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"nyc": "^15.1.0",
|
|
30
30
|
"prettier": "2.4.1",
|
|
31
31
|
"random-readable": "^1.0.1",
|
|
32
|
+
"superagent-defaults": "^0.1.14",
|
|
32
33
|
"zunit": "^3.0.8"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
package/lib/management/client.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const debug = require('debug')('rascal:management:client');
|
|
2
|
-
const format = require('util').format;
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const agent = require('superagent');
|
|
5
|
-
|
|
6
|
-
function assertVhost(name, config, next) {
|
|
7
|
-
debug('Asserting vhost: %s', name);
|
|
8
|
-
const options = getVhostOptions(name, config);
|
|
9
|
-
request('put', options.url, options.timeout, (err) => {
|
|
10
|
-
if (!err) return next();
|
|
11
|
-
const message = err.status ? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
12
|
-
return next(new Error(message));
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function checkVhost(name, config, next) {
|
|
17
|
-
debug('Checking vhost: %s', name);
|
|
18
|
-
const options = getVhostOptions(name, config);
|
|
19
|
-
request('get', options.url, options.timeout, (err) => {
|
|
20
|
-
if (!err) return next();
|
|
21
|
-
const message = err.status ? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
22
|
-
return next(new Error(message));
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function deleteVhost(name, config, next) {
|
|
27
|
-
debug('Deleting vhost: %s', name);
|
|
28
|
-
const options = getVhostOptions(name, config);
|
|
29
|
-
request('delete', options.url, options.timeout, (err) => {
|
|
30
|
-
if (!err) return next();
|
|
31
|
-
const message = err.status ? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
32
|
-
return next(new Error(message));
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function getVhostOptions(name, config) {
|
|
37
|
-
const url = format('%s/%s/%s', config.url, 'api/vhosts', name);
|
|
38
|
-
return _.defaultsDeep({ url }, config.options);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function request(method, url, timeout, next) {
|
|
42
|
-
agent[method](url)
|
|
43
|
-
.timeout({ deadline: timeout })
|
|
44
|
-
.then(() => {
|
|
45
|
-
next();
|
|
46
|
-
})
|
|
47
|
-
.catch(next);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module.exports = {
|
|
51
|
-
assertVhost,
|
|
52
|
-
checkVhost,
|
|
53
|
-
deleteVhost,
|
|
54
|
-
};
|