@toa.io/bindings.amqp 0.2.1-dev.3 → 0.2.1-dev.4
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 +3 -3
- package/readme.md +30 -21
- package/source/broadcast.js +49 -0
- package/source/communication.js +54 -0
- package/source/consumer.js +35 -0
- package/source/emitter.js +36 -0
- package/source/factory.js +62 -0
- package/{src → source}/index.js +5 -2
- package/{src → source}/pointer.js +0 -5
- package/source/producer.js +49 -0
- package/source/queues.js +13 -0
- package/source/receiver.js +42 -0
- package/test/annotations.test.js +1 -0
- package/test/broadcast.test.js +83 -0
- package/test/communication.mock.js +20 -0
- package/test/communication.test.js +97 -0
- package/test/comq.mock.js +21 -0
- package/test/consumer.test.js +51 -0
- package/test/emitter.test.js +54 -0
- package/test/factory.test.js +201 -0
- package/test/pointer.test.js +4 -5
- package/test/producer.test.js +69 -0
- package/test/properties.test.js +7 -0
- package/test/queues.mock.js +7 -0
- package/test/queues.test.js +35 -0
- package/test/receiver.test.js +64 -0
- package/types/communication.d.ts +16 -0
- package/src/broadcaster.js +0 -37
- package/src/channel.js +0 -140
- package/src/connection.js +0 -49
- package/src/consumer.js +0 -28
- package/src/emitter.js +0 -31
- package/src/factory.js +0 -69
- package/src/message.js +0 -7
- package/src/producer.js +0 -38
- package/src/queue.js +0 -7
- package/src/receiver.js +0 -39
- package/types/pointer.d.ts +0 -8
- /package/{src → source}/annotation.js +0 -0
- /package/{src → source}/constants.js +0 -0
- /package/{src → source}/deployment.js +0 -0
package/src/channel.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
const { newid, timeout } = require('@toa.io/generic')
|
|
5
|
-
const { console } = require('@toa.io/console')
|
|
6
|
-
|
|
7
|
-
const { pack, unpack } = require('./message')
|
|
8
|
-
|
|
9
|
-
class Channel extends Connector {
|
|
10
|
-
#id
|
|
11
|
-
#connection
|
|
12
|
-
#channel
|
|
13
|
-
|
|
14
|
-
#bound = {}
|
|
15
|
-
#expected = {}
|
|
16
|
-
|
|
17
|
-
constructor (connection) {
|
|
18
|
-
super()
|
|
19
|
-
|
|
20
|
-
this.#id = newid()
|
|
21
|
-
this.#connection = connection
|
|
22
|
-
|
|
23
|
-
this.depends(connection)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async connection () {
|
|
27
|
-
this.#channel = await this.#connection.channel()
|
|
28
|
-
this.#channel.prefetch(100)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async disconnection () {
|
|
32
|
-
// solves 'Channel ended, no reply will be forthcoming'
|
|
33
|
-
await timeout(50)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async request (label, request) {
|
|
37
|
-
const queue = 'request.' + label
|
|
38
|
-
const correlation = newid()
|
|
39
|
-
|
|
40
|
-
await this.#channel.assertQueue(queue, QUEUE)
|
|
41
|
-
await this.#bind(label)
|
|
42
|
-
|
|
43
|
-
const message = pack(request)
|
|
44
|
-
const properties = { replyTo: this.#id, correlationId: correlation }
|
|
45
|
-
|
|
46
|
-
await this.#channel.sendToQueue(queue, message, properties)
|
|
47
|
-
|
|
48
|
-
const reply = await this.#reply(label, correlation)
|
|
49
|
-
|
|
50
|
-
return unpack(reply.content)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async reply (label, invocation) {
|
|
54
|
-
const queue = 'request.' + label
|
|
55
|
-
const exchange = 'reply.' + label
|
|
56
|
-
|
|
57
|
-
await this.#channel.assertQueue(queue, QUEUE)
|
|
58
|
-
await this.#channel.assertExchange(exchange, 'direct', EXCHANGE)
|
|
59
|
-
|
|
60
|
-
await this.#channel.consume(queue, async (received) => {
|
|
61
|
-
const content = unpack(received.content)
|
|
62
|
-
const reply = await invocation(content)
|
|
63
|
-
|
|
64
|
-
const buffer = pack(reply)
|
|
65
|
-
const properties = { correlationId: received.properties.correlationId }
|
|
66
|
-
|
|
67
|
-
await this.#channel.publish(exchange, received.properties.replyTo, buffer, properties)
|
|
68
|
-
await this.#channel.ack(received)
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async publish (label, content, options) {
|
|
73
|
-
const exchange = 'event.' + label
|
|
74
|
-
|
|
75
|
-
// TODO: assert once per exchange
|
|
76
|
-
await this.#channel.assertExchange(exchange, 'fanout', EXCHANGE)
|
|
77
|
-
|
|
78
|
-
const buffer = pack(content)
|
|
79
|
-
|
|
80
|
-
await this.#channel.publish(exchange, '', buffer, options)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async subscribe (label, id, callback) {
|
|
84
|
-
const exchange = 'event.' + label
|
|
85
|
-
const queue = exchange + '..' + id
|
|
86
|
-
const options = { consumerTag: id }
|
|
87
|
-
|
|
88
|
-
await this.#channel.assertExchange(exchange, 'fanout', EXCHANGE)
|
|
89
|
-
await this.#channel.assertQueue(queue, QUEUE)
|
|
90
|
-
await this.#channel.bindQueue(queue, exchange, '')
|
|
91
|
-
|
|
92
|
-
await this.#channel.consume(queue, async (message) => {
|
|
93
|
-
const content = unpack(message.content)
|
|
94
|
-
await callback(content)
|
|
95
|
-
await this.#channel.ack(message)
|
|
96
|
-
}, options)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async unsubscribe (id) {
|
|
100
|
-
await this.#channel.cancel(id)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async #bind (label) {
|
|
104
|
-
const queue = `reply.${label}.${this.#id}`
|
|
105
|
-
const exchange = 'reply.' + label
|
|
106
|
-
|
|
107
|
-
if (this.#bound[queue]) return
|
|
108
|
-
|
|
109
|
-
await this.#channel.assertQueue(queue, { exclusive: true, ...QUEUE })
|
|
110
|
-
await this.#channel.assertExchange(exchange, 'direct', EXCHANGE)
|
|
111
|
-
await this.#channel.bindQueue(queue, exchange, this.#id)
|
|
112
|
-
await this.#channel.consume(queue, (message) => this.#replies(message))
|
|
113
|
-
|
|
114
|
-
this.#bound[queue] = true
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#reply (label, correlation) {
|
|
118
|
-
return new Promise((resolve) => (this.#expected[correlation] = resolve))
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async #replies (message) {
|
|
122
|
-
const correlation = message.properties.correlationId
|
|
123
|
-
const resolve = this.#expected[correlation]
|
|
124
|
-
|
|
125
|
-
if (!resolve) {
|
|
126
|
-
console.warn(`Unexpected reply '${correlation}'. Possible message redelivery.`)
|
|
127
|
-
return
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
resolve(message)
|
|
131
|
-
|
|
132
|
-
delete this.#expected[correlation]
|
|
133
|
-
await this.#channel.ack(message)
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const QUEUE = { durable: true }
|
|
138
|
-
const EXCHANGE = { durable: true }
|
|
139
|
-
|
|
140
|
-
exports.Channel = Channel
|
package/src/connection.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const amqp = require('amqplib')
|
|
4
|
-
|
|
5
|
-
const { Connector } = require('@toa.io/core')
|
|
6
|
-
const { console } = require('@toa.io/console')
|
|
7
|
-
|
|
8
|
-
class Connection extends Connector {
|
|
9
|
-
/** @type {toa.amqp.Pointer} */
|
|
10
|
-
#pointer
|
|
11
|
-
|
|
12
|
-
/** @type {import('amqplib').Connection} */
|
|
13
|
-
#connection
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param {toa.amqp.Pointer} pointer
|
|
17
|
-
*/
|
|
18
|
-
constructor (pointer) {
|
|
19
|
-
super()
|
|
20
|
-
|
|
21
|
-
this.#pointer = pointer
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async connection () {
|
|
25
|
-
try {
|
|
26
|
-
this.#connection = await amqp.connect(this.#pointer.reference)
|
|
27
|
-
} catch (e) {
|
|
28
|
-
console.error(`Connection to ${this.#pointer.label} has failed`)
|
|
29
|
-
|
|
30
|
-
throw e
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
console.info(`AMQP Binding connected to ${this.#pointer.label}`)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async disconnection () {
|
|
37
|
-
// TODO: handle current operations
|
|
38
|
-
// http://www.squaremobius.net/amqp.node/channel_api.html#model_close
|
|
39
|
-
await this.#connection.close()
|
|
40
|
-
|
|
41
|
-
console.info(`AMQP Binding disconnected from ${this.#pointer.label}`)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async channel () {
|
|
45
|
-
return await this.#connection.createChannel()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
exports.Connection = Connection
|
package/src/consumer.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
const { name } = require('./queue')
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @implements {toa.core.bindings.Consumer}
|
|
9
|
-
*/
|
|
10
|
-
class Consumer extends Connector {
|
|
11
|
-
#channel
|
|
12
|
-
#queue
|
|
13
|
-
|
|
14
|
-
constructor (channel, locator, endpoint) {
|
|
15
|
-
super()
|
|
16
|
-
|
|
17
|
-
this.#channel = channel
|
|
18
|
-
this.#queue = name(locator, endpoint)
|
|
19
|
-
|
|
20
|
-
this.depends(channel)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async request (request) {
|
|
24
|
-
return this.#channel.request(this.#queue, request)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
exports.Consumer = Consumer
|
package/src/emitter.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
const { name } = require('./queue')
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @implements {toa.core.bindings.Emitter}
|
|
8
|
-
*/
|
|
9
|
-
class Emitter extends Connector {
|
|
10
|
-
#channel
|
|
11
|
-
#locator
|
|
12
|
-
#label
|
|
13
|
-
|
|
14
|
-
constructor (channel, locator, label) {
|
|
15
|
-
super()
|
|
16
|
-
|
|
17
|
-
this.#channel = channel
|
|
18
|
-
this.#locator = locator
|
|
19
|
-
this.#label = label
|
|
20
|
-
|
|
21
|
-
this.depends(channel)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async emit (payload) {
|
|
25
|
-
const label = name(this.#locator, this.#label)
|
|
26
|
-
|
|
27
|
-
await this.#channel.publish(label, payload)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
exports.Emitter = Emitter
|
package/src/factory.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Locator } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
const { Channel } = require('./channel')
|
|
6
|
-
const { Consumer } = require('./consumer')
|
|
7
|
-
const { Producer } = require('./producer')
|
|
8
|
-
const { Emitter } = require('./emitter')
|
|
9
|
-
const { Receiver } = require('./receiver')
|
|
10
|
-
const { Broadcaster } = require('./broadcaster')
|
|
11
|
-
const { Connection } = require('./connection')
|
|
12
|
-
const { Pointer } = require('./pointer')
|
|
13
|
-
const { SYSTEM } = require('./constants')
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @implements {toa.core.bindings.Factory}
|
|
17
|
-
*/
|
|
18
|
-
class Factory {
|
|
19
|
-
#connections = {}
|
|
20
|
-
|
|
21
|
-
producer (locator, endpoints, producer) {
|
|
22
|
-
const channel = this.#channel(locator)
|
|
23
|
-
|
|
24
|
-
return new Producer(channel, locator, endpoints, producer)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
consumer (locator, endpoint) {
|
|
28
|
-
const channel = this.#channel(locator)
|
|
29
|
-
|
|
30
|
-
return new Consumer(channel, locator, endpoint)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
emitter (locator, label) {
|
|
34
|
-
const channel = this.#channel(locator)
|
|
35
|
-
|
|
36
|
-
return new Emitter(channel, locator, label)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
receiver (locator, label, id, receiver) {
|
|
40
|
-
const channel = this.#channel(locator)
|
|
41
|
-
|
|
42
|
-
return new Receiver(channel, locator, label, id, receiver)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
broadcaster (name, group) {
|
|
46
|
-
const channel = this.#channel()
|
|
47
|
-
|
|
48
|
-
return new Broadcaster(channel, name, group)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {toa.core.Locator} [locator]
|
|
53
|
-
* @returns {Channel}
|
|
54
|
-
*/
|
|
55
|
-
#channel (locator) {
|
|
56
|
-
if (locator === undefined) locator = new Locator(SYSTEM)
|
|
57
|
-
|
|
58
|
-
const pointer = new Pointer(locator)
|
|
59
|
-
const key = pointer.reference
|
|
60
|
-
|
|
61
|
-
if (this.#connections[key] === undefined) {
|
|
62
|
-
this.#connections[key] = new Connection(pointer)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return new Channel(this.#connections[key])
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
exports.Factory = Factory
|
package/src/message.js
DELETED
package/src/producer.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
const { name } = require('./queue')
|
|
6
|
-
|
|
7
|
-
class Producer extends Connector {
|
|
8
|
-
#channel
|
|
9
|
-
/** @type {toa.core.Locator} */
|
|
10
|
-
#locator
|
|
11
|
-
/** @type {toa.core.Component} */
|
|
12
|
-
#producer
|
|
13
|
-
/** @type {Array<string>} */
|
|
14
|
-
#endpoints
|
|
15
|
-
|
|
16
|
-
constructor (channel, locator, endpoints, producer) {
|
|
17
|
-
super()
|
|
18
|
-
|
|
19
|
-
this.#channel = channel
|
|
20
|
-
this.#locator = locator
|
|
21
|
-
this.#endpoints = endpoints
|
|
22
|
-
this.#producer = producer
|
|
23
|
-
|
|
24
|
-
this.depends(channel)
|
|
25
|
-
this.depends(producer)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async connection () {
|
|
29
|
-
await Promise.all(this.#endpoints.map((endpoint) => this.#endpoint(endpoint)))
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async #endpoint (endpoint) {
|
|
33
|
-
const queue = name(this.#locator, endpoint)
|
|
34
|
-
await this.#channel.reply(queue, async (request) => this.#producer.invoke(endpoint, request))
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
exports.Producer = Producer
|
package/src/queue.js
DELETED
package/src/receiver.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
const { name } = require('./queue')
|
|
6
|
-
|
|
7
|
-
class Receiver extends Connector {
|
|
8
|
-
#channel
|
|
9
|
-
/** @type {toa.core.Receiver} */
|
|
10
|
-
#receiver
|
|
11
|
-
|
|
12
|
-
/** @type {string} */
|
|
13
|
-
#label
|
|
14
|
-
|
|
15
|
-
/** @type {string} */
|
|
16
|
-
#id
|
|
17
|
-
|
|
18
|
-
constructor (channel, locator, label, id, receiver) {
|
|
19
|
-
super()
|
|
20
|
-
|
|
21
|
-
this.#channel = channel
|
|
22
|
-
this.#receiver = receiver
|
|
23
|
-
this.#label = name(locator, label)
|
|
24
|
-
this.#id = id
|
|
25
|
-
|
|
26
|
-
this.depends(channel)
|
|
27
|
-
this.depends(receiver)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async connection () {
|
|
31
|
-
await this.#channel.subscribe(this.#label, this.#id, (message) => this.#receiver.receive(message))
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async disconnection () {
|
|
35
|
-
await this.#channel.unsubscribe(this.#id)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
exports.Receiver = Receiver
|
package/types/pointer.d.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|