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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 14.1.0
4
+
5
+ - Adds support for custom user agents - See https://github.com/guidesmiths/rascal/issues/170
6
+
3
7
  ## 14.0.1
4
8
 
5
9
  - Fixes https://github.com/guidesmiths/rascal/issues/178
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.
@@ -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: { counters } }, (err) => {
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 client = require('../../management/client');
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 client = require('../../management/client');
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 client = require('../../management/client');
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.1",
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": {
@@ -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
- };