@onlineapps/mq-client-core 1.0.14 → 1.0.15

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/mq-client-core",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "Core MQ client library for RabbitMQ - shared by infrastructure services and connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,272 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * queueConfig.js
5
+ *
6
+ * Central configuration for INFRASTRUCTURE queues only.
7
+ * Business queues ({service}.workflow, {service}.queue, {service}.dlq) are created
8
+ * by individual services via QueueManager.setupServiceQueues().
9
+ *
10
+ * This ensures consistent configuration for infrastructure queues across all services.
11
+ *
12
+ * NOTE: This is part of mq-client-core (spodní vrstva) because it's used by both:
13
+ * - Infrastructure services (via mq-client-core)
14
+ * - Business services (via conn-infra-mq connector)
15
+ */
16
+
17
+ module.exports = {
18
+ /**
19
+ * Workflow infrastructure queue configurations
20
+ * These are shared infrastructure queues used by all services
21
+ */
22
+ workflow: {
23
+ /**
24
+ * workflow.init - Entry point for all workflows
25
+ * All services listen as competing consumers
26
+ */
27
+ init: {
28
+ durable: true,
29
+ arguments: {
30
+ 'x-message-ttl': 300000, // 5 minutes TTL
31
+ 'x-max-length': 10000 // Max 10k messages
32
+ }
33
+ },
34
+
35
+ /**
36
+ * workflow.completed - Completed workflows
37
+ */
38
+ completed: {
39
+ durable: true,
40
+ arguments: {
41
+ 'x-message-ttl': 300000, // 5 minutes TTL
42
+ 'x-max-length': 10000
43
+ }
44
+ },
45
+
46
+ /**
47
+ * workflow.failed - Failed workflows
48
+ */
49
+ failed: {
50
+ durable: true,
51
+ arguments: {
52
+ 'x-message-ttl': 300000, // 5 minutes TTL
53
+ 'x-max-length': 10000
54
+ }
55
+ },
56
+
57
+ /**
58
+ * workflow.dlq - Dead letter queue for workflows
59
+ */
60
+ dlq: {
61
+ durable: true,
62
+ arguments: {
63
+ // No TTL for DLQ - messages should persist
64
+ 'x-max-length': 50000 // Higher limit for DLQ
65
+ }
66
+ }
67
+ },
68
+
69
+ /**
70
+ * Business queue templates
71
+ * These are templates for service-specific queues ({service}.workflow, {service}.queue, {service}.dlq)
72
+ * Used by QueueManager.setupServiceQueues() to ensure consistent configuration
73
+ */
74
+ business: {
75
+ /**
76
+ * {service}.workflow - Service-specific workflow queue
77
+ * Used for routing workflow steps to specific services
78
+ */
79
+ workflow: {
80
+ durable: true,
81
+ arguments: {
82
+ 'x-message-ttl': 300000, // 5 minutes TTL
83
+ 'x-max-length': 10000, // Max 10k messages
84
+ 'x-dead-letter-exchange': 'dlx',
85
+ 'x-dead-letter-routing-key': '{service}.dlq' // Placeholder, replaced with actual service name
86
+ }
87
+ },
88
+
89
+ /**
90
+ * {service}.queue - Service main processing queue
91
+ * Used for direct service-to-service communication
92
+ */
93
+ queue: {
94
+ durable: true,
95
+ arguments: {
96
+ 'x-message-ttl': 30000, // 30 seconds TTL
97
+ 'x-max-length': 10000, // Max 10k messages
98
+ 'x-dead-letter-exchange': 'dlx',
99
+ 'x-dead-letter-routing-key': '{service}.dlq' // Placeholder, replaced with actual service name
100
+ }
101
+ },
102
+
103
+ /**
104
+ * {service}.dlq - Service dead letter queue
105
+ * Receives failed messages from service.queue and service.workflow
106
+ */
107
+ dlq: {
108
+ durable: true,
109
+ arguments: {
110
+ // No TTL for DLQ - messages should persist
111
+ 'x-max-length': 50000 // Higher limit for DLQ
112
+ }
113
+ }
114
+ },
115
+
116
+ /**
117
+ * Registry infrastructure queue configurations
118
+ */
119
+ registry: {
120
+ /**
121
+ * registry.register - Registration requests
122
+ */
123
+ register: {
124
+ durable: true,
125
+ arguments: {
126
+ 'x-message-ttl': 60000, // 1 minute TTL
127
+ 'x-max-length': 1000
128
+ }
129
+ },
130
+
131
+ /**
132
+ * registry.heartbeats - Service heartbeats
133
+ */
134
+ heartbeats: {
135
+ durable: true,
136
+ arguments: {
137
+ 'x-message-ttl': 120000, // 2 minutes TTL
138
+ 'x-max-length': 5000
139
+ }
140
+ },
141
+
142
+ /**
143
+ * registry.changes - Registry event fanout exchange
144
+ * (This is an exchange, not a queue, but included for reference)
145
+ */
146
+ changes: {
147
+ type: 'exchange',
148
+ durable: true
149
+ }
150
+ },
151
+
152
+ /**
153
+ * Get infrastructure queue configuration by type and name
154
+ * @param {string} type - Queue type: 'workflow', 'registry'
155
+ * @param {string} name - Queue name: 'init', 'completed', 'register', etc.
156
+ * @returns {Object} Queue configuration
157
+ */
158
+ getQueueConfig(type, name) {
159
+ const config = this[type]?.[name];
160
+ if (!config) {
161
+ throw new Error(`Infrastructure queue config not found: ${type}.${name}`);
162
+ }
163
+
164
+ // Deep clone to avoid modifying original
165
+ return JSON.parse(JSON.stringify(config));
166
+ },
167
+
168
+ /**
169
+ * Get workflow infrastructure queue configuration
170
+ * @param {string} queueName - Queue name (e.g., 'workflow.init', 'workflow.completed')
171
+ * @returns {Object} Queue configuration
172
+ */
173
+ getWorkflowQueueConfig(queueName) {
174
+ const parts = queueName.split('.');
175
+ if (parts.length !== 2 || parts[0] !== 'workflow') {
176
+ throw new Error(`Invalid workflow queue name: ${queueName}. Expected format: workflow.{name}`);
177
+ }
178
+ return this.getQueueConfig('workflow', parts[1]);
179
+ },
180
+
181
+ /**
182
+ * Get registry infrastructure queue configuration
183
+ * @param {string} queueName - Queue name (e.g., 'registry.register', 'registry.heartbeats')
184
+ * @returns {Object} Queue configuration
185
+ */
186
+ getRegistryQueueConfig(queueName) {
187
+ const parts = queueName.split('.');
188
+ if (parts.length !== 2 || parts[0] !== 'registry') {
189
+ throw new Error(`Invalid registry queue name: ${queueName}. Expected format: registry.{name}`);
190
+ }
191
+ return this.getQueueConfig('registry', parts[1]);
192
+ },
193
+
194
+ /**
195
+ * Check if queue name is an infrastructure queue
196
+ * @param {string} queueName - Queue name to check
197
+ * @returns {boolean} True if infrastructure queue
198
+ */
199
+ isInfrastructureQueue(queueName) {
200
+ return queueName.startsWith('workflow.') || queueName.startsWith('registry.');
201
+ },
202
+
203
+ /**
204
+ * Check if queue name is a business queue
205
+ * @param {string} queueName - Queue name to check
206
+ * @returns {boolean} True if business queue
207
+ */
208
+ isBusinessQueue(queueName) {
209
+ // Business queues follow pattern: {service}.{type}
210
+ // where type is: workflow, queue, dlq
211
+ const parts = queueName.split('.');
212
+ if (parts.length !== 2) return false;
213
+ return ['workflow', 'queue', 'dlq'].includes(parts[1]);
214
+ },
215
+
216
+ /**
217
+ * Parse business queue name to extract service name and queue type
218
+ * @param {string} queueName - Business queue name (e.g., 'hello-service.workflow')
219
+ * @returns {Object} { serviceName, queueType } or null if not a business queue
220
+ */
221
+ parseBusinessQueue(queueName) {
222
+ if (!this.isBusinessQueue(queueName)) {
223
+ return null;
224
+ }
225
+ const parts = queueName.split('.');
226
+ return {
227
+ serviceName: parts[0],
228
+ queueType: parts[1]
229
+ };
230
+ },
231
+
232
+ /**
233
+ * Get business queue configuration template
234
+ * @param {string} queueType - Queue type: 'workflow', 'queue', 'dlq'
235
+ * @param {string} serviceName - Service name (replaces {service} placeholder)
236
+ * @returns {Object} Queue configuration
237
+ */
238
+ getBusinessQueueConfig(queueType, serviceName) {
239
+ const template = this.business?.[queueType];
240
+ if (!template) {
241
+ throw new Error(`Business queue template not found: ${queueType}`);
242
+ }
243
+
244
+ // Deep clone to avoid modifying original
245
+ const config = JSON.parse(JSON.stringify(template));
246
+
247
+ // Replace {service} placeholder in routing keys
248
+ if (config.arguments && serviceName) {
249
+ const routingKey = config.arguments['x-dead-letter-routing-key'];
250
+ if (routingKey && typeof routingKey === 'string') {
251
+ config.arguments['x-dead-letter-routing-key'] = routingKey.replace('{service}', serviceName);
252
+ }
253
+ }
254
+
255
+ return config;
256
+ },
257
+
258
+ /**
259
+ * Get infrastructure queue configuration by queue name (auto-detect type)
260
+ * @param {string} queueName - Full queue name (e.g., 'workflow.init', 'registry.register')
261
+ * @returns {Object} Queue configuration
262
+ */
263
+ getInfrastructureQueueConfig(queueName) {
264
+ if (queueName.startsWith('workflow.')) {
265
+ return this.getWorkflowQueueConfig(queueName);
266
+ } else if (queueName.startsWith('registry.')) {
267
+ return this.getRegistryQueueConfig(queueName);
268
+ } else {
269
+ throw new Error(`Queue ${queueName} is not an infrastructure queue. Infrastructure queues must start with 'workflow.' or 'registry.'`);
270
+ }
271
+ }
272
+ };
@@ -21,12 +21,14 @@
21
21
  async function initInfrastructureQueues(channel, options = {}) {
22
22
  const logger = options.logger || console;
23
23
 
24
- // Load queueConfig from @onlineapps/conn-infra-mq
25
- let queueConfig;
26
- try {
27
- queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
28
- } catch (requireError) {
29
- throw new Error(`Cannot load queueConfig from @onlineapps/conn-infra-mq: ${requireError.message}. Make sure @onlineapps/conn-infra-mq is installed.`);
24
+ // Load queueConfig - either from options or try to load from @onlineapps/conn-infra-mq
25
+ let queueConfig = options.queueConfig;
26
+ if (!queueConfig) {
27
+ try {
28
+ queueConfig = require('@onlineapps/conn-infra-mq/src/config/queueConfig');
29
+ } catch (requireError) {
30
+ throw new Error(`Cannot load queueConfig. Either provide queueConfig in options, or ensure @onlineapps/conn-infra-mq is installed: ${requireError.message}`);
31
+ }
30
32
  }
31
33
 
32
34
  const queuesToCreate = options.queues || [