@diia-inhouse/diia-queue 13.3.4 → 14.0.10

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.
Files changed (148) hide show
  1. package/dist/constants.js +9 -9
  2. package/dist/index.d.ts +27 -0
  3. package/dist/index.js +23 -21
  4. package/dist/interfaces/deps.d.ts +30 -0
  5. package/dist/interfaces/externalCommunicator.d.ts +58 -0
  6. package/dist/interfaces/index.d.ts +95 -0
  7. package/dist/interfaces/index.js +7 -30
  8. package/dist/interfaces/messageBrokerServiceConfig.d.ts +80 -0
  9. package/dist/interfaces/messageBrokerServiceConfig.js +27 -24
  10. package/dist/interfaces/messageHandler.d.ts +6 -0
  11. package/dist/interfaces/metrics/index.d.ts +23 -0
  12. package/dist/interfaces/metrics/index.js +12 -16
  13. package/dist/interfaces/options.d.ts +52 -0
  14. package/dist/interfaces/providers/rabbitmq/amqpConnection.d.ts +33 -0
  15. package/dist/interfaces/providers/rabbitmq/amqpConnection.js +14 -17
  16. package/dist/interfaces/providers/rabbitmq/amqpPublisher.d.ts +20 -0
  17. package/dist/interfaces/providers/rabbitmq/index.d.ts +107 -0
  18. package/dist/interfaces/providers/rabbitmq/index.js +35 -47
  19. package/dist/interfaces/queueConfig/configs.d.ts +47 -0
  20. package/dist/interfaces/queueConfig/configs.js +8 -9
  21. package/dist/interfaces/queueConfig/index.d.ts +1 -0
  22. package/dist/interfaces/queueContext.d.ts +8 -0
  23. package/dist/interfaces/queueStatus.d.ts +15 -0
  24. package/dist/interfaces/queueStatus.js +8 -9
  25. package/dist/metrics/index.js +5 -8
  26. package/dist/providers/index.d.ts +5 -0
  27. package/dist/providers/index.js +6 -22
  28. package/dist/providers/rabbitmq/amqpAsserter.d.ts +53 -0
  29. package/dist/providers/rabbitmq/amqpAsserter.js +369 -416
  30. package/dist/providers/rabbitmq/amqpConnection.d.ts +24 -0
  31. package/dist/providers/rabbitmq/amqpConnection.js +97 -150
  32. package/dist/providers/rabbitmq/amqpListener.d.ts +47 -0
  33. package/dist/providers/rabbitmq/amqpListener.js +218 -225
  34. package/dist/providers/rabbitmq/amqpPublisher.d.ts +38 -0
  35. package/dist/providers/rabbitmq/amqpPublisher.js +184 -191
  36. package/dist/providers/rabbitmq/index.d.ts +56 -0
  37. package/dist/providers/rabbitmq/index.js +161 -186
  38. package/dist/services/communicator.d.ts +66 -0
  39. package/dist/services/communicator.js +164 -186
  40. package/dist/services/eventBus.d.ts +25 -0
  41. package/dist/services/eventBus.js +45 -57
  42. package/dist/services/eventCommunicator.js +75 -124
  43. package/dist/services/eventMessageHandler.d.ts +25 -0
  44. package/dist/services/eventMessageHandler.js +112 -129
  45. package/dist/services/eventMessageValidator.d.ts +13 -0
  46. package/dist/services/eventMessageValidator.js +59 -44
  47. package/dist/services/externalCommunicator.d.ts +114 -0
  48. package/dist/services/externalCommunicator.js +149 -140
  49. package/dist/services/externalEventBus.d.ts +39 -0
  50. package/dist/services/externalEventBus.js +144 -162
  51. package/dist/services/index.d.ts +8 -0
  52. package/dist/services/index.js +10 -26
  53. package/dist/services/metrics.d.ts +15 -0
  54. package/dist/services/metrics.js +46 -49
  55. package/dist/services/optionsBuilder.d.ts +14 -0
  56. package/dist/services/optionsBuilder.js +43 -58
  57. package/dist/services/queue.d.ts +29 -0
  58. package/dist/services/queue.js +78 -93
  59. package/dist/services/scheduledTask.d.ts +30 -0
  60. package/dist/services/scheduledTask.js +60 -68
  61. package/dist/services/task.d.ts +33 -0
  62. package/dist/services/task.js +160 -176
  63. package/dist/utils.js +7 -11
  64. package/package.json +44 -50
  65. package/dist/constants.js.map +0 -1
  66. package/dist/index.js.map +0 -1
  67. package/dist/interfaces/deps.js +0 -3
  68. package/dist/interfaces/deps.js.map +0 -1
  69. package/dist/interfaces/externalCommunicator.js +0 -3
  70. package/dist/interfaces/externalCommunicator.js.map +0 -1
  71. package/dist/interfaces/index.js.map +0 -1
  72. package/dist/interfaces/messageBrokerServiceConfig.js.map +0 -1
  73. package/dist/interfaces/messageHandler.js +0 -3
  74. package/dist/interfaces/messageHandler.js.map +0 -1
  75. package/dist/interfaces/metrics/index.js.map +0 -1
  76. package/dist/interfaces/options.js +0 -3
  77. package/dist/interfaces/options.js.map +0 -1
  78. package/dist/interfaces/providers/rabbitmq/amqpConnection.js.map +0 -1
  79. package/dist/interfaces/providers/rabbitmq/amqpPublisher.js +0 -4
  80. package/dist/interfaces/providers/rabbitmq/amqpPublisher.js.map +0 -1
  81. package/dist/interfaces/providers/rabbitmq/index.js.map +0 -1
  82. package/dist/interfaces/queueConfig/configs.js.map +0 -1
  83. package/dist/interfaces/queueConfig/index.js +0 -18
  84. package/dist/interfaces/queueConfig/index.js.map +0 -1
  85. package/dist/interfaces/queueContext.js +0 -3
  86. package/dist/interfaces/queueContext.js.map +0 -1
  87. package/dist/interfaces/queueStatus.js.map +0 -1
  88. package/dist/interfaces/services/eventMessageHandler.js +0 -3
  89. package/dist/interfaces/services/eventMessageHandler.js.map +0 -1
  90. package/dist/metrics/index.js.map +0 -1
  91. package/dist/providers/index.js.map +0 -1
  92. package/dist/providers/rabbitmq/amqpAsserter.js.map +0 -1
  93. package/dist/providers/rabbitmq/amqpConnection.js.map +0 -1
  94. package/dist/providers/rabbitmq/amqpListener.js.map +0 -1
  95. package/dist/providers/rabbitmq/amqpPublisher.js.map +0 -1
  96. package/dist/providers/rabbitmq/index.js.map +0 -1
  97. package/dist/services/communicator.js.map +0 -1
  98. package/dist/services/eventBus.js.map +0 -1
  99. package/dist/services/eventCommunicator.js.map +0 -1
  100. package/dist/services/eventMessageHandler.js.map +0 -1
  101. package/dist/services/eventMessageValidator.js.map +0 -1
  102. package/dist/services/externalCommunicator.js.map +0 -1
  103. package/dist/services/externalEventBus.js.map +0 -1
  104. package/dist/services/index.js.map +0 -1
  105. package/dist/services/metrics.js.map +0 -1
  106. package/dist/services/optionsBuilder.js.map +0 -1
  107. package/dist/services/queue.js.map +0 -1
  108. package/dist/services/scheduledTask.js.map +0 -1
  109. package/dist/services/task.js.map +0 -1
  110. package/dist/types/constants.d.ts +0 -8
  111. package/dist/types/index.d.ts +0 -4
  112. package/dist/types/interfaces/deps.d.ts +0 -26
  113. package/dist/types/interfaces/externalCommunicator.d.ts +0 -54
  114. package/dist/types/interfaces/index.d.ts +0 -99
  115. package/dist/types/interfaces/messageBrokerServiceConfig.d.ts +0 -79
  116. package/dist/types/interfaces/messageHandler.d.ts +0 -2
  117. package/dist/types/interfaces/metrics/index.d.ts +0 -20
  118. package/dist/types/interfaces/options.d.ts +0 -49
  119. package/dist/types/interfaces/providers/rabbitmq/amqpConnection.d.ts +0 -29
  120. package/dist/types/interfaces/providers/rabbitmq/amqpPublisher.d.ts +0 -16
  121. package/dist/types/interfaces/providers/rabbitmq/index.d.ts +0 -114
  122. package/dist/types/interfaces/queueConfig/configs.d.ts +0 -47
  123. package/dist/types/interfaces/queueConfig/index.d.ts +0 -1
  124. package/dist/types/interfaces/queueContext.d.ts +0 -4
  125. package/dist/types/interfaces/queueStatus.d.ts +0 -11
  126. package/dist/types/interfaces/services/eventMessageHandler.d.ts +0 -5
  127. package/dist/types/metrics/index.d.ts +0 -3
  128. package/dist/types/providers/index.d.ts +0 -5
  129. package/dist/types/providers/rabbitmq/amqpAsserter.d.ts +0 -49
  130. package/dist/types/providers/rabbitmq/amqpConnection.d.ts +0 -20
  131. package/dist/types/providers/rabbitmq/amqpListener.d.ts +0 -42
  132. package/dist/types/providers/rabbitmq/amqpPublisher.d.ts +0 -34
  133. package/dist/types/providers/rabbitmq/index.d.ts +0 -52
  134. package/dist/types/services/communicator.d.ts +0 -57
  135. package/dist/types/services/eventBus.d.ts +0 -20
  136. package/dist/types/services/eventCommunicator.d.ts +0 -15
  137. package/dist/types/services/eventMessageHandler.d.ts +0 -19
  138. package/dist/types/services/eventMessageValidator.d.ts +0 -9
  139. package/dist/types/services/externalCommunicator.d.ts +0 -110
  140. package/dist/types/services/externalEventBus.d.ts +0 -33
  141. package/dist/types/services/index.d.ts +0 -9
  142. package/dist/types/services/metrics.d.ts +0 -11
  143. package/dist/types/services/optionsBuilder.d.ts +0 -10
  144. package/dist/types/services/queue.d.ts +0 -23
  145. package/dist/types/services/scheduledTask.d.ts +0 -25
  146. package/dist/types/services/task.d.ts +0 -28
  147. package/dist/types/utils.d.ts +0 -3
  148. package/dist/utils.js.map +0 -1
@@ -1,140 +1,149 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExternalCommunicator = void 0;
4
- const node_crypto_1 = require("node:crypto");
5
- const errors_1 = require("@diia-inhouse/errors");
6
- class ExternalCommunicator {
7
- externalEventBus;
8
- eventMessageValidator;
9
- logger;
10
- constructor(externalEventBus, eventMessageValidator, logger) {
11
- this.externalEventBus = externalEventBus;
12
- this.eventMessageValidator = eventMessageValidator;
13
- this.logger = logger;
14
- }
15
- /**
16
- * Synchronous request/response over the external event bus.
17
- *
18
- * Publishes `event` to the configured external exchange wrapped as
19
- * `{ uuid, request }` and awaits the subscriber's response on the same call.
20
- * The response envelope is validated against `ops.validationRules`, and any embedded error is rethrown as
21
- * {@link ExternalCommunicatorError}.
22
- *
23
- * Use this when the caller needs the response inline (e.g. a user-facing
24
- * request that must block on `AGateway`). For fire-and-forget or fan-out
25
- * flows, use the `default` publish + listener pattern instead.
26
- *
27
- * ### Transport
28
- *
29
- * Implemented on top of RabbitMQ's
30
- * [direct reply-to](https://www.rabbitmq.com/docs/direct-reply-to)
31
- * feature: the publisher consumes the pseudo-queue
32
- * `amq.rabbitmq.reply-to` and stamps each request with `replyTo` +
33
- * `correlationId`. The subscriber publishes its response back to that
34
- * `replyTo` on the default exchange, and this call resolves when the
35
- * matching `correlationId` arrives. No reply queue is declared per
36
- * request, so there is no per-call broker setup overhead.
37
- *
38
- * ### Response contract
39
- *
40
- * The subscriber must respond with an
41
- * {@link ExternalCommunicatorResponse} envelope:
42
- *
43
- * ```ts
44
- * { uuid: string, response: T, error?: { http_code, message?, data? } }
45
- * ```
46
- *
47
- * On success this method returns **only the `response` field** typed as
48
- * `T` the wrapping `uuid` and the envelope itself are not exposed to
49
- * the caller. Therefore `T` should describe the shape of `response`, not
50
- * of the full envelope.
51
- *
52
- * ### Error contract
53
- *
54
- * Errors travel through the same envelope (`error` field on the
55
- * subscriber's response this is **not** a transport-level failure),
56
- * but on the caller side they are surfaced as a thrown
57
- * {@link ExternalCommunicatorError} instead of being returned. The
58
- * envelope's `error` payload is mapped onto the exception so no data is
59
- * lost:
60
- *
61
- * - `error.message` → `Error.message` (falls back to `'unknown error'`
62
- * when missing).
63
- * - `error.http_code` exception's status code (read via `getCode()`).
64
- * - `error.data` exception's data bag (read via `getData()`), spread
65
- * alongside `event` (the event name) and `httpCode` (a duplicate of
66
- * the status code, kept on `data` for downstream consumers).
67
- *
68
- * Callers that need to inspect the original status or payload should
69
- * `catch` the error and read those fields:
70
- *
71
- * ```ts
72
- * try {
73
- * await externalCommunicator.receiveDirect<T>(event, req, ops)
74
- * } catch (err) {
75
- * if (err instanceof ExternalCommunicatorError) {
76
- * err.getCode() // original error.http_code
77
- * err.getData() // { event, httpCode, ...error.data }
78
- * err.message // error.message || 'unknown error'
79
- * }
80
- * throw err
81
- * }
82
- * ```
83
- *
84
- * @typeParam T - shape of the successful `response` payload returned by the subscriber.
85
- * @param event - external event name. Must be declared in
86
- * `serviceRulesConfig.topicsConfig[QueueConfigType.External][topicName].events[]`
87
- * so the event resolves to an exchange (or pass `ops.exchangeName`
88
- * to override the lookup).
89
- * @param request - payload forwarded to the subscriber. Defaults to `{}`.
90
- * @param ops - direct-call options. See {@link ReceiveDirectOps}.
91
- * @returns the subscriber's `response` field, typed as `T`. The envelope's
92
- * `uuid` and `error` fields are not returned.
93
- *
94
- * @throws {ExternalCommunicatorError} when the subscriber responds with an
95
- * `error` envelope. The original `http_code`, `message`, and `data`
96
- * fields are preserved on the thrown error.
97
- * @throws {Error} `'Message in a wrong format was received from a direct channel'`
98
- * when `validationRules` are provided and the response fails validation.
99
- *
100
- * @example
101
- * ```ts
102
- * const result = await externalCommunicator.receiveDirect<{ data: string }>(
103
- * 'notary.lookup',
104
- * { notaryCertificateNumber: '1234', requestId: '-0' },
105
- * {
106
- * // Describes the inner `response` only; the envelope (uuid,
107
- * // error, meta, ...) is wrapped by the validator.
108
- * validationRules: { data: { type: 'string' } },
109
- * timeout: DurationMs.Second * 5,
110
- * },
111
- * )
112
- * ```
113
- */
114
- async receiveDirect(event, request = {}, ops) {
115
- const { exchangeName, validationRules, ignoreCache, timeout, registryApiVersion, requestUuid = (0, node_crypto_1.randomUUID)() } = ops;
116
- const payload = { uuid: requestUuid, request };
117
- const options = { ignoreCache, timeout, exchangeName, registryApiVersion };
118
- const externalResponse = await this.externalEventBus.publishDirect(event, payload, options);
119
- this.logger.debug('External direct response', externalResponse);
120
- if (validationRules) {
121
- try {
122
- this.eventMessageValidator.validateSyncedEventMessage(externalResponse, validationRules);
123
- }
124
- catch (err) {
125
- const errorMsg = 'Message in a wrong format was received from a direct channel';
126
- this.logger.error(errorMsg, { err, externalResponse });
127
- throw new Error(errorMsg);
128
- }
129
- }
130
- const { error, response } = externalResponse.payload;
131
- if (error) {
132
- this.logger.error(`Error received by an external event ${event}: ${error.http_code} ${error.message}`, { requestUuid });
133
- const errMsg = error.message || 'unknown error';
134
- throw new errors_1.ExternalCommunicatorError(errMsg, error.http_code, { event, httpCode: error.http_code, ...error.data });
135
- }
136
- return response;
137
- }
138
- }
139
- exports.ExternalCommunicator = ExternalCommunicator;
140
- //# sourceMappingURL=externalCommunicator.js.map
1
+ import { ExternalCommunicatorError } from "@diia-inhouse/errors";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/services/externalCommunicator.ts
4
+ var ExternalCommunicator = class {
5
+ externalEventBus;
6
+ eventMessageValidator;
7
+ logger;
8
+ constructor(externalEventBus, eventMessageValidator, logger) {
9
+ this.externalEventBus = externalEventBus;
10
+ this.eventMessageValidator = eventMessageValidator;
11
+ this.logger = logger;
12
+ }
13
+ /**
14
+ * Synchronous request/response over the external event bus.
15
+ *
16
+ * Publishes `event` to the configured external exchange wrapped as
17
+ * `{ uuid, request }` and awaits the subscriber's response on the same call.
18
+ * The response envelope is validated against `ops.validationRules`, and any embedded error is rethrown as
19
+ * {@link ExternalCommunicatorError}.
20
+ *
21
+ * Use this when the caller needs the response inline (e.g. a user-facing
22
+ * request that must block on `AGateway`). For fire-and-forget or fan-out
23
+ * flows, use the `default` publish + listener pattern instead.
24
+ *
25
+ * ### Transport
26
+ *
27
+ * Implemented on top of RabbitMQ's
28
+ * [direct reply-to](https://www.rabbitmq.com/docs/direct-reply-to)
29
+ * feature: the publisher consumes the pseudo-queue
30
+ * `amq.rabbitmq.reply-to` and stamps each request with `replyTo` +
31
+ * `correlationId`. The subscriber publishes its response back to that
32
+ * `replyTo` on the default exchange, and this call resolves when the
33
+ * matching `correlationId` arrives. No reply queue is declared per
34
+ * request, so there is no per-call broker setup overhead.
35
+ *
36
+ * ### Response contract
37
+ *
38
+ * The subscriber must respond with an
39
+ * {@link ExternalCommunicatorResponse} envelope:
40
+ *
41
+ * ```ts
42
+ * { uuid: string, response: T, error?: { http_code, message?, data? } }
43
+ * ```
44
+ *
45
+ * On success this method returns **only the `response` field** typed as
46
+ * `T` — the wrapping `uuid` and the envelope itself are not exposed to
47
+ * the caller. Therefore `T` should describe the shape of `response`, not
48
+ * of the full envelope.
49
+ *
50
+ * ### Error contract
51
+ *
52
+ * Errors travel through the same envelope (`error` field on the
53
+ * subscriber's response — this is **not** a transport-level failure),
54
+ * but on the caller side they are surfaced as a thrown
55
+ * {@link ExternalCommunicatorError} instead of being returned. The
56
+ * envelope's `error` payload is mapped onto the exception so no data is
57
+ * lost:
58
+ *
59
+ * - `error.message` → `Error.message` (falls back to `'unknown error'`
60
+ * when missing).
61
+ * - `error.http_code` → exception's status code (read via `getCode()`).
62
+ * - `error.data` → exception's data bag (read via `getData()`), spread
63
+ * alongside `event` (the event name) and `httpCode` (a duplicate of
64
+ * the status code, kept on `data` for downstream consumers).
65
+ *
66
+ * Callers that need to inspect the original status or payload should
67
+ * `catch` the error and read those fields:
68
+ *
69
+ * ```ts
70
+ * try {
71
+ * await externalCommunicator.receiveDirect<T>(event, req, ops)
72
+ * } catch (err) {
73
+ * if (err instanceof ExternalCommunicatorError) {
74
+ * err.getCode() // original error.http_code
75
+ * err.getData() // { event, httpCode, ...error.data }
76
+ * err.message // error.message || 'unknown error'
77
+ * }
78
+ * throw err
79
+ * }
80
+ * ```
81
+ *
82
+ * @typeParam T - shape of the successful `response` payload returned by the subscriber.
83
+ * @param event - external event name. Must be declared in
84
+ * `serviceRulesConfig.topicsConfig[QueueConfigType.External][topicName].events[]`
85
+ * so the event resolves to an exchange (or pass `ops.exchangeName`
86
+ * to override the lookup).
87
+ * @param request - payload forwarded to the subscriber. Defaults to `{}`.
88
+ * @param ops - direct-call options. See {@link ReceiveDirectOps}.
89
+ * @returns the subscriber's `response` field, typed as `T`. The envelope's
90
+ * `uuid` and `error` fields are not returned.
91
+ *
92
+ * @throws {ExternalCommunicatorError} when the subscriber responds with an
93
+ * `error` envelope. The original `http_code`, `message`, and `data`
94
+ * fields are preserved on the thrown error.
95
+ * @throws {Error} `'Message in a wrong format was received from a direct channel'`
96
+ * when `validationRules` are provided and the response fails validation.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const result = await externalCommunicator.receiveDirect<{ data: string }>(
101
+ * 'notary.lookup',
102
+ * { notaryCertificateNumber: '1234', requestId: '-0' },
103
+ * {
104
+ * // Describes the inner `response` only; the envelope (uuid,
105
+ * // error, meta, ...) is wrapped by the validator.
106
+ * validationRules: { data: { type: 'string' } },
107
+ * timeout: DurationMs.Second * 5,
108
+ * },
109
+ * )
110
+ * ```
111
+ */
112
+ async receiveDirect(event, request = {}, ops) {
113
+ const { exchangeName, validationRules, ignoreCache, timeout, registryApiVersion, requestUuid = randomUUID() } = ops;
114
+ const payload = {
115
+ uuid: requestUuid,
116
+ request
117
+ };
118
+ const options = {
119
+ ignoreCache,
120
+ timeout,
121
+ exchangeName,
122
+ registryApiVersion
123
+ };
124
+ const externalResponse = await this.externalEventBus.publishDirect(event, payload, options);
125
+ this.logger.debug("External direct response", externalResponse);
126
+ if (validationRules) try {
127
+ this.eventMessageValidator.validateSyncedEventMessage(externalResponse, validationRules);
128
+ } catch (err) {
129
+ const errorMsg = "Message in a wrong format was received from a direct channel";
130
+ this.logger.error(errorMsg, {
131
+ err,
132
+ externalResponse
133
+ });
134
+ throw new Error(errorMsg, { cause: err });
135
+ }
136
+ const { error, response } = externalResponse.payload;
137
+ if (error) {
138
+ this.logger.error(`Error received by an external event ${event}: ${error.http_code} ${error.message}`, { requestUuid });
139
+ throw new ExternalCommunicatorError(error.message || "unknown error", error.http_code, {
140
+ event,
141
+ httpCode: error.http_code,
142
+ ...error.data
143
+ });
144
+ }
145
+ return response;
146
+ }
147
+ };
148
+ //#endregion
149
+ export { ExternalCommunicator };
@@ -0,0 +1,39 @@
1
+ import { ExchangeName, ExchangeOptions } from "../interfaces/messageBrokerServiceConfig.js";
2
+ import { PublishDirectOptions, PublishOptions } from "../interfaces/options.js";
3
+ import { EventName } from "../interfaces/queueConfig/configs.js";
4
+ import { MessagePayload, PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
5
+ import { EventBusListener, ExternalEventBusQueue, MessageBrokerServiceEventsListener } from "../interfaces/index.js";
6
+ import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
7
+ import { Communicator } from "./communicator.js";
8
+ import { EventMessageHandler } from "./eventMessageHandler.js";
9
+ import { OnInit } from "@diia-inhouse/types";
10
+ import Logger$1 from "@diia-inhouse/diia-logger";
11
+ import { EnvService } from "@diia-inhouse/env";
12
+
13
+ //#region src/services/externalEventBus.d.ts
14
+ declare class ExternalEventBus extends Communicator implements ExternalEventBusQueue, OnInit {
15
+ private readonly envService;
16
+ private readonly eventCommunicator;
17
+ private readonly publishEventsSet;
18
+ private readonly subscribeEventsSet;
19
+ private readonly exchangePrefixName;
20
+ private readonly eventQueueMap;
21
+ constructor(logger: Logger$1, systemServiceName: string, envService: EnvService, queueProvider: RabbitMQProvider, externalEventListenerList: EventBusListener[], eventMessageHandler: EventMessageHandler, hostName: string);
22
+ static BuildRequestRoutingKey(eventName: string): string;
23
+ static BuildResponseRoutingKey(eventName: EventName, portalEvents?: string[]): string;
24
+ private static prepareQueuePrefix;
25
+ publish(eventName: EventName, payload: MessagePayload, options?: PublishOptions): Promise<PublishingResult>;
26
+ publishDirect<T>(eventName: EventName, payload: MessagePayload, options?: PublishDirectOptions): Promise<T>;
27
+ protected getUnicastListeners(): MessageBrokerServiceEventsListener[];
28
+ protected getExchangeNameWithSuffix(topic: ExchangeName): string;
29
+ protected getProducerExchangesOptions(): ExchangeOptions[];
30
+ protected override getMulticastListeners(): MessageBrokerServiceEventsListener[];
31
+ private getPublishMessage;
32
+ private getPublishRoutingKey;
33
+ private defineQueuesAndExchangesOptionsBasedOnGlobalConfig;
34
+ private buildEventQueueMap;
35
+ private buildResponseQueueName;
36
+ private buildRequestQueueName;
37
+ }
38
+ //#endregion
39
+ export { ExternalEventBus };
@@ -1,163 +1,145 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
1
+ import { Message } from "../interfaces/providers/rabbitmq/index.js";
2
+ import { QueueTypes } from "../interfaces/messageBrokerServiceConfig.js";
3
+ import "../interfaces/index.js";
4
+ import constants_default from "../constants.js";
5
+ import Communicator from "./communicator.js";
6
+ import { EventCommunicator } from "./eventCommunicator.js";
7
+ import { ErrorType, ExternalCommunicatorError } from "@diia-inhouse/errors";
8
+ import { HttpStatusCode } from "@diia-inhouse/types";
9
+ //#region src/services/externalEventBus.ts
10
+ var ExternalEventBus = class ExternalEventBus extends Communicator {
11
+ envService;
12
+ eventCommunicator;
13
+ publishEventsSet;
14
+ subscribeEventsSet;
15
+ exchangePrefixName = "TopicExternal";
16
+ eventQueueMap = /* @__PURE__ */ new Map();
17
+ constructor(logger, systemServiceName, envService, queueProvider, externalEventListenerList, eventMessageHandler, hostName) {
18
+ super(logger, queueProvider, hostName, systemServiceName);
19
+ this.envService = envService;
20
+ const { rabbit: { custom }, service: { publish = [], subscribe = [] } } = this.queueProvider.getConfig();
21
+ if (custom?.responseRoutingKeyPrefix && !this.envService.isLocal() && !this.envService.isTest()) throw new Error("Response routing key could be used only on local env");
22
+ this.publishEventsSet = new Set(publish);
23
+ this.subscribeEventsSet = new Set(subscribe);
24
+ this.eventQueueMap = this.buildEventQueueMap();
25
+ this.eventCommunicator = new EventCommunicator(logger, queueProvider, eventMessageHandler, externalEventListenerList);
26
+ }
27
+ static BuildRequestRoutingKey(eventName) {
28
+ return `queue.${constants_default.PROJECT_NAME}.${eventName}.req`;
29
+ }
30
+ static BuildResponseRoutingKey(eventName, portalEvents = []) {
31
+ return `${ExternalEventBus.prepareQueuePrefix(eventName, portalEvents)}.${eventName}.res`;
32
+ }
33
+ static prepareQueuePrefix(event, portalEvents = []) {
34
+ if (portalEvents.includes(event)) return `queue.${constants_default.PORTAL_NAME}`;
35
+ return `queue.${constants_default.PROJECT_NAME}`;
36
+ }
37
+ async publish(eventName, payload, options) {
38
+ const message = this.getPublishMessage(eventName, payload, options);
39
+ const routingKey = this.getPublishRoutingKey(eventName);
40
+ return await this.publishEventToExchange(eventName, message, {
41
+ ...options,
42
+ routingKey
43
+ });
44
+ }
45
+ async publishDirect(eventName, payload, options = {}) {
46
+ const { exchangeName: customExchangeName } = options;
47
+ const exchangeName = customExchangeName ?? this.eventNameToExchangeNameMap.get(eventName);
48
+ if (!exchangeName) throw new ExternalCommunicatorError(`Exchange name for event ${eventName} is not defined`, HttpStatusCode.INTERNAL_SERVER_ERROR, {
49
+ event: eventName,
50
+ customExchangeName
51
+ }, ErrorType.Unoperated);
52
+ const routingKey = ExternalEventBus.BuildRequestRoutingKey(eventName);
53
+ const { data } = this.getPublishMessage(eventName, payload, options);
54
+ return await this.queueProvider.publishExternalDirect(data, exchangeName, routingKey, options);
55
+ }
56
+ getUnicastListeners() {
57
+ return this.eventCommunicator.getUnicastListeners();
58
+ }
59
+ getExchangeNameWithSuffix(topic) {
60
+ return `${this.exchangePrefixName}${topic}`;
61
+ }
62
+ getProducerExchangesOptions() {
63
+ const [exchangesOptions] = this.defineQueuesAndExchangesOptionsBasedOnGlobalConfig();
64
+ return exchangesOptions;
65
+ }
66
+ getMulticastListeners() {
67
+ const [exchangesOptions, queuesOptions] = this.defineQueuesAndExchangesOptionsBasedOnGlobalConfig();
68
+ return this.eventCommunicator.getMulticastListeners(queuesOptions, exchangesOptions, this.eventQueueMap);
69
+ }
70
+ getPublishMessage(eventName, message, options) {
71
+ const { rabbit: { custom: { responseRoutingKeyPrefix } = {} } } = this.queueProvider.getConfig();
72
+ const responseRoutingKey = this.buildResponseQueueName(eventName, responseRoutingKeyPrefix);
73
+ const partialMeta = {
74
+ ignoreCache: options?.ignoreCache,
75
+ registryApiVersion: options?.registryApiVersion,
76
+ ...this.publishEventsSet.has(eventName) ? { responseRoutingKey } : {}
77
+ };
78
+ return new Message(this.getPublishQueueMessageData(eventName, message, partialMeta));
79
+ }
80
+ getPublishRoutingKey(eventName) {
81
+ if (this.publishEventsSet.has(eventName)) return ExternalEventBus.BuildRequestRoutingKey(eventName);
82
+ else if (this.subscribeEventsSet.has(eventName)) {
83
+ const { portalEvents } = this.queueProvider.getConfig();
84
+ return ExternalEventBus.BuildResponseRoutingKey(eventName, portalEvents);
85
+ }
86
+ return "";
87
+ }
88
+ defineQueuesAndExchangesOptionsBasedOnGlobalConfig() {
89
+ const { rabbit: { listenerOptions, declareOptions: { assertQueues, assertExchanges, queuesOptions: overriddenQueuesOptions = {} } = {} } } = this.queueProvider.getConfig();
90
+ const queuesOptions = [];
91
+ const exchangesMap = /* @__PURE__ */ new Map();
92
+ for (const [eventName, queueName] of this.eventQueueMap.entries()) {
93
+ const exchangeName = this.eventNameToExchangeNameMap.get(eventName);
94
+ if (!exchangeName) {
95
+ this.logger.error(`Can't find external topic name for event [${eventName}]`);
96
+ return [[], []];
97
+ }
98
+ const queueOptions = {
99
+ name: queueName,
100
+ declare: assertQueues,
101
+ type: QueueTypes.Quorum,
102
+ options: listenerOptions?.queueOptions,
103
+ bindTo: [{
104
+ bind: assertQueues,
105
+ routingKey: queueName,
106
+ exchangeName
107
+ }],
108
+ consumerOptions: this.optionsBuilder.defineConsumerOptionsBasedOnGlobalConfig(),
109
+ ...overriddenQueuesOptions
110
+ };
111
+ queuesOptions.push(queueOptions);
112
+ const exchangeOptions = {
113
+ name: exchangeName,
114
+ type: "topic",
115
+ declare: assertExchanges
116
+ };
117
+ exchangesMap.set(exchangeName, exchangeOptions);
118
+ }
119
+ return [[...exchangesMap.values()], queuesOptions];
120
+ }
121
+ buildEventQueueMap() {
122
+ const eventQueueMap = /* @__PURE__ */ new Map();
123
+ const { service: { publish = [], subscribe = [] }, rabbit: { custom: { responseRoutingKeyPrefix } = {} } } = this.queueProvider.getConfig();
124
+ if (publish.length === 0 && subscribe.length === 0) {
125
+ this.logger.info("No one external events to listen");
126
+ return eventQueueMap;
127
+ }
128
+ for (const responseEvent of publish) eventQueueMap.set(responseEvent, this.buildResponseQueueName(responseEvent, responseRoutingKeyPrefix));
129
+ for (const requestEvent of subscribe) eventQueueMap.set(requestEvent, this.buildRequestQueueName(requestEvent, responseRoutingKeyPrefix));
130
+ return eventQueueMap;
131
+ }
132
+ buildResponseQueueName(eventName, prefix) {
133
+ const result = `queue.${constants_default.PROJECT_NAME}.${eventName}.res`;
134
+ if (prefix) return `${prefix}.${result}`;
135
+ return result;
136
+ }
137
+ buildRequestQueueName(eventName, prefix) {
138
+ const { portalEvents } = this.queueProvider.getConfig();
139
+ const result = `${ExternalEventBus.prepareQueuePrefix(eventName, portalEvents)}.${eventName}.req`;
140
+ if (prefix) return `${prefix}.${result}`;
141
+ return result;
142
+ }
4
143
  };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ExternalEventBus = void 0;
7
- const errors_1 = require("@diia-inhouse/errors");
8
- const types_1 = require("@diia-inhouse/types");
9
- const constants_1 = __importDefault(require("../constants"));
10
- const interfaces_1 = require("../interfaces");
11
- const communicator_1 = __importDefault(require("./communicator"));
12
- const eventCommunicator_1 = require("./eventCommunicator");
13
- class ExternalEventBus extends communicator_1.default {
14
- envService;
15
- eventCommunicator;
16
- publishEventsSet;
17
- subscribeEventsSet;
18
- exchangePrefixName = 'TopicExternal';
19
- eventQueueMap = new Map();
20
- constructor(logger, systemServiceName, envService, queueProvider, externalEventListenerList, eventMessageHandler, hostName) {
21
- super(logger, queueProvider, hostName, systemServiceName);
22
- this.envService = envService;
23
- const { rabbit: { custom }, service: { publish = [], subscribe = [] }, } = this.queueProvider.getConfig();
24
- if (custom?.responseRoutingKeyPrefix && !this.envService.isLocal() && !this.envService.isTest()) {
25
- throw new Error('Response routing key could be used only on local env');
26
- }
27
- this.publishEventsSet = new Set(publish);
28
- this.subscribeEventsSet = new Set(subscribe);
29
- this.eventQueueMap = this.buildEventQueueMap();
30
- this.eventCommunicator = new eventCommunicator_1.EventCommunicator(logger, queueProvider, eventMessageHandler, externalEventListenerList);
31
- }
32
- static BuildRequestRoutingKey(eventName) {
33
- return `queue.${constants_1.default.PROJECT_NAME}.${eventName}.req`;
34
- }
35
- static BuildResponseRoutingKey(eventName, portalEvents = []) {
36
- const queuePrefix = ExternalEventBus.prepareQueuePrefix(eventName, portalEvents);
37
- return `${queuePrefix}.${eventName}.res`;
38
- }
39
- static prepareQueuePrefix(event, portalEvents = []) {
40
- if (portalEvents.includes(event)) {
41
- return `queue.${constants_1.default.PORTAL_NAME}`;
42
- }
43
- return `queue.${constants_1.default.PROJECT_NAME}`;
44
- }
45
- async publish(eventName, payload, options) {
46
- const message = this.getPublishMessage(eventName, payload, options);
47
- const routingKey = this.getPublishRoutingKey(eventName);
48
- return await this.publishEventToExchange(eventName, message, { ...options, routingKey });
49
- }
50
- async publishDirect(eventName, payload, options = {}) {
51
- const { exchangeName: customExchangeName } = options;
52
- const exchangeName = customExchangeName ?? this.eventNameToExchangeNameMap.get(eventName);
53
- if (!exchangeName) {
54
- throw new errors_1.ExternalCommunicatorError(`Exchange name for event ${eventName} is not defined`, types_1.HttpStatusCode.INTERNAL_SERVER_ERROR, { event: eventName, customExchangeName }, errors_1.ErrorType.Unoperated);
55
- }
56
- const routingKey = ExternalEventBus.BuildRequestRoutingKey(eventName);
57
- const { data } = this.getPublishMessage(eventName, payload, options);
58
- return await this.queueProvider.publishExternalDirect(data, exchangeName, routingKey, options);
59
- }
60
- getUnicastListeners() {
61
- return this.eventCommunicator.getUnicastListeners();
62
- }
63
- getExchangeNameWithSuffix(topic) {
64
- return `${this.exchangePrefixName}${topic}`;
65
- }
66
- getProducerExchangesOptions() {
67
- const [exchangesOptions] = this.defineQueuesAndExchangesOptionsBasedOnGlobalConfig();
68
- return exchangesOptions;
69
- }
70
- getMulticastListeners() {
71
- const [exchangesOptions, queuesOptions] = this.defineQueuesAndExchangesOptionsBasedOnGlobalConfig();
72
- return this.eventCommunicator.getMulticastListeners(queuesOptions, exchangesOptions, this.eventQueueMap);
73
- }
74
- getPublishMessage(eventName, message, options) {
75
- const { rabbit: { custom: { responseRoutingKeyPrefix } = {} }, } = this.queueProvider.getConfig();
76
- const responseRoutingKey = this.buildResponseQueueName(eventName, responseRoutingKeyPrefix);
77
- const partialMeta = {
78
- ignoreCache: options?.ignoreCache,
79
- registryApiVersion: options?.registryApiVersion,
80
- ...(this.publishEventsSet.has(eventName) ? { responseRoutingKey } : {}),
81
- };
82
- const data = this.getPublishQueueMessageData(eventName, message, partialMeta);
83
- return new interfaces_1.Message(data);
84
- }
85
- getPublishRoutingKey(eventName) {
86
- if (this.publishEventsSet.has(eventName)) {
87
- return ExternalEventBus.BuildRequestRoutingKey(eventName);
88
- }
89
- else if (this.subscribeEventsSet.has(eventName)) {
90
- const { portalEvents } = this.queueProvider.getConfig();
91
- return ExternalEventBus.BuildResponseRoutingKey(eventName, portalEvents);
92
- }
93
- return '';
94
- }
95
- defineQueuesAndExchangesOptionsBasedOnGlobalConfig() {
96
- const { rabbit: { listenerOptions, declareOptions: { assertQueues, assertExchanges, queuesOptions: overriddenQueuesOptions = {} } = {}, }, } = this.queueProvider.getConfig();
97
- const queuesOptions = [];
98
- const exchangesMap = new Map();
99
- for (const [eventName, queueName] of this.eventQueueMap.entries()) {
100
- const exchangeName = this.eventNameToExchangeNameMap.get(eventName);
101
- if (!exchangeName) {
102
- this.logger.error(`Can't find external topic name for event [${eventName}]`);
103
- return [[], []];
104
- }
105
- const queueOptions = {
106
- name: queueName,
107
- declare: assertQueues,
108
- type: interfaces_1.QueueTypes.Quorum,
109
- options: listenerOptions?.queueOptions,
110
- bindTo: [
111
- {
112
- bind: assertQueues,
113
- routingKey: queueName,
114
- exchangeName: exchangeName,
115
- },
116
- ],
117
- consumerOptions: this.optionsBuilder.defineConsumerOptionsBasedOnGlobalConfig(),
118
- ...overriddenQueuesOptions,
119
- };
120
- queuesOptions.push(queueOptions);
121
- const exchangeOptions = {
122
- name: exchangeName,
123
- type: interfaces_1.ExchangeType.Topic,
124
- declare: assertExchanges,
125
- };
126
- exchangesMap.set(exchangeName, exchangeOptions);
127
- }
128
- const exchangesOptions = [...exchangesMap.values()];
129
- return [exchangesOptions, queuesOptions];
130
- }
131
- buildEventQueueMap() {
132
- const eventQueueMap = new Map();
133
- const { service: { publish = [], subscribe = [] }, rabbit: { custom: { responseRoutingKeyPrefix } = {} }, } = this.queueProvider.getConfig();
134
- if (publish.length === 0 && subscribe.length === 0) {
135
- this.logger.info('No one external events to listen');
136
- return eventQueueMap;
137
- }
138
- for (const responseEvent of publish) {
139
- eventQueueMap.set(responseEvent, this.buildResponseQueueName(responseEvent, responseRoutingKeyPrefix));
140
- }
141
- for (const requestEvent of subscribe) {
142
- eventQueueMap.set(requestEvent, this.buildRequestQueueName(requestEvent, responseRoutingKeyPrefix));
143
- }
144
- return eventQueueMap;
145
- }
146
- buildResponseQueueName(eventName, prefix) {
147
- const result = `queue.${constants_1.default.PROJECT_NAME}.${eventName}.res`;
148
- if (prefix) {
149
- return `${prefix}.${result}`;
150
- }
151
- return result;
152
- }
153
- buildRequestQueueName(eventName, prefix) {
154
- const { portalEvents } = this.queueProvider.getConfig();
155
- const result = `${ExternalEventBus.prepareQueuePrefix(eventName, portalEvents)}.${eventName}.req`;
156
- if (prefix) {
157
- return `${prefix}.${result}`;
158
- }
159
- return result;
160
- }
161
- }
162
- exports.ExternalEventBus = ExternalEventBus;
163
- //# sourceMappingURL=externalEventBus.js.map
144
+ //#endregion
145
+ export { ExternalEventBus };