@gugananuvem/aws-local-simulator 1.0.11 → 1.0.12
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 +122 -69
- package/package.json +2 -2
- package/src/config/config-loader.js +2 -0
- package/src/config/default-config.js +2 -0
- package/src/server.js +3 -1
- package/src/services/apigateway/index.js +5 -3
- package/src/services/apigateway/server.js +53 -0
- package/src/services/cognito/server.js +54 -3
- package/src/services/cognito/simulator.js +269 -2
- package/src/services/lambda/handler-loader.js +13 -2
- package/src/services/lambda/index.js +2 -1
- package/src/services/lambda/server.js +32 -39
- package/src/services/lambda/simulator.js +44 -157
- package/src/services/sqs/server.js +88 -16
- package/src/services/sqs/simulator.js +79 -298
- package/src/services/sts/index.js +37 -0
- package/src/services/sts/server.js +142 -0
- package/src/services/sts/simulator.js +69 -0
|
@@ -26,16 +26,24 @@ class SQSSimulator {
|
|
|
26
26
|
// Carrega filas da configuração
|
|
27
27
|
if (this.config.sqs?.queues) {
|
|
28
28
|
for (const queueConfig of this.config.sqs.queues) {
|
|
29
|
-
|
|
29
|
+
const name = typeof queueConfig === 'string' ? queueConfig : queueConfig.name;
|
|
30
|
+
this.createQueue(name);
|
|
31
|
+
// Restore persisted messages for this queue
|
|
32
|
+
const queue = this.queues.get(name);
|
|
33
|
+
if (queue) {
|
|
34
|
+
queue.messages = this.store.read(name) || [];
|
|
35
|
+
queue.messageCount = queue.messages.length;
|
|
36
|
+
}
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
|
-
|
|
39
|
+
|
|
33
40
|
// Carrega filas existentes do disco
|
|
34
41
|
const savedQueues = this.store.read('__queues__');
|
|
35
42
|
if (savedQueues) {
|
|
36
43
|
for (const [name, data] of Object.entries(savedQueues)) {
|
|
37
44
|
if (!this.queues.has(name)) {
|
|
38
|
-
this.
|
|
45
|
+
const messages = this.store.read(name) || [];
|
|
46
|
+
this.queues.set(name, { ...data, messages });
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
}
|
|
@@ -45,7 +53,7 @@ class SQSSimulator {
|
|
|
45
53
|
if (this.queues.has(queueName)) {
|
|
46
54
|
return { error: { code: 'QueueAlreadyExists', message: 'Queue already exists' }, status: 409 };
|
|
47
55
|
}
|
|
48
|
-
|
|
56
|
+
|
|
49
57
|
const queue = {
|
|
50
58
|
name: queueName,
|
|
51
59
|
url: `http://localhost:${this.config.ports.sqs}/queue/${queueName}`,
|
|
@@ -57,13 +65,16 @@ class SQSSimulator {
|
|
|
57
65
|
createdAt: new Date().toISOString(),
|
|
58
66
|
messageCount: 0
|
|
59
67
|
};
|
|
60
|
-
|
|
68
|
+
|
|
61
69
|
this.queues.set(queueName, queue);
|
|
62
70
|
this.persistQueues();
|
|
63
|
-
|
|
64
|
-
|
|
71
|
+
// Only initialize message store if it doesn't already exist
|
|
72
|
+
if (!this.store.read(queueName)) {
|
|
73
|
+
this.store.write(queueName, []);
|
|
74
|
+
}
|
|
75
|
+
|
|
65
76
|
logger.debug(`✅ Fila SQS criada: ${queueName}`);
|
|
66
|
-
|
|
77
|
+
|
|
67
78
|
return { queue };
|
|
68
79
|
}
|
|
69
80
|
|
|
@@ -88,30 +99,39 @@ class SQSSimulator {
|
|
|
88
99
|
}
|
|
89
100
|
}
|
|
90
101
|
|
|
102
|
+
// Extracts queue name from QueueName param or QueueUrl (AWS CLI v2 JSON protocol sends QueueUrl)
|
|
103
|
+
resolveQueueName(req) {
|
|
104
|
+
const name = req.query.QueueName || req.body.QueueName;
|
|
105
|
+
if (name) return name;
|
|
106
|
+
const url = req.query.QueueUrl || req.body.QueueUrl;
|
|
107
|
+
if (url) return url.split('/').pop();
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
91
111
|
createQueueAction(req) {
|
|
92
112
|
const queueName = req.query.QueueName || req.body.QueueName;
|
|
93
113
|
const result = this.createQueue(queueName);
|
|
94
|
-
|
|
114
|
+
|
|
95
115
|
if (result.error) {
|
|
96
116
|
return result;
|
|
97
117
|
}
|
|
98
|
-
|
|
118
|
+
|
|
99
119
|
return { queueUrl: result.queue.url };
|
|
100
120
|
}
|
|
101
121
|
|
|
102
122
|
sendMessageAction(req) {
|
|
103
|
-
const queueName =
|
|
123
|
+
const queueName = this.resolveQueueName(req);
|
|
104
124
|
const queue = this.queues.get(queueName);
|
|
105
|
-
|
|
125
|
+
|
|
106
126
|
if (!queue) {
|
|
107
127
|
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
108
128
|
}
|
|
109
|
-
|
|
129
|
+
|
|
110
130
|
const messageBody = req.query.MessageBody || req.body.MessageBody;
|
|
111
131
|
const messageId = crypto.randomUUID();
|
|
112
132
|
const receiptHandle = crypto.randomUUID();
|
|
113
133
|
const md5 = crypto.createHash('md5').update(messageBody).digest('hex');
|
|
114
|
-
|
|
134
|
+
|
|
115
135
|
const message = {
|
|
116
136
|
MessageId: messageId,
|
|
117
137
|
ReceiptHandle: receiptHandle,
|
|
@@ -120,44 +140,40 @@ class SQSSimulator {
|
|
|
120
140
|
Attributes: {},
|
|
121
141
|
timestamp: Date.now()
|
|
122
142
|
};
|
|
123
|
-
|
|
143
|
+
|
|
124
144
|
queue.messages.push(message);
|
|
125
145
|
queue.messageCount++;
|
|
126
146
|
this.persistQueue(queueName);
|
|
127
|
-
|
|
147
|
+
|
|
128
148
|
logger.verboso(`📨 Mensagem enviada para ${queueName}: ${messageId}`);
|
|
129
|
-
|
|
130
|
-
// Processa imediatamente se houver handler
|
|
149
|
+
|
|
131
150
|
if (queue.handler) {
|
|
132
151
|
this.processQueueMessages(queue);
|
|
133
152
|
}
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
messageId,
|
|
137
|
-
md5
|
|
138
|
-
};
|
|
153
|
+
|
|
154
|
+
return { messageId, md5 };
|
|
139
155
|
}
|
|
140
156
|
|
|
141
157
|
sendMessageBatchAction(req) {
|
|
142
|
-
const queueName =
|
|
158
|
+
const queueName = this.resolveQueueName(req);
|
|
143
159
|
const queue = this.queues.get(queueName);
|
|
144
|
-
|
|
160
|
+
|
|
145
161
|
if (!queue) {
|
|
146
162
|
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
147
163
|
}
|
|
148
|
-
|
|
164
|
+
|
|
149
165
|
const entries = req.query.SendMessageBatchRequestEntry || req.body.SendMessageBatchRequestEntry;
|
|
150
166
|
const batchEntries = Array.isArray(entries) ? entries : [entries];
|
|
151
|
-
|
|
167
|
+
|
|
152
168
|
const successful = [];
|
|
153
169
|
const failed = [];
|
|
154
|
-
|
|
170
|
+
|
|
155
171
|
for (const entry of batchEntries) {
|
|
156
172
|
try {
|
|
157
173
|
const messageId = crypto.randomUUID();
|
|
158
174
|
const receiptHandle = crypto.randomUUID();
|
|
159
175
|
const md5 = crypto.createHash('md5').update(entry.MessageBody).digest('hex');
|
|
160
|
-
|
|
176
|
+
|
|
161
177
|
const message = {
|
|
162
178
|
MessageId: messageId,
|
|
163
179
|
ReceiptHandle: receiptHandle,
|
|
@@ -166,10 +182,10 @@ class SQSSimulator {
|
|
|
166
182
|
Attributes: {},
|
|
167
183
|
timestamp: Date.now()
|
|
168
184
|
};
|
|
169
|
-
|
|
185
|
+
|
|
170
186
|
queue.messages.push(message);
|
|
171
187
|
queue.messageCount++;
|
|
172
|
-
|
|
188
|
+
|
|
173
189
|
successful.push({
|
|
174
190
|
Id: entry.Id,
|
|
175
191
|
MessageId: messageId,
|
|
@@ -183,61 +199,62 @@ class SQSSimulator {
|
|
|
183
199
|
});
|
|
184
200
|
}
|
|
185
201
|
}
|
|
186
|
-
|
|
202
|
+
|
|
187
203
|
this.persistQueue(queueName);
|
|
188
|
-
|
|
204
|
+
|
|
189
205
|
if (queue.handler && successful.length > 0) {
|
|
190
206
|
this.processQueueMessages(queue);
|
|
191
207
|
}
|
|
192
|
-
|
|
208
|
+
|
|
193
209
|
return { successful, failed };
|
|
194
210
|
}
|
|
195
211
|
|
|
196
212
|
receiveMessageAction(req) {
|
|
197
|
-
const queueName =
|
|
213
|
+
const queueName = this.resolveQueueName(req);
|
|
198
214
|
const queue = this.queues.get(queueName);
|
|
199
|
-
|
|
215
|
+
|
|
200
216
|
if (!queue) {
|
|
201
217
|
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
202
218
|
}
|
|
203
|
-
|
|
219
|
+
|
|
204
220
|
const maxNumberOfMessages = parseInt(req.query.MaxNumberOfMessages || req.body.MaxNumberOfMessages || 1);
|
|
205
221
|
const messages = queue.messages.splice(0, maxNumberOfMessages);
|
|
206
|
-
|
|
222
|
+
|
|
207
223
|
if (messages.length > 0) {
|
|
224
|
+
queue.messageCount -= messages.length;
|
|
208
225
|
this.persistQueue(queueName);
|
|
209
226
|
}
|
|
210
|
-
|
|
227
|
+
|
|
211
228
|
return { messages };
|
|
212
229
|
}
|
|
213
230
|
|
|
214
231
|
deleteMessageAction(req) {
|
|
215
|
-
const queueName =
|
|
232
|
+
const queueName = this.resolveQueueName(req);
|
|
216
233
|
const receiptHandle = req.query.ReceiptHandle || req.body.ReceiptHandle;
|
|
217
234
|
const queue = this.queues.get(queueName);
|
|
218
|
-
|
|
235
|
+
|
|
219
236
|
if (!queue) {
|
|
220
237
|
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
221
238
|
}
|
|
222
|
-
|
|
239
|
+
|
|
223
240
|
const index = queue.messages.findIndex(m => m.ReceiptHandle === receiptHandle);
|
|
224
241
|
if (index !== -1) {
|
|
225
242
|
queue.messages.splice(index, 1);
|
|
226
243
|
queue.messageCount--;
|
|
227
244
|
this.persistQueue(queueName);
|
|
228
245
|
}
|
|
229
|
-
|
|
246
|
+
|
|
230
247
|
return { success: true };
|
|
231
248
|
}
|
|
232
249
|
|
|
233
250
|
getQueueUrlAction(req) {
|
|
234
|
-
const queueName =
|
|
251
|
+
const queueName = this.resolveQueueName(req);
|
|
235
252
|
const queue = this.queues.get(queueName);
|
|
236
|
-
|
|
253
|
+
|
|
237
254
|
if (!queue) {
|
|
238
255
|
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
239
256
|
}
|
|
240
|
-
|
|
257
|
+
|
|
241
258
|
return { queueUrl: queue.url };
|
|
242
259
|
}
|
|
243
260
|
|
|
@@ -247,32 +264,32 @@ class SQSSimulator {
|
|
|
247
264
|
url: q.url,
|
|
248
265
|
messageCount: q.messageCount
|
|
249
266
|
}));
|
|
250
|
-
|
|
267
|
+
|
|
251
268
|
return { queues };
|
|
252
269
|
}
|
|
253
270
|
|
|
254
271
|
attachLambdaToQueue(queueName, handler, options = {}) {
|
|
255
272
|
const queue = this.queues.get(queueName);
|
|
256
|
-
|
|
273
|
+
|
|
257
274
|
if (!queue) {
|
|
258
275
|
this.createQueue(queueName);
|
|
259
276
|
return this.attachLambdaToQueue(queueName, handler, options);
|
|
260
277
|
}
|
|
261
|
-
|
|
278
|
+
|
|
262
279
|
queue.handler = handler;
|
|
263
280
|
queue.batchSize = options.batchSize || 10;
|
|
264
281
|
this.persistQueue(queueName);
|
|
265
|
-
|
|
282
|
+
|
|
266
283
|
logger.debug(`🔗 Lambda associada à fila ${queueName}`);
|
|
267
|
-
|
|
284
|
+
|
|
268
285
|
return queue;
|
|
269
286
|
}
|
|
270
287
|
|
|
271
288
|
async processQueueMessages(queue) {
|
|
272
289
|
if (!queue.handler || queue.messages.length === 0) return;
|
|
273
|
-
|
|
290
|
+
|
|
274
291
|
const messagesToProcess = queue.messages.splice(0, queue.batchSize);
|
|
275
|
-
|
|
292
|
+
|
|
276
293
|
const event = {
|
|
277
294
|
Records: messagesToProcess.map(msg => ({
|
|
278
295
|
messageId: msg.MessageId,
|
|
@@ -286,27 +303,29 @@ class SQSSimulator {
|
|
|
286
303
|
awsRegion: 'local'
|
|
287
304
|
}))
|
|
288
305
|
};
|
|
289
|
-
|
|
306
|
+
|
|
290
307
|
logger.verboso(`🔄 Processando ${messagesToProcess.length} mensagens da fila ${queue.name}`);
|
|
291
|
-
|
|
308
|
+
|
|
292
309
|
try {
|
|
293
310
|
const result = await queue.handler(event);
|
|
294
|
-
|
|
311
|
+
|
|
295
312
|
if (result && result.batchItemFailures && result.batchItemFailures.length > 0) {
|
|
296
313
|
const failedIds = new Set(result.batchItemFailures.map(f => f.itemIdentifier));
|
|
297
314
|
const failedMessages = messagesToProcess.filter(msg => failedIds.has(msg.MessageId));
|
|
298
315
|
queue.messages.unshift(...failedMessages);
|
|
299
316
|
logger.warn(`⚠️ ${failedMessages.length} mensagens falharam`);
|
|
317
|
+
} else {
|
|
318
|
+
queue.messageCount -= messagesToProcess.length;
|
|
300
319
|
}
|
|
301
320
|
} catch (error) {
|
|
302
321
|
logger.error(`❌ Erro ao processar mensagens:`, error);
|
|
303
322
|
queue.messages.unshift(...messagesToProcess);
|
|
304
323
|
}
|
|
305
|
-
|
|
324
|
+
|
|
306
325
|
this.persistQueue(queue.name);
|
|
307
326
|
}
|
|
308
327
|
|
|
309
|
-
|
|
328
|
+
persistQueues() {
|
|
310
329
|
const queuesObj = {};
|
|
311
330
|
for (const [name, queue] of this.queues.entries()) {
|
|
312
331
|
queuesObj[name] = {
|
|
@@ -348,244 +367,6 @@ class SQSSimulator {
|
|
|
348
367
|
}
|
|
349
368
|
}
|
|
350
369
|
|
|
351
|
-
attachLambdaToQueue(queueName, handler, options = {}) {
|
|
352
|
-
const queue = this.queues.get(queueName);
|
|
353
|
-
|
|
354
|
-
if (!queue) {
|
|
355
|
-
this.createQueue(queueName);
|
|
356
|
-
return this.attachLambdaToQueue(queueName, handler, options);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
queue.handler = handler;
|
|
360
|
-
queue.batchSize = options.batchSize || 10;
|
|
361
|
-
this.persistQueues();
|
|
362
|
-
|
|
363
|
-
logger.debug(`🔗 Lambda associada à fila ${queueName}`);
|
|
364
|
-
|
|
365
|
-
return queue;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
async processQueueMessages(queue) {
|
|
369
|
-
if (!queue.handler || queue.messages.length === 0) return;
|
|
370
|
-
|
|
371
|
-
const messagesToProcess = queue.messages.splice(0, queue.batchSize);
|
|
372
|
-
|
|
373
|
-
const event = {
|
|
374
|
-
Records: messagesToProcess.map(msg => ({
|
|
375
|
-
messageId: msg.MessageId,
|
|
376
|
-
receiptHandle: msg.ReceiptHandle,
|
|
377
|
-
body: msg.Body,
|
|
378
|
-
attributes: msg.Attributes,
|
|
379
|
-
messageAttributes: {},
|
|
380
|
-
md5OfBody: msg.MD5OfBody,
|
|
381
|
-
eventSource: 'aws:sqs',
|
|
382
|
-
eventSourceARN: queue.arn,
|
|
383
|
-
awsRegion: 'local'
|
|
384
|
-
}))
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
logger.verboso(`🔄 Processando ${messagesToProcess.length} mensagens da fila ${queue.name}`);
|
|
388
|
-
|
|
389
|
-
try {
|
|
390
|
-
const result = await queue.handler(event);
|
|
391
|
-
|
|
392
|
-
if (result && result.batchItemFailures && result.batchItemFailures.length > 0) {
|
|
393
|
-
const failedIds = new Set(result.batchItemFailures.map(f => f.itemIdentifier));
|
|
394
|
-
const failedMessages = messagesToProcess.filter(msg => failedIds.has(msg.MessageId));
|
|
395
|
-
queue.messages.unshift(...failedMessages);
|
|
396
|
-
logger.warn(`⚠️ ${failedMessages.length} mensagens falharam`);
|
|
397
|
-
} else {
|
|
398
|
-
queue.messageCount -= messagesToProcess.length;
|
|
399
|
-
}
|
|
400
|
-
} catch (error) {
|
|
401
|
-
logger.error(`❌ Erro ao processar mensagens:`, error);
|
|
402
|
-
queue.messages.unshift(...messagesToProcess);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
this.persistQueue(queue.name);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
handleRequest(action, req, res) {
|
|
409
|
-
switch(action) {
|
|
410
|
-
case 'CreateQueue':
|
|
411
|
-
return this.createQueueAction(req);
|
|
412
|
-
case 'SendMessage':
|
|
413
|
-
return this.sendMessageAction(req);
|
|
414
|
-
case 'SendMessageBatch':
|
|
415
|
-
return this.sendMessageBatchAction(req);
|
|
416
|
-
case 'ReceiveMessage':
|
|
417
|
-
return this.receiveMessageAction(req);
|
|
418
|
-
case 'DeleteMessage':
|
|
419
|
-
return this.deleteMessageAction(req);
|
|
420
|
-
case 'GetQueueUrl':
|
|
421
|
-
return this.getQueueUrlAction(req);
|
|
422
|
-
case 'ListQueues':
|
|
423
|
-
return this.listQueuesAction(req);
|
|
424
|
-
default:
|
|
425
|
-
return { error: { code: 'InvalidAction', message: `Action ${action} not supported` }, status: 400 };
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
createQueueAction(req) {
|
|
430
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
431
|
-
const result = this.createQueue(queueName);
|
|
432
|
-
|
|
433
|
-
if (result.error) {
|
|
434
|
-
return result;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return { queueUrl: result.queue.url };
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
sendMessageAction(req) {
|
|
441
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
442
|
-
const queue = this.queues.get(queueName);
|
|
443
|
-
|
|
444
|
-
if (!queue) {
|
|
445
|
-
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const messageBody = req.query.MessageBody || req.body.MessageBody;
|
|
449
|
-
const messageId = crypto.randomUUID();
|
|
450
|
-
const receiptHandle = crypto.randomUUID();
|
|
451
|
-
const md5 = crypto.createHash('md5').update(messageBody).digest('hex');
|
|
452
|
-
|
|
453
|
-
const message = {
|
|
454
|
-
MessageId: messageId,
|
|
455
|
-
ReceiptHandle: receiptHandle,
|
|
456
|
-
Body: messageBody,
|
|
457
|
-
MD5OfBody: md5,
|
|
458
|
-
Attributes: {},
|
|
459
|
-
timestamp: Date.now()
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
queue.messages.push(message);
|
|
463
|
-
queue.messageCount++;
|
|
464
|
-
this.persistQueue(queueName);
|
|
465
|
-
|
|
466
|
-
logger.verboso(`📨 Mensagem enviada para ${queueName}: ${messageId}`);
|
|
467
|
-
|
|
468
|
-
if (queue.handler) {
|
|
469
|
-
this.processQueueMessages(queue);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
return { messageId, md5 };
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
sendMessageBatchAction(req) {
|
|
476
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
477
|
-
const queue = this.queues.get(queueName);
|
|
478
|
-
|
|
479
|
-
if (!queue) {
|
|
480
|
-
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const entries = req.query.SendMessageBatchRequestEntry || req.body.SendMessageBatchRequestEntry;
|
|
484
|
-
const batchEntries = Array.isArray(entries) ? entries : [entries];
|
|
485
|
-
|
|
486
|
-
const successful = [];
|
|
487
|
-
const failed = [];
|
|
488
|
-
|
|
489
|
-
for (const entry of batchEntries) {
|
|
490
|
-
try {
|
|
491
|
-
const messageId = crypto.randomUUID();
|
|
492
|
-
const receiptHandle = crypto.randomUUID();
|
|
493
|
-
const md5 = crypto.createHash('md5').update(entry.MessageBody).digest('hex');
|
|
494
|
-
|
|
495
|
-
const message = {
|
|
496
|
-
MessageId: messageId,
|
|
497
|
-
ReceiptHandle: receiptHandle,
|
|
498
|
-
Body: entry.MessageBody,
|
|
499
|
-
MD5OfBody: md5,
|
|
500
|
-
Attributes: {},
|
|
501
|
-
timestamp: Date.now()
|
|
502
|
-
};
|
|
503
|
-
|
|
504
|
-
queue.messages.push(message);
|
|
505
|
-
queue.messageCount++;
|
|
506
|
-
|
|
507
|
-
successful.push({
|
|
508
|
-
Id: entry.Id,
|
|
509
|
-
MessageId: messageId,
|
|
510
|
-
MD5OfMessageBody: md5
|
|
511
|
-
});
|
|
512
|
-
} catch (error) {
|
|
513
|
-
failed.push({
|
|
514
|
-
Id: entry.Id,
|
|
515
|
-
Code: 'InternalError',
|
|
516
|
-
Message: error.message
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
this.persistQueue(queueName);
|
|
522
|
-
|
|
523
|
-
if (queue.handler && successful.length > 0) {
|
|
524
|
-
this.processQueueMessages(queue);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
return { successful, failed };
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
receiveMessageAction(req) {
|
|
531
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
532
|
-
const queue = this.queues.get(queueName);
|
|
533
|
-
|
|
534
|
-
if (!queue) {
|
|
535
|
-
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
const maxNumberOfMessages = parseInt(req.query.MaxNumberOfMessages || req.body.MaxNumberOfMessages || 1);
|
|
539
|
-
const messages = queue.messages.splice(0, maxNumberOfMessages);
|
|
540
|
-
|
|
541
|
-
if (messages.length > 0) {
|
|
542
|
-
queue.messageCount -= messages.length;
|
|
543
|
-
this.persistQueue(queueName);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
return { messages };
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
deleteMessageAction(req) {
|
|
550
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
551
|
-
const receiptHandle = req.query.ReceiptHandle || req.body.ReceiptHandle;
|
|
552
|
-
const queue = this.queues.get(queueName);
|
|
553
|
-
|
|
554
|
-
if (!queue) {
|
|
555
|
-
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
const index = queue.messages.findIndex(m => m.ReceiptHandle === receiptHandle);
|
|
559
|
-
if (index !== -1) {
|
|
560
|
-
queue.messages.splice(index, 1);
|
|
561
|
-
queue.messageCount--;
|
|
562
|
-
this.persistQueue(queueName);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
return { success: true };
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
getQueueUrlAction(req) {
|
|
569
|
-
const queueName = req.query.QueueName || req.body.QueueName;
|
|
570
|
-
const queue = this.queues.get(queueName);
|
|
571
|
-
|
|
572
|
-
if (!queue) {
|
|
573
|
-
return { error: { code: 'QueueDoesNotExist', message: 'Queue does not exist' }, status: 400 };
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
return { queueUrl: queue.url };
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
listQueuesAction(req) {
|
|
580
|
-
const queues = Array.from(this.queues.values()).map(q => ({
|
|
581
|
-
name: q.name,
|
|
582
|
-
url: q.url,
|
|
583
|
-
messageCount: q.messageCount
|
|
584
|
-
}));
|
|
585
|
-
|
|
586
|
-
return { queues };
|
|
587
|
-
}
|
|
588
|
-
|
|
589
370
|
listQueues() {
|
|
590
371
|
return Array.from(this.queues.values()).map(q => ({
|
|
591
372
|
name: q.name,
|
|
@@ -598,7 +379,7 @@ class SQSSimulator {
|
|
|
598
379
|
getQueue(queueName) {
|
|
599
380
|
const queue = this.queues.get(queueName);
|
|
600
381
|
if (!queue) return null;
|
|
601
|
-
|
|
382
|
+
|
|
602
383
|
return {
|
|
603
384
|
name: queue.name,
|
|
604
385
|
url: queue.url,
|
|
@@ -657,4 +438,4 @@ class SQSSimulator {
|
|
|
657
438
|
}
|
|
658
439
|
}
|
|
659
440
|
|
|
660
|
-
module.exports = SQSSimulator;
|
|
441
|
+
module.exports = SQSSimulator;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const STSServer = require('./server');
|
|
2
|
+
const logger = require('../../utils/logger');
|
|
3
|
+
|
|
4
|
+
class STSService {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
this.name = 'sts';
|
|
8
|
+
this.port = config.ports.sts || 9326;
|
|
9
|
+
this.server = null;
|
|
10
|
+
this.isRunning = false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async initialize() {
|
|
14
|
+
this.server = new STSServer(this.port, this.config);
|
|
15
|
+
await this.server.initialize();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async start() {
|
|
19
|
+
if (this.isRunning) return;
|
|
20
|
+
await this.server.start();
|
|
21
|
+
this.isRunning = true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async stop() {
|
|
25
|
+
if (!this.isRunning) return;
|
|
26
|
+
await this.server.stop();
|
|
27
|
+
this.isRunning = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async reset() {}
|
|
31
|
+
|
|
32
|
+
getStatus() {
|
|
33
|
+
return { running: this.isRunning, port: this.port, endpoint: `http://localhost:${this.port}` };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
module.exports = STSService;
|