@webda/amqp 4.0.0-beta.2 → 4.0.0-beta.3
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 +78 -12
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/{pubsub.d.ts → pubsub.service.d.ts} +37 -14
- package/lib/pubsub.service.d.ts.map +1 -0
- package/lib/{pubsub.js → pubsub.service.js} +44 -21
- package/lib/pubsub.service.js.map +1 -0
- package/lib/queue.service.d.ts +66 -0
- package/lib/queue.service.d.ts.map +1 -0
- package/lib/{queue.js → queue.service.js} +35 -11
- package/lib/queue.service.js.map +1 -0
- package/package.json +30 -36
- package/webda.module.json +168 -141
- package/lib/pubsub.d.ts.map +0 -1
- package/lib/pubsub.js.map +0 -1
- package/lib/pubsub.spec.d.ts +0 -2
- package/lib/pubsub.spec.d.ts.map +0 -1
- package/lib/pubsub.spec.js +0 -84
- package/lib/pubsub.spec.js.map +0 -1
- package/lib/queue.d.ts +0 -41
- package/lib/queue.d.ts.map +0 -1
- package/lib/queue.js.map +0 -1
- package/lib/queue.spec.d.ts +0 -2
- package/lib/queue.spec.d.ts.map +0 -1
- package/lib/queue.spec.js +0 -29
- package/lib/queue.spec.js.map +0 -1
package/README.md
CHANGED
|
@@ -13,30 +13,96 @@ This module is part of Webda Application Framework that allows you to quickly de
|
|
|
13
13
|
|
|
14
14
|
<!-- README_HEADER -->
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
You can use it with RabbitMQ or any other AMQP compatible server.
|
|
16
|
+
# @webda/amqp
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
> RabbitMQ-backed Queue and Pub/Sub services for Webda — drop-in replacements for in-memory transports when you need durable, cross-process messaging.
|
|
19
|
+
|
|
20
|
+
## When to use it
|
|
21
|
+
|
|
22
|
+
- You need a durable task queue backed by RabbitMQ (or any AMQP 0-9-1 broker).
|
|
23
|
+
- You need fan-out pub/sub across multiple Webda instances via AMQP exchanges.
|
|
24
|
+
- You are replacing `MemoryQueue` / `MemoryPubSub` in a production deployment.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm add @webda/amqp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
### AMQPQueue
|
|
20
35
|
|
|
21
36
|
```json
|
|
22
37
|
{
|
|
23
38
|
"services": {
|
|
24
|
-
"
|
|
39
|
+
"taskQueue": {
|
|
25
40
|
"type": "AMQPQueue",
|
|
26
|
-
"
|
|
27
|
-
"queue": "
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
"url": "amqp://localhost:5672",
|
|
42
|
+
"queue": "my-tasks"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Parameter | Type | Default | Required | Description |
|
|
49
|
+
|---|---|---|---|---|
|
|
50
|
+
| `url` | string | — | Yes | AMQP broker connection URL (e.g. `amqp://user:pass@host:5672`) |
|
|
51
|
+
| `queue` | string | — | Yes | Name of the AMQP queue to assert and consume |
|
|
52
|
+
| `queueOptions` | object | — | No | Options forwarded to `channel.assertQueue()` (e.g. `{ durable: true }`) |
|
|
53
|
+
|
|
54
|
+
### AMQPPubSubService
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"services": {
|
|
59
|
+
"eventBus": {
|
|
31
60
|
"type": "AMQPPubSub",
|
|
32
|
-
"
|
|
33
|
-
"channel": "
|
|
34
|
-
"
|
|
61
|
+
"url": "amqp://localhost:5672",
|
|
62
|
+
"channel": "my-events",
|
|
63
|
+
"exchange": { "type": "fanout", "durable": true }
|
|
35
64
|
}
|
|
36
65
|
}
|
|
37
66
|
}
|
|
38
67
|
```
|
|
39
68
|
|
|
69
|
+
| Parameter | Type | Default | Required | Description |
|
|
70
|
+
|---|---|---|---|---|
|
|
71
|
+
| `url` | string | — | Yes | AMQP broker connection URL |
|
|
72
|
+
| `channel` | string | — | Yes | Exchange name to publish/subscribe to |
|
|
73
|
+
| `subscription` | string | `""` | No | Subscription queue name (auto-generated exclusive queue if empty) |
|
|
74
|
+
| `exchange.type` | string | `"fanout"` | No | Exchange type (`fanout`, `direct`, `topic`, `headers`) |
|
|
75
|
+
| `exchange.durable` | boolean | `true` | No | Survive broker restarts |
|
|
76
|
+
| `exchange.autoDelete` | boolean | `false` | No | Delete when last binding is removed |
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { Queue } from "@webda/core";
|
|
82
|
+
import { Service } from "@webda/core";
|
|
83
|
+
import { Bean, Inject } from "@webda/core";
|
|
84
|
+
|
|
85
|
+
@Bean
|
|
86
|
+
export class OrderService extends Service {
|
|
87
|
+
@Inject("taskQueue")
|
|
88
|
+
queue: Queue<{ orderId: string }>;
|
|
89
|
+
|
|
90
|
+
async placeOrder(orderId: string): Promise<void> {
|
|
91
|
+
// Publish a task to RabbitMQ
|
|
92
|
+
await this.queue.sendMessage({ orderId });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Consumer side: start a queue worker via AsyncJobService or
|
|
97
|
+
// by calling queue.consume(async (msg) => { ... })
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Reference
|
|
101
|
+
|
|
102
|
+
- API reference: see the auto-generated typedoc at `docs/pages/Modules/amqp/`.
|
|
103
|
+
- Source: [`packages/amqp`](https://github.com/loopingz/webda.io/tree/main/packages/amqp)
|
|
104
|
+
- Related: [`@webda/core`](../core) for the `Queue` and `PubSubService` base classes, [`@webda/async`](../async) for job orchestration on top of a queue.
|
|
105
|
+
|
|
40
106
|
<!-- README_FOOTER -->
|
|
41
107
|
## Sponsors
|
|
42
108
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./pubsub.js";
|
|
2
|
-
export * from "./queue.js";
|
|
1
|
+
export * from "./pubsub.service.js";
|
|
2
|
+
export * from "./queue.service.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./pubsub.js";
|
|
2
|
-
export * from "./queue.js";
|
|
1
|
+
export * from "./pubsub.service.js";
|
|
2
|
+
export * from "./queue.service.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PubSubService, ServiceParameters } from "@webda/core";
|
|
2
|
+
import { CancelablePromise } from "@webda/utils";
|
|
2
3
|
import * as amqplib from "amqplib";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link AMQPPubSubService}
|
|
6
|
+
*/
|
|
3
7
|
export declare class AMQPPubSubParameters extends ServiceParameters {
|
|
8
|
+
/**
|
|
9
|
+
* AMQP connection url
|
|
10
|
+
* @example "amqp://localhost:5672"
|
|
11
|
+
*/
|
|
4
12
|
url: string;
|
|
13
|
+
/**
|
|
14
|
+
* Exchange name to publish to and consume from
|
|
15
|
+
*/
|
|
5
16
|
channel: string;
|
|
6
17
|
/**
|
|
18
|
+
* Queue name used to subscribe, empty to let the broker generate one
|
|
7
19
|
* @default ""
|
|
8
|
-
* @SchemaOptional
|
|
9
20
|
*/
|
|
10
|
-
subscription
|
|
21
|
+
subscription?: string;
|
|
11
22
|
exchange?: {
|
|
12
23
|
/**
|
|
13
24
|
* @default fanout
|
|
@@ -40,43 +51,55 @@ export declare class AMQPPubSubParameters extends ServiceParameters {
|
|
|
40
51
|
*/
|
|
41
52
|
arguments?: any;
|
|
42
53
|
};
|
|
43
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @override
|
|
56
|
+
* @param params - the input parameters
|
|
57
|
+
* @returns this
|
|
58
|
+
*/
|
|
59
|
+
load(params?: any): this;
|
|
44
60
|
}
|
|
45
61
|
/**
|
|
62
|
+
* Pub/sub backed by an AMQP exchange
|
|
46
63
|
*
|
|
47
64
|
* @see https://www.rabbitmq.com/tutorials/tutorial-three-python.html
|
|
48
65
|
* @WebdaModda AMQPPubSub
|
|
49
66
|
*/
|
|
50
67
|
export default class AMQPPubSubService<T = any, K extends AMQPPubSubParameters = AMQPPubSubParameters> extends PubSubService<T, K> {
|
|
51
68
|
channel: amqplib.Channel;
|
|
52
|
-
conn: amqplib.
|
|
53
|
-
exchange:
|
|
69
|
+
conn: amqplib.ChannelModel;
|
|
70
|
+
exchange: amqplib.Replies.AssertExchange;
|
|
54
71
|
/**
|
|
55
72
|
* @override
|
|
73
|
+
* @param event - the event to publish
|
|
74
|
+
* @param routingKey - the routing key to use
|
|
56
75
|
*/
|
|
57
|
-
|
|
76
|
+
sendMessage(event: T, routingKey?: string): Promise<void>;
|
|
58
77
|
/**
|
|
59
78
|
* @override
|
|
79
|
+
* @returns this service
|
|
60
80
|
*/
|
|
61
|
-
|
|
81
|
+
init(): Promise<this>;
|
|
62
82
|
/**
|
|
83
|
+
* Close the AMQP connection
|
|
63
84
|
* @override
|
|
64
85
|
*/
|
|
65
|
-
|
|
86
|
+
stop(): Promise<void>;
|
|
66
87
|
/**
|
|
67
88
|
* Return queue size
|
|
68
|
-
* @returns
|
|
89
|
+
* @returns the number of messages in the subscription queue
|
|
69
90
|
*/
|
|
70
91
|
size(): Promise<number>;
|
|
71
92
|
/**
|
|
72
93
|
* Work a queue calling the callback with every Event received
|
|
73
|
-
* If the callback is called without exception the
|
|
74
|
-
* @param callback
|
|
75
|
-
* @param eventPrototype
|
|
94
|
+
* If the callback is called without exception the message is acknowledged
|
|
95
|
+
* @param callback - invoked with each event received
|
|
96
|
+
* @param eventPrototype - optional class to rehydrate JSON into
|
|
97
|
+
* @param onBind - invoked once the subscription is bound
|
|
98
|
+
* @returns a cancelable subscription handle
|
|
76
99
|
*/
|
|
77
100
|
consume(callback: (event: T) => Promise<void>, eventPrototype?: {
|
|
78
101
|
new (): T;
|
|
79
102
|
}, onBind?: () => void): CancelablePromise;
|
|
80
103
|
}
|
|
81
104
|
export { AMQPPubSubService };
|
|
82
|
-
//# sourceMappingURL=pubsub.d.ts.map
|
|
105
|
+
//# sourceMappingURL=pubsub.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.service.d.ts","sourceRoot":"","sources":["../src/pubsub.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAa,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,iBAAiB;IACzD;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QACT;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;;;WAIG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB;;;WAGG;QACH,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB;;;;WAIG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B;;WAEG;QACH,SAAS,CAAC,EAAE,GAAG,CAAC;KACjB,CAAC;IAEF;;;;OAIG;IACH,IAAI,CAAC,MAAM,GAAE,GAAQ,GAAG,IAAI,CAM3B;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB,CACpC,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,oBAAoB,GAAG,oBAAoB,CACrD,SAAQ,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;IAEzC;;;;OAIG;IACG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAY1B;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1B;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5B;IAED;;;;;;;OAOG;IACH,OAAO,CACL,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EACrC,cAAc,CAAC,EAAE;QAAE,QAAQ,CAAC,CAAA;KAAE,EAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,GAClB,iBAAiB,CAqCnB;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PubSubService, ServiceParameters } from "@webda/core";
|
|
2
|
+
import { CancelablePromise, JSONUtils } from "@webda/utils";
|
|
2
3
|
import * as amqplib from "amqplib";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link AMQPPubSubService}
|
|
6
|
+
*/
|
|
3
7
|
export class AMQPPubSubParameters extends ServiceParameters {
|
|
4
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @override
|
|
10
|
+
* @param params - the input parameters
|
|
11
|
+
* @returns this
|
|
12
|
+
*/
|
|
13
|
+
load(params = {}) {
|
|
5
14
|
var _a;
|
|
6
|
-
super(params);
|
|
15
|
+
super.load(params);
|
|
7
16
|
this.exchange ?? (this.exchange = {});
|
|
8
17
|
(_a = this.exchange).type ?? (_a.type = "fanout");
|
|
9
18
|
this.subscription ?? (this.subscription = "");
|
|
19
|
+
return this;
|
|
10
20
|
}
|
|
11
21
|
}
|
|
12
22
|
/**
|
|
23
|
+
* Pub/sub backed by an AMQP exchange
|
|
13
24
|
*
|
|
14
25
|
* @see https://www.rabbitmq.com/tutorials/tutorial-three-python.html
|
|
15
26
|
* @WebdaModda AMQPPubSub
|
|
@@ -17,19 +28,16 @@ export class AMQPPubSubParameters extends ServiceParameters {
|
|
|
17
28
|
export default class AMQPPubSubService extends PubSubService {
|
|
18
29
|
/**
|
|
19
30
|
* @override
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return new AMQPPubSubParameters(params);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* @override
|
|
31
|
+
* @param event - the event to publish
|
|
32
|
+
* @param routingKey - the routing key to use
|
|
26
33
|
*/
|
|
27
34
|
async sendMessage(event, routingKey = "") {
|
|
28
35
|
this.metrics.messages_sent.inc();
|
|
29
|
-
|
|
36
|
+
this.channel.publish(this.parameters.channel, routingKey, Buffer.from(JSONUtils.stringify(event)));
|
|
30
37
|
}
|
|
31
38
|
/**
|
|
32
39
|
* @override
|
|
40
|
+
* @returns this service
|
|
33
41
|
*/
|
|
34
42
|
async init() {
|
|
35
43
|
await super.init();
|
|
@@ -40,18 +48,35 @@ export default class AMQPPubSubService extends PubSubService {
|
|
|
40
48
|
this.exchange = await this.channel.assertExchange(this.parameters.channel, this.parameters.exchange?.type || "fanout", params);
|
|
41
49
|
return this;
|
|
42
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Close the AMQP connection
|
|
53
|
+
* @override
|
|
54
|
+
*/
|
|
55
|
+
async stop() {
|
|
56
|
+
if (this.conn) {
|
|
57
|
+
const conn = this.conn;
|
|
58
|
+
this.conn = undefined;
|
|
59
|
+
this.channel = undefined;
|
|
60
|
+
await conn.close().catch(() => {
|
|
61
|
+
/* already closed */
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
await super.stop();
|
|
65
|
+
}
|
|
43
66
|
/**
|
|
44
67
|
* Return queue size
|
|
45
|
-
* @returns
|
|
68
|
+
* @returns the number of messages in the subscription queue
|
|
46
69
|
*/
|
|
47
70
|
async size() {
|
|
48
71
|
return (await this.channel.assertQueue(this.parameters.subscription)).messageCount;
|
|
49
72
|
}
|
|
50
73
|
/**
|
|
51
74
|
* Work a queue calling the callback with every Event received
|
|
52
|
-
* If the callback is called without exception the
|
|
53
|
-
* @param callback
|
|
54
|
-
* @param eventPrototype
|
|
75
|
+
* If the callback is called without exception the message is acknowledged
|
|
76
|
+
* @param callback - invoked with each event received
|
|
77
|
+
* @param eventPrototype - optional class to rehydrate JSON into
|
|
78
|
+
* @param onBind - invoked once the subscription is bound
|
|
79
|
+
* @returns a cancelable subscription handle
|
|
55
80
|
*/
|
|
56
81
|
consume(callback, eventPrototype, onBind) {
|
|
57
82
|
let consumerTag;
|
|
@@ -71,25 +96,23 @@ export default class AMQPPubSubService extends PubSubService {
|
|
|
71
96
|
const end = this.metrics.processing_duration.startTimer();
|
|
72
97
|
try {
|
|
73
98
|
await callback(this.unserialize(msg?.content.toString() || "", eventPrototype));
|
|
74
|
-
|
|
99
|
+
this.channel.ack(msg);
|
|
75
100
|
}
|
|
76
101
|
catch (err) {
|
|
77
102
|
this.metrics.errors.inc();
|
|
78
|
-
this.
|
|
103
|
+
this.log("ERROR", `Message ${msg?.properties?.messageId}`, err);
|
|
79
104
|
}
|
|
80
105
|
finally {
|
|
81
106
|
end();
|
|
82
107
|
}
|
|
83
108
|
})).consumerTag;
|
|
84
|
-
|
|
85
|
-
onBind();
|
|
86
|
-
}
|
|
109
|
+
onBind?.();
|
|
87
110
|
}, async () => {
|
|
88
111
|
if (consumerTag) {
|
|
89
|
-
this.channel
|
|
112
|
+
await this.channel?.cancel(consumerTag);
|
|
90
113
|
}
|
|
91
114
|
});
|
|
92
115
|
}
|
|
93
116
|
}
|
|
94
117
|
export { AMQPPubSubService };
|
|
95
|
-
//# sourceMappingURL=pubsub.js.map
|
|
118
|
+
//# sourceMappingURL=pubsub.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.service.js","sourceRoot":"","sources":["../src/pubsub.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { MessageReceipt, Queue, QueueParameters } from "@webda/core";
|
|
2
|
+
import * as amqplib from "amqplib";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for {@link AMQPQueue}
|
|
5
|
+
*/
|
|
6
|
+
export declare class AMQPQueueParameters extends QueueParameters {
|
|
7
|
+
/**
|
|
8
|
+
* AMQP connection url
|
|
9
|
+
* @example "amqp://localhost:5672"
|
|
10
|
+
*/
|
|
11
|
+
url: string;
|
|
12
|
+
/**
|
|
13
|
+
* Queue name
|
|
14
|
+
*/
|
|
15
|
+
queue: string;
|
|
16
|
+
/**
|
|
17
|
+
* Options passed to assertQueue
|
|
18
|
+
*/
|
|
19
|
+
queueOptions?: any;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Implements a Queue stored in AMQP
|
|
23
|
+
*
|
|
24
|
+
* @WebdaModda
|
|
25
|
+
*/
|
|
26
|
+
export default class AMQPQueue<T = any, K extends AMQPQueueParameters = AMQPQueueParameters> extends Queue<T, K> {
|
|
27
|
+
channel: amqplib.Channel;
|
|
28
|
+
conn: amqplib.ChannelModel;
|
|
29
|
+
/**
|
|
30
|
+
* @override
|
|
31
|
+
* @returns this service
|
|
32
|
+
*/
|
|
33
|
+
init(): Promise<this>;
|
|
34
|
+
/**
|
|
35
|
+
* Close the AMQP connection
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* @override
|
|
41
|
+
* @param event - the event to enqueue
|
|
42
|
+
*/
|
|
43
|
+
sendMessage(event: T): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* @override
|
|
46
|
+
* @param proto - optional prototype to rehydrate the payload into
|
|
47
|
+
* @returns the received message if any
|
|
48
|
+
*/
|
|
49
|
+
receiveMessage<L>(proto?: new () => L): Promise<MessageReceipt<L>[]>;
|
|
50
|
+
/**
|
|
51
|
+
* @override
|
|
52
|
+
* @param id - the receipt handle returned by {@link receiveMessage}
|
|
53
|
+
*/
|
|
54
|
+
deleteMessage(id: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* @override
|
|
57
|
+
* @returns the number of messages ready in the queue
|
|
58
|
+
*/
|
|
59
|
+
size(): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Purge the queue, used by tests
|
|
62
|
+
*/
|
|
63
|
+
__clean(): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export { AMQPQueue };
|
|
66
|
+
//# sourceMappingURL=queue.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.service.d.ts","sourceRoot":"","sources":["../src/queue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IACtD;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAS,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,mBAAmB,GAAG,mBAAmB,CAAE,SAAQ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9G,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC;IAE3B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAM1B;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1B;IAED;;;OAGG;IACG,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzC;IAED;;;;OAIG;IACG,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAWzE;IAED;;;OAGG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7C;IAED;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5B;IAED;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7B;CACF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Queue, QueueParameters } from "@webda/core";
|
|
2
|
+
import { JSONUtils } from "@webda/utils";
|
|
2
3
|
import * as amqplib from "amqplib";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link AMQPQueue}
|
|
6
|
+
*/
|
|
3
7
|
export class AMQPQueueParameters extends QueueParameters {
|
|
4
8
|
}
|
|
5
9
|
/**
|
|
@@ -10,12 +14,7 @@ export class AMQPQueueParameters extends QueueParameters {
|
|
|
10
14
|
export default class AMQPQueue extends Queue {
|
|
11
15
|
/**
|
|
12
16
|
* @override
|
|
13
|
-
|
|
14
|
-
loadParameters(params) {
|
|
15
|
-
return new AMQPQueueParameters(params);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* @override
|
|
17
|
+
* @returns this service
|
|
19
18
|
*/
|
|
20
19
|
async init() {
|
|
21
20
|
await super.init();
|
|
@@ -25,13 +24,32 @@ export default class AMQPQueue extends Queue {
|
|
|
25
24
|
return this;
|
|
26
25
|
}
|
|
27
26
|
/**
|
|
27
|
+
* Close the AMQP connection
|
|
28
28
|
* @override
|
|
29
29
|
*/
|
|
30
|
+
async stop() {
|
|
31
|
+
if (this.conn) {
|
|
32
|
+
const conn = this.conn;
|
|
33
|
+
this.conn = undefined;
|
|
34
|
+
this.channel = undefined;
|
|
35
|
+
await conn.close().catch(() => {
|
|
36
|
+
/* already closed */
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
await super.stop();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @override
|
|
43
|
+
* @param event - the event to enqueue
|
|
44
|
+
*/
|
|
30
45
|
async sendMessage(event) {
|
|
31
|
-
|
|
46
|
+
this.metrics.messages_sent.inc();
|
|
47
|
+
this.channel.sendToQueue(this.parameters.queue, Buffer.from(JSONUtils.stringify(event)));
|
|
32
48
|
}
|
|
33
49
|
/**
|
|
34
50
|
* @override
|
|
51
|
+
* @param proto - optional prototype to rehydrate the payload into
|
|
52
|
+
* @returns the received message if any
|
|
35
53
|
*/
|
|
36
54
|
async receiveMessage(proto) {
|
|
37
55
|
const msg = await this.channel.get(this.parameters.queue);
|
|
@@ -47,18 +65,24 @@ export default class AMQPQueue extends Queue {
|
|
|
47
65
|
}
|
|
48
66
|
/**
|
|
49
67
|
* @override
|
|
68
|
+
* @param id - the receipt handle returned by {@link receiveMessage}
|
|
50
69
|
*/
|
|
51
70
|
async deleteMessage(id) {
|
|
52
|
-
|
|
71
|
+
this.channel.ack(id);
|
|
53
72
|
}
|
|
54
73
|
/**
|
|
55
74
|
* @override
|
|
75
|
+
* @returns the number of messages ready in the queue
|
|
56
76
|
*/
|
|
57
77
|
async size() {
|
|
58
78
|
return (await this.channel.assertQueue(this.parameters.queue)).messageCount;
|
|
59
79
|
}
|
|
60
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Purge the queue, used by tests
|
|
82
|
+
*/
|
|
83
|
+
async __clean() {
|
|
61
84
|
await this.channel.purgeQueue(this.parameters.queue);
|
|
62
85
|
}
|
|
63
86
|
}
|
|
64
|
-
|
|
87
|
+
export { AMQPQueue };
|
|
88
|
+
//# sourceMappingURL=queue.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.service.js","sourceRoot":"","sources":["../src/queue.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;CAcvD;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAwE,SAAQ,KAAW;IAI9G;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;YACtB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;YACzB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC5B,oBAAoB;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,KAAQ;QACxB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAI,KAAmB;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO;YACL;gBACE,aAAa,EAAO,GAAG;gBACvB,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC;aACzD;SACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,EAAU;QAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAM,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;CACF;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webda/amqp",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.3",
|
|
4
4
|
"description": "Implements AMQP on webda",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"activemq",
|
|
@@ -10,36 +10,15 @@
|
|
|
10
10
|
"repository": "git://github.com/loopingz/webda.io.git",
|
|
11
11
|
"main": "lib/index.js",
|
|
12
12
|
"typings": "lib/index.d.ts",
|
|
13
|
-
"scripts": {
|
|
14
|
-
"build": "webda build",
|
|
15
|
-
"build:watch": "webda build --watch",
|
|
16
|
-
"pretest": "npm run build",
|
|
17
|
-
"lint": "eslint",
|
|
18
|
-
"lint:fix": "eslint --fix",
|
|
19
|
-
"test": "c8 mocha",
|
|
20
|
-
"format": "prettier --check src/**/*",
|
|
21
|
-
"format:fix": "prettier --write src/**/*"
|
|
22
|
-
},
|
|
23
13
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
14
|
+
"amqplib": "^0.10.9",
|
|
15
|
+
"@webda/core": "4.0.0-beta.3",
|
|
16
|
+
"@webda/utils": "4.0.0-beta.3"
|
|
26
17
|
},
|
|
27
18
|
"files": [
|
|
28
19
|
"lib",
|
|
29
20
|
"webda.module.json"
|
|
30
21
|
],
|
|
31
|
-
"c8": {
|
|
32
|
-
"report-dir": "./reports",
|
|
33
|
-
"reporter": [
|
|
34
|
-
"html",
|
|
35
|
-
"lcov",
|
|
36
|
-
"json",
|
|
37
|
-
"text"
|
|
38
|
-
],
|
|
39
|
-
"exclude": [
|
|
40
|
-
"**/*.spec.ts"
|
|
41
|
-
]
|
|
42
|
-
},
|
|
43
22
|
"homepage": "https://webda.io",
|
|
44
23
|
"publishConfig": {
|
|
45
24
|
"access": "public"
|
|
@@ -48,23 +27,38 @@
|
|
|
48
27
|
"namespace": "Webda"
|
|
49
28
|
},
|
|
50
29
|
"devDependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"@types/
|
|
53
|
-
"@
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"tsx": "^4.
|
|
30
|
+
"@types/amqplib": "^0.10.8",
|
|
31
|
+
"@types/node": "25.5.0",
|
|
32
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
33
|
+
"jscodeshift": "^17.3.0",
|
|
34
|
+
"skott": "^0.35.8",
|
|
35
|
+
"tsx": "^4.21.0",
|
|
36
|
+
"typescript": "7.1.0-dev.20260929.1",
|
|
37
|
+
"vite": "^6.0.0",
|
|
38
|
+
"vitest": "^4.1.2",
|
|
39
|
+
"@webda/test": "4.0.0-beta.3",
|
|
40
|
+
"@webda/compiler": "^4.0.0-beta.3"
|
|
57
41
|
},
|
|
58
42
|
"nx": {
|
|
59
43
|
"implicitDependencies": [
|
|
60
|
-
"@webda/core"
|
|
61
|
-
"@webda/shell"
|
|
44
|
+
"@webda/core"
|
|
62
45
|
]
|
|
63
46
|
},
|
|
64
47
|
"type": "module",
|
|
65
48
|
"engines": {
|
|
66
|
-
"node": ">=
|
|
49
|
+
"node": ">=22.0.0"
|
|
67
50
|
},
|
|
68
51
|
"license": "LGPL-3.0-only",
|
|
69
|
-
"
|
|
70
|
-
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "webdac build",
|
|
54
|
+
"build:watch": "webdac build --watch",
|
|
55
|
+
"pretest": "npm run build",
|
|
56
|
+
"lint": "eslint",
|
|
57
|
+
"lint:fix": "eslint --fix",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"format": "prettier --check src/**/*",
|
|
60
|
+
"format:fix": "prettier --write src/**/*",
|
|
61
|
+
"deps:graph": "skott --showCircularDependencies --no-trackTypeOnlyDependencies --displayMode=raw -e .ts",
|
|
62
|
+
"codemod": "jscodeshift --parser=ts --extensions=tsx,ts -t ../codemod/current.mjs src"
|
|
63
|
+
}
|
|
64
|
+
}
|
package/webda.module.json
CHANGED
|
@@ -1,166 +1,193 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://webda.io/schemas/webda.module.v4.json",
|
|
2
3
|
"beans": {},
|
|
3
4
|
"deployers": {},
|
|
4
5
|
"moddas": {
|
|
5
|
-
"Webda/AMQPPubSub": "lib/pubsub:default",
|
|
6
|
-
"Webda/AMQPQueue": "lib/queue:default"
|
|
7
|
-
},
|
|
8
|
-
"models": {
|
|
9
|
-
"graph": {},
|
|
10
|
-
"tree": {},
|
|
11
|
-
"plurals": {},
|
|
12
|
-
"list": {},
|
|
13
|
-
"reflections": {}
|
|
14
|
-
},
|
|
15
|
-
"schemas": {
|
|
16
6
|
"Webda/AMQPPubSub": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
7
|
+
"Import": "lib/pubsub.service:default",
|
|
8
|
+
"Schema": {
|
|
9
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"definitions": {
|
|
12
|
+
"exchange": {
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"alternateExchange": {
|
|
16
|
+
"description": "an exchange to send messages to if this exchange can’t route them to any queues.\n\nSpecific to RabbitMQ",
|
|
17
|
+
"type": "string"
|
|
18
|
+
},
|
|
19
|
+
"arguments": {
|
|
20
|
+
"description": "any additional arguments that may be needed by an exchange"
|
|
21
|
+
},
|
|
22
|
+
"autoDelete": {
|
|
23
|
+
"default": false,
|
|
24
|
+
"description": "if true, the exchange will be destroyed once the number of bindings for which it is the source drop to zero.",
|
|
25
|
+
"type": "boolean"
|
|
26
|
+
},
|
|
27
|
+
"durable": {
|
|
28
|
+
"default": true,
|
|
29
|
+
"description": "if true, the exchange will survive broker restarts.",
|
|
30
|
+
"type": "boolean"
|
|
31
|
+
},
|
|
32
|
+
"internal": {
|
|
33
|
+
"default": false,
|
|
34
|
+
"description": "if true, messages cannot be published directly to the exchange\n(i.e., it can only be the target of bindings, or possibly create messages ex-nihilo).",
|
|
35
|
+
"type": "boolean"
|
|
36
|
+
},
|
|
37
|
+
"type": {
|
|
38
|
+
"default": "fanout",
|
|
39
|
+
"type": "string"
|
|
40
|
+
}
|
|
40
41
|
},
|
|
41
|
-
"
|
|
42
|
-
"type": "boolean",
|
|
43
|
-
"description": "if true, the exchange will survive broker restarts.",
|
|
44
|
-
"default": true
|
|
45
|
-
},
|
|
46
|
-
"internal": {
|
|
47
|
-
"type": "boolean",
|
|
48
|
-
"description": "if true, messages cannot be published directly to the exchange (i.e., it can only be the target of bindings, or possibly create messages ex-nihilo).",
|
|
49
|
-
"default": false
|
|
50
|
-
},
|
|
51
|
-
"autoDelete": {
|
|
52
|
-
"type": "boolean",
|
|
53
|
-
"description": "if true, the exchange will be destroyed once the number of bindings for which it is the source drop to zero.",
|
|
54
|
-
"default": false
|
|
55
|
-
},
|
|
56
|
-
"alternateExchange": {
|
|
57
|
-
"type": "string",
|
|
58
|
-
"description": "an exchange to send messages to if this exchange can’t route them to any queues.\n\nSpecific to RabbitMQ"
|
|
59
|
-
},
|
|
60
|
-
"arguments": {
|
|
61
|
-
"description": "any additional arguments that may be needed by an exchange"
|
|
62
|
-
}
|
|
42
|
+
"type": "object"
|
|
63
43
|
}
|
|
64
44
|
},
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
45
|
+
"description": "Configuration for {@link AMQPPubSubService}",
|
|
46
|
+
"properties": {
|
|
47
|
+
"channel": {
|
|
48
|
+
"description": "Exchange name to publish to and consume from",
|
|
49
|
+
"type": "string"
|
|
50
|
+
},
|
|
51
|
+
"exchange": {
|
|
52
|
+
"$ref": "#/definitions/exchange"
|
|
53
|
+
},
|
|
54
|
+
"subscription": {
|
|
55
|
+
"default": "",
|
|
56
|
+
"description": "Queue name used to subscribe, empty to let the broker generate one",
|
|
57
|
+
"type": "string"
|
|
58
|
+
},
|
|
59
|
+
"type": {
|
|
60
|
+
"description": "Type of the service",
|
|
61
|
+
"type": "string"
|
|
62
|
+
},
|
|
63
|
+
"url": {
|
|
64
|
+
"description": "AMQP connection url",
|
|
65
|
+
"example": "amqp://localhost:5672",
|
|
66
|
+
"type": "string"
|
|
67
|
+
},
|
|
68
|
+
"openapi": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"additionalProperties": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"required": [
|
|
74
|
+
"channel",
|
|
75
|
+
"type",
|
|
76
|
+
"url"
|
|
77
|
+
],
|
|
78
|
+
"type": "object",
|
|
79
|
+
"title": "AMQPPubSubService"
|
|
69
80
|
},
|
|
70
|
-
"
|
|
71
|
-
"channel",
|
|
72
|
-
"type",
|
|
73
|
-
"url"
|
|
74
|
-
],
|
|
75
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
76
|
-
"title": "AMQPPubSubService"
|
|
81
|
+
"Configuration": "lib/pubsub.service:AMQPPubSubParameters"
|
|
77
82
|
},
|
|
78
83
|
"Webda/AMQPQueue": {
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
"Import": "lib/queue.service:default",
|
|
85
|
+
"Schema": {
|
|
86
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"definitions": {
|
|
89
|
+
"WaitDelayerDefinition": {
|
|
90
|
+
"additionalProperties": false,
|
|
91
|
+
"description": "Configuration object for selecting and parameterizing a `WaitDelayer` from the registry.",
|
|
92
|
+
"properties": {
|
|
93
|
+
"interval": {
|
|
94
|
+
"description": "Base interval in milliseconds passed to the delayer factory.",
|
|
95
|
+
"type": "number"
|
|
96
|
+
},
|
|
97
|
+
"type": {
|
|
98
|
+
"description": "Key identifying the factory in `WaitDelayerFactories.registry` (e.g. `\"linear\"`, `\"exponential\"`).",
|
|
99
|
+
"type": "string"
|
|
100
|
+
}
|
|
95
101
|
},
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"interval",
|
|
103
|
-
"type"
|
|
104
|
-
],
|
|
105
|
-
"description": "Delayer between two failed attempts to process messages"
|
|
106
|
-
},
|
|
107
|
-
"workerParallelism": {
|
|
108
|
-
"type": "boolean",
|
|
109
|
-
"description": "Define if worker should process multi message received in //",
|
|
110
|
-
"default": true
|
|
111
|
-
},
|
|
112
|
-
"maxConsumers": {
|
|
113
|
-
"type": "number",
|
|
114
|
-
"description": "Max number of queue consumers Queue will auto increase to this max number if queue is loaded and it will decrease to just one consumer if no messages are available",
|
|
115
|
-
"default": 10
|
|
102
|
+
"required": [
|
|
103
|
+
"interval",
|
|
104
|
+
"type"
|
|
105
|
+
],
|
|
106
|
+
"type": "object"
|
|
107
|
+
}
|
|
116
108
|
},
|
|
117
|
-
"
|
|
118
|
-
|
|
109
|
+
"description": "Configuration for {@link AMQPQueue}",
|
|
110
|
+
"properties": {
|
|
111
|
+
"maxConsumers": {
|
|
112
|
+
"default": 10,
|
|
113
|
+
"description": "Max number of queue consumers\nQueue will auto increase to this max number if queue is loaded\nand it will decrease to just one consumer if no messages are available",
|
|
114
|
+
"type": "number"
|
|
115
|
+
},
|
|
116
|
+
"queue": {
|
|
117
|
+
"description": "Queue name",
|
|
118
|
+
"type": "string"
|
|
119
|
+
},
|
|
120
|
+
"queueOptions": {
|
|
121
|
+
"description": "Options passed to assertQueue"
|
|
122
|
+
},
|
|
123
|
+
"type": {
|
|
124
|
+
"description": "Type of the service",
|
|
125
|
+
"type": "string"
|
|
126
|
+
},
|
|
127
|
+
"url": {
|
|
128
|
+
"description": "AMQP connection url",
|
|
129
|
+
"example": "amqp://localhost:5672",
|
|
130
|
+
"type": "string"
|
|
131
|
+
},
|
|
132
|
+
"workerDelayer": {
|
|
133
|
+
"$ref": "#/definitions/WaitDelayerDefinition",
|
|
134
|
+
"description": "Delayer between two failed attempts to process messages"
|
|
135
|
+
},
|
|
136
|
+
"workerParallelism": {
|
|
137
|
+
"default": true,
|
|
138
|
+
"description": "Define if worker should process multi message received in //",
|
|
139
|
+
"type": "boolean"
|
|
140
|
+
},
|
|
141
|
+
"openapi": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"additionalProperties": true
|
|
144
|
+
}
|
|
119
145
|
},
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
"type"
|
|
123
|
-
"
|
|
124
|
-
|
|
146
|
+
"required": [
|
|
147
|
+
"queue",
|
|
148
|
+
"type",
|
|
149
|
+
"url"
|
|
150
|
+
],
|
|
151
|
+
"type": "object",
|
|
152
|
+
"title": "AMQPQueue"
|
|
125
153
|
},
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
],
|
|
132
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
133
|
-
"title": "AMQPQueue"
|
|
134
|
-
},
|
|
154
|
+
"Configuration": "lib/queue.service:AMQPQueueParameters"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"models": {},
|
|
158
|
+
"schemas": {
|
|
135
159
|
"Webda/BinaryFile": {
|
|
136
|
-
"
|
|
160
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
161
|
+
"WebdaSchema": true,
|
|
162
|
+
"additionalProperties": false,
|
|
163
|
+
"description": "Represent a file to store",
|
|
137
164
|
"properties": {
|
|
138
|
-
"hash": {
|
|
139
|
-
"type": "string",
|
|
140
|
-
"description": "Will be computed by the service\n\nhash of the content"
|
|
141
|
-
},
|
|
142
165
|
"challenge": {
|
|
143
|
-
"
|
|
144
|
-
"
|
|
166
|
+
"description": "Will be computed by the service\n\nhash of the content prefixed by 'WEBDA'",
|
|
167
|
+
"type": "string"
|
|
145
168
|
},
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"
|
|
169
|
+
"hash": {
|
|
170
|
+
"description": "Will be computed by the service\n\nhash of the content",
|
|
171
|
+
"type": "string"
|
|
149
172
|
},
|
|
150
|
-
"
|
|
151
|
-
"
|
|
152
|
-
"description": "Current name"
|
|
173
|
+
"metadata": {
|
|
174
|
+
"description": "Metadatas stored along with the binary"
|
|
153
175
|
},
|
|
154
176
|
"mimetype": {
|
|
155
|
-
"
|
|
156
|
-
"
|
|
177
|
+
"description": "Mimetype of the binary",
|
|
178
|
+
"type": "string"
|
|
157
179
|
},
|
|
158
|
-
"
|
|
159
|
-
"description": "
|
|
180
|
+
"name": {
|
|
181
|
+
"description": "Current name",
|
|
182
|
+
"type": "string"
|
|
160
183
|
},
|
|
161
184
|
"originalname": {
|
|
162
|
-
"
|
|
163
|
-
"
|
|
185
|
+
"description": "Original name",
|
|
186
|
+
"type": "string"
|
|
187
|
+
},
|
|
188
|
+
"size": {
|
|
189
|
+
"description": "Size of the binary",
|
|
190
|
+
"type": "number"
|
|
164
191
|
}
|
|
165
192
|
},
|
|
166
193
|
"required": [
|
|
@@ -168,9 +195,9 @@
|
|
|
168
195
|
"name",
|
|
169
196
|
"size"
|
|
170
197
|
],
|
|
171
|
-
"
|
|
172
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
198
|
+
"type": "object",
|
|
173
199
|
"title": "BinaryFile"
|
|
174
200
|
}
|
|
175
|
-
}
|
|
201
|
+
},
|
|
202
|
+
"behaviors": {}
|
|
176
203
|
}
|
package/lib/pubsub.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pubsub.d.ts","sourceRoot":"","sources":["../src/pubsub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAa,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,qBAAa,oBAAqB,SAAQ,iBAAiB;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QACd;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;;;WAIG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB;;;WAGG;QACH,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB;;;;WAIG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B;;WAEG;QACH,SAAS,CAAC,EAAE,GAAG,CAAC;KACjB,CAAC;gBAEU,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC;CAMlD;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB,CACpC,CAAC,GAAG,GAAG,EACP,CAAC,SAAS,oBAAoB,GAAG,oBAAoB,CACrD,SAAQ,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC;IACzB,QAAQ,EAAE,GAAG,CAAC;IAEd;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,GAAG;IAI1B;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B;;;;;OAKG;IACH,OAAO,CACL,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EACrC,cAAc,CAAC,EAAE;QAAE,QAAQ,CAAC,CAAA;KAAE,EAC9B,MAAM,CAAC,EAAE,MAAM,IAAI,GAClB,iBAAiB;CAwCrB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
package/lib/pubsub.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../src/pubsub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,MAAM,OAAO,oBAAqB,SAAQ,iBAAiB;IAyCzD,YAAY,MAAqC;;QAC/C,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,QAAQ,KAAb,IAAI,CAAC,QAAQ,GAAK,EAAE,EAAC;QACrB,MAAA,IAAI,CAAC,QAAQ,EAAC,IAAI,QAAJ,IAAI,GAAK,QAAQ,EAAC;QAChC,IAAI,CAAC,YAAY,KAAjB,IAAI,CAAC,YAAY,GAAK,EAAE,EAAC;IAC3B,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,iBAGnB,SAAQ,aAAmB;IAK3B;;OAEG;IACH,cAAc,CAAC,MAAW;QACxB,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAQ,EAAE,aAAqB,EAAE;QACjD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3G,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,EACvB,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,IAAI,QAAQ,EAC1C,MAAM,CACP,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC;IACrF,CAAC;IAED;;;;;OAKG;IACH,OAAO,CACL,QAAqC,EACrC,cAA8B,EAC9B,MAAmB;QAEnB,IAAI,WAAmB,CAAC;QACxB,OAAO,IAAI,iBAAiB,CAC1B,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE;gBACzE,SAAS,EAAE,IAAI;gBACf,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACxE,WAAW,GAAG,CACZ,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;gBAClD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;oBACjB,MAAM,CAAC,qBAAqB,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC;gBAC1D,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;oBAChF,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;oBAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC7E,CAAC;wBAAS,CAAC;oBACT,GAAG,EAAE,CAAC;gBACR,CAAC;YACH,CAAC,CAAC,CACH,CAAC,WAAW,CAAC;YACd,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC,EACD,KAAK,IAAI,EAAE;YACT,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
package/lib/pubsub.spec.d.ts
DELETED
package/lib/pubsub.spec.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pubsub.spec.d.ts","sourceRoot":"","sources":["../src/pubsub.spec.ts"],"names":[],"mappings":""}
|
package/lib/pubsub.spec.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { suite, test } from "@testdeck/mocha";
|
|
8
|
-
import { WaitFor, WaitLinearDelay } from "@webda/core";
|
|
9
|
-
import { WebdaSimpleTest } from "@webda/core/lib/test.js";
|
|
10
|
-
import * as assert from "assert";
|
|
11
|
-
import * as sinon from "sinon";
|
|
12
|
-
import { AMQPPubSubParameters, AMQPPubSubService } from "./pubsub.js";
|
|
13
|
-
let AMQPPubSubTest = class AMQPPubSubTest extends WebdaSimpleTest {
|
|
14
|
-
async before() {
|
|
15
|
-
await super.before();
|
|
16
|
-
this.pubsub = await this.addService(AMQPPubSubService, {
|
|
17
|
-
endpoint: "amqp://localhost:5672",
|
|
18
|
-
channel: "webda-test-pub",
|
|
19
|
-
maxConsumers: 1
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
async params() {
|
|
23
|
-
// just for cov
|
|
24
|
-
const p = new AMQPPubSubParameters({
|
|
25
|
-
exchange: {
|
|
26
|
-
type: "fanout2"
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
assert.strictEqual(p.exchange?.type, "fanout2");
|
|
30
|
-
}
|
|
31
|
-
async basic() {
|
|
32
|
-
let counter = 0;
|
|
33
|
-
const consumers = [];
|
|
34
|
-
await new Promise(resolve => {
|
|
35
|
-
consumers.push(this.pubsub.consume(async (evt) => {
|
|
36
|
-
counter++;
|
|
37
|
-
if (counter > 2) {
|
|
38
|
-
throw new Error("Only consume 2");
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
consumers.push(this.pubsub.consume(async (evt) => {
|
|
42
|
-
counter++;
|
|
43
|
-
}, undefined, resolve));
|
|
44
|
-
});
|
|
45
|
-
await this.pubsub.sendMessage("plop");
|
|
46
|
-
await this.pubsub.size();
|
|
47
|
-
await WaitFor(async (resolve) => {
|
|
48
|
-
if (counter === 2) {
|
|
49
|
-
resolve();
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
}, 10, "Events", undefined, WaitLinearDelay(10));
|
|
54
|
-
assert.strictEqual(counter, 2);
|
|
55
|
-
await this.pubsub.sendMessage("error");
|
|
56
|
-
await WaitFor(async (resolve) => {
|
|
57
|
-
if (counter === 4) {
|
|
58
|
-
resolve();
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
}, 10, "Events error", undefined, WaitLinearDelay(10));
|
|
63
|
-
await Promise.all(consumers.map(p => p.cancel()));
|
|
64
|
-
// Hack our way to test close by server
|
|
65
|
-
// @ts-ignore
|
|
66
|
-
const stub = sinon.stub(this.pubsub.channel, "consume").callsFake((ex, call) => {
|
|
67
|
-
call(null);
|
|
68
|
-
});
|
|
69
|
-
// Should reject
|
|
70
|
-
await assert.rejects(() => this.pubsub.consume(async (evt) => {
|
|
71
|
-
counter++;
|
|
72
|
-
}), /Cancelled by server/);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
__decorate([
|
|
76
|
-
test
|
|
77
|
-
], AMQPPubSubTest.prototype, "params", null);
|
|
78
|
-
__decorate([
|
|
79
|
-
test
|
|
80
|
-
], AMQPPubSubTest.prototype, "basic", null);
|
|
81
|
-
AMQPPubSubTest = __decorate([
|
|
82
|
-
suite
|
|
83
|
-
], AMQPPubSubTest);
|
|
84
|
-
//# sourceMappingURL=pubsub.spec.js.map
|
package/lib/pubsub.spec.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pubsub.spec.js","sourceRoot":"","sources":["../src/pubsub.spec.ts"],"names":[],"mappings":"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"}
|
package/lib/queue.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { MessageReceipt, Queue, QueueParameters } from "@webda/core";
|
|
2
|
-
export declare class AMQPQueueParameters extends QueueParameters {
|
|
3
|
-
url: string;
|
|
4
|
-
queue: string;
|
|
5
|
-
queueOptions?: any;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Implements a Queue stored in AMQP
|
|
9
|
-
*
|
|
10
|
-
* @WebdaModda
|
|
11
|
-
*/
|
|
12
|
-
export default class AMQPQueue<T = any, K extends AMQPQueueParameters = AMQPQueueParameters> extends Queue<T, K> {
|
|
13
|
-
channel: any;
|
|
14
|
-
conn: any;
|
|
15
|
-
/**
|
|
16
|
-
* @override
|
|
17
|
-
*/
|
|
18
|
-
loadParameters(params: any): AMQPQueueParameters;
|
|
19
|
-
/**
|
|
20
|
-
* @override
|
|
21
|
-
*/
|
|
22
|
-
init(): Promise<this>;
|
|
23
|
-
/**
|
|
24
|
-
* @override
|
|
25
|
-
*/
|
|
26
|
-
sendMessage(event: T): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* @override
|
|
29
|
-
*/
|
|
30
|
-
receiveMessage<L>(proto?: new () => L): Promise<MessageReceipt<L>[]>;
|
|
31
|
-
/**
|
|
32
|
-
* @override
|
|
33
|
-
*/
|
|
34
|
-
deleteMessage(id: string): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* @override
|
|
37
|
-
*/
|
|
38
|
-
size(): Promise<number>;
|
|
39
|
-
___cleanData(): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=queue.d.ts.map
|
package/lib/queue.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhF,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,GAAG,CAAC;CACpB;AACD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAS,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,mBAAmB,GAAG,mBAAmB,CAAE,SAAQ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9G,OAAO,EAAE,GAAG,CAAC;IACb,IAAI,EAAE,GAAG,CAAC;IACV;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,GAAG;IAI1B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C;;OAEG;IACG,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAa1E;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvB,YAAY;CAGnB"}
|
package/lib/queue.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,MAAM,OAAO,mBAAoB,SAAQ,eAAe;CAIvD;AACD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAwE,SAAQ,KAAW;IAG9G;;OAEG;IACH,cAAc,CAAC,MAAW;QACxB,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAQ;QACxB,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjG,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAI,KAAmB;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO;YACL;gBACE,aAAa,EAAE,GAAG;gBAClB,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC;aACzD;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,EAAU;QAC5B,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;CACF"}
|
package/lib/queue.spec.d.ts
DELETED
package/lib/queue.spec.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.spec.d.ts","sourceRoot":"","sources":["../src/queue.spec.ts"],"names":[],"mappings":""}
|
package/lib/queue.spec.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { suite, test } from "@testdeck/mocha";
|
|
8
|
-
import { QueueTest } from "@webda/core/lib/queues/queue.spec.js";
|
|
9
|
-
import * as assert from "assert";
|
|
10
|
-
import AMQPQueue from "./queue.js";
|
|
11
|
-
let AMQPQueueTest = class AMQPQueueTest extends QueueTest {
|
|
12
|
-
async basic() {
|
|
13
|
-
const queue = await this.addService(AMQPQueue, {
|
|
14
|
-
endpoint: "amqp://localhost:5672",
|
|
15
|
-
queue: "webda-test",
|
|
16
|
-
maxConsumers: 1
|
|
17
|
-
});
|
|
18
|
-
await queue.__clean();
|
|
19
|
-
await this.simple(queue, true);
|
|
20
|
-
assert.deepStrictEqual(await queue.receiveMessage(), []);
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
__decorate([
|
|
24
|
-
test
|
|
25
|
-
], AMQPQueueTest.prototype, "basic", null);
|
|
26
|
-
AMQPQueueTest = __decorate([
|
|
27
|
-
suite
|
|
28
|
-
], AMQPQueueTest);
|
|
29
|
-
//# sourceMappingURL=queue.spec.js.map
|
package/lib/queue.spec.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.spec.js","sourceRoot":"","sources":["../src/queue.spec.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,SAAS,MAAM,SAAS,CAAC;AAGhC,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,SAAS;IAE7B,AAAN,KAAK,CAAC,KAAK;QACT,MAAM,KAAK,GAAc,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE;YACxD,QAAQ,EAAE,uBAAuB;YACjC,KAAK,EAAE,YAAY;YACnB,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF,CAAA;AAVO;IADL,IAAI;0CAUJ;AAXG,aAAa;IADlB,KAAK;GACA,aAAa,CAYlB"}
|