@gugananuvem/aws-local-simulator 1.0.35 → 1.0.39

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 (149) hide show
  1. package/README.md +662 -658
  2. package/package.json +10 -3
  3. package/src/config/default-config.js +71 -0
  4. package/src/config/env-loader.js +4 -2
  5. package/src/middleware/authorization.js +271 -0
  6. package/src/middleware/cloudtrail-logger.js +333 -0
  7. package/src/middleware/error-handler.js +138 -0
  8. package/src/middleware/index.js +79 -0
  9. package/src/middleware/policy-enforcement.js +407 -0
  10. package/src/server.js +74 -4
  11. package/src/services/acm/index.js +66 -0
  12. package/src/services/acm/models/certificate.js +202 -0
  13. package/src/services/acm/server.js +224 -0
  14. package/src/services/acm/simulator.js +293 -0
  15. package/src/services/alb/index.js +104 -0
  16. package/src/services/alb/models/loadBalancer.js +88 -0
  17. package/src/services/alb/models/targetGroup.js +128 -0
  18. package/src/services/alb/server.js +160 -0
  19. package/src/services/alb/simulator.js +262 -0
  20. package/src/services/apigateway/index.js +22 -0
  21. package/src/services/apigateway/server.js +247 -35
  22. package/src/services/apigateway/simulator.js +780 -26
  23. package/src/services/asg/index.js +100 -0
  24. package/src/services/asg/models/autoScalingGroup.js +110 -0
  25. package/src/services/asg/models/launchTemplate.js +41 -0
  26. package/src/services/asg/models/scalingPolicy.js +51 -0
  27. package/src/services/asg/server.js +236 -0
  28. package/src/services/asg/simulator.js +410 -0
  29. package/src/services/aurora/cluster-manager.js +731 -0
  30. package/src/services/aurora/data-api.js +514 -0
  31. package/src/services/aurora/db-engine.js +270 -0
  32. package/src/services/aurora/index.js +159 -0
  33. package/src/services/aurora/rds-api.js +189 -0
  34. package/src/services/aurora/server.js +213 -0
  35. package/src/services/aurora/sql-translator.js +334 -0
  36. package/src/services/cloudformation/index.js +2 -2
  37. package/src/services/cloudformation/server.js +1 -0
  38. package/src/services/cloudfront/cache-engine.js +225 -0
  39. package/src/services/cloudfront/geo-restrictions.js +377 -0
  40. package/src/services/cloudfront/index.js +220 -0
  41. package/src/services/cloudfront/models/behavior.js +158 -0
  42. package/src/services/cloudfront/models/distribution.js +284 -0
  43. package/src/services/cloudfront/models/index.js +99 -0
  44. package/src/services/cloudfront/models/invalidation.js +109 -0
  45. package/src/services/cloudfront/models/origin.js +155 -0
  46. package/src/services/cloudfront/origin-router.js +552 -0
  47. package/src/services/cloudfront/origin-validator.js +398 -0
  48. package/src/services/cloudfront/server.js +512 -0
  49. package/src/services/cloudfront/signed-url-generator.js +377 -0
  50. package/src/services/cloudfront/simulator.js +425 -0
  51. package/src/services/cloudfront/store.js +326 -0
  52. package/src/services/cloudshell/env-builder.js +27 -0
  53. package/src/services/cloudshell/index.js +48 -0
  54. package/src/services/cloudshell/routes.js +60 -0
  55. package/src/services/cloudshell/session-manager.js +226 -0
  56. package/src/services/cloudshell/static/.gitkeep +0 -0
  57. package/src/services/cloudshell/static/index.html +406 -0
  58. package/src/services/cloudshell/websocket-handler.js +107 -0
  59. package/src/services/cloudtrail/index.js +2 -3
  60. package/src/services/cloudtrail/server.js +68 -0
  61. package/src/services/cognito/server.js +4 -1
  62. package/src/services/dynamodb/server.js +4 -1
  63. package/src/services/dynamodb/simulator.js +2 -1
  64. package/src/services/ec2/index.js +101 -0
  65. package/src/services/ec2/instanceServer.js +311 -0
  66. package/src/services/ec2/models/ami.js +39 -0
  67. package/src/services/ec2/models/instance.js +98 -0
  68. package/src/services/ec2/models/networkInterface.js +74 -0
  69. package/src/services/ec2/models/securityGroup.js +71 -0
  70. package/src/services/ec2/server.js +350 -0
  71. package/src/services/ec2/simulator.js +436 -0
  72. package/src/services/eventbridge/server.js +36 -0
  73. package/src/services/eventbridge/simulator.js +230 -45
  74. package/src/services/iam/index.js +65 -0
  75. package/src/services/iam/middleware.js +99 -0
  76. package/src/services/iam/server.js +331 -0
  77. package/src/services/iam/simulator.js +1432 -0
  78. package/src/services/index.js +28 -0
  79. package/src/services/kinesis-analytics/index.js +105 -0
  80. package/src/services/kinesis-analytics/models/application.js +325 -0
  81. package/src/services/kinesis-analytics/models/index.js +12 -0
  82. package/src/services/kinesis-analytics/server.js +250 -0
  83. package/src/services/kinesis-analytics/simulator.js +407 -0
  84. package/src/services/kinesis-analytics/store.js +176 -0
  85. package/src/services/kinesis-data-streams/index.js +106 -0
  86. package/src/services/kinesis-data-streams/models/index.js +12 -0
  87. package/src/services/kinesis-data-streams/models/record.js +70 -0
  88. package/src/services/kinesis-data-streams/models/stream.js +280 -0
  89. package/src/services/kinesis-data-streams/server.js +255 -0
  90. package/src/services/kinesis-data-streams/simulator.js +514 -0
  91. package/src/services/kinesis-data-streams/store.js +163 -0
  92. package/src/services/kinesis-firehose/index.js +106 -0
  93. package/src/services/kinesis-firehose/models/delivery-stream.js +265 -0
  94. package/src/services/kinesis-firehose/models/index.js +10 -0
  95. package/src/services/kinesis-firehose/server.js +215 -0
  96. package/src/services/kinesis-firehose/simulator.js +388 -0
  97. package/src/services/kinesis-firehose/store.js +163 -0
  98. package/src/services/kms/server.js +4 -1
  99. package/src/services/lambda/index.js +26 -0
  100. package/src/services/lambda/server.js +12 -1
  101. package/src/services/lambda/simulator.js +4 -0
  102. package/src/services/opensearch/index.js +105 -0
  103. package/src/services/opensearch/models/document.js +115 -0
  104. package/src/services/opensearch/models/index.js +73 -0
  105. package/src/services/opensearch/server.js +310 -0
  106. package/src/services/opensearch/simulator.js +605 -0
  107. package/src/services/opensearch/store.js +162 -0
  108. package/src/services/organizations/control-tower-simulator.js +321 -0
  109. package/src/services/organizations/control-tower-store.js +182 -0
  110. package/src/services/organizations/iam-integration.js +413 -0
  111. package/src/services/organizations/index.js +172 -0
  112. package/src/services/organizations/models/index.js +13 -0
  113. package/src/services/organizations/models/invitation.js +48 -0
  114. package/src/services/organizations/models/organization.js +566 -0
  115. package/src/services/organizations/models/role.js +244 -0
  116. package/src/services/organizations/models/scp.js +131 -0
  117. package/src/services/organizations/server.js +736 -0
  118. package/src/services/organizations/simulator.js +593 -0
  119. package/src/services/organizations/store.js +235 -0
  120. package/src/services/organizations/vpc-integration.js +453 -0
  121. package/src/services/route53/index.js +67 -0
  122. package/src/services/route53/models/healthCheck.js +101 -0
  123. package/src/services/route53/models/hostedZone.js +37 -0
  124. package/src/services/route53/models/resourceRecord.js +106 -0
  125. package/src/services/route53/server.js +841 -0
  126. package/src/services/route53/simulator.js +350 -0
  127. package/src/services/s3/index.js +62 -0
  128. package/src/services/s3/presigned-url-generator.js +337 -0
  129. package/src/services/s3/server.js +231 -0
  130. package/src/services/s3/simulator.js +551 -4
  131. package/src/services/sns/index.js +31 -0
  132. package/src/services/sns/server.js +9 -0
  133. package/src/services/sqs/index.js +38 -0
  134. package/src/services/sqs/server.js +57 -4
  135. package/src/services/sqs/simulator.js +423 -33
  136. package/src/services/sts/simulator.js +209 -17
  137. package/src/services/vpc/README.md +459 -0
  138. package/src/services/vpc/ec2ResponseFormatter.js +431 -0
  139. package/src/services/vpc/index.js +90 -0
  140. package/src/services/vpc/models/internetGateway.js +71 -0
  141. package/src/services/vpc/models/routeTable.js +160 -0
  142. package/src/services/vpc/models/subnet.js +48 -0
  143. package/src/services/vpc/models/vpc.js +37 -0
  144. package/src/services/vpc/models/vpcEndpoint.js +100 -0
  145. package/src/services/vpc/models/vpcGateway.js +134 -0
  146. package/src/services/vpc/server.js +836 -0
  147. package/src/services/vpc/simulator.js +613 -0
  148. package/src/utils/policy-cache.js +215 -0
  149. package/aws-config +0 -154
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Kinesis Data Firehose Service - Ponto de entrada
3
+ */
4
+
5
+ const KinesisFirehoseServer = require('./server');
6
+ const KinesisFirehoseSimulator = require('./simulator');
7
+
8
+ class KinesisFirehoseService {
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.name = 'kinesis-firehose';
12
+ this.port = config.ports['kinesis-firehose'] || 4569;
13
+ this.server = null;
14
+ this.simulator = null;
15
+ this.isRunning = false;
16
+ }
17
+
18
+ async initialize() {
19
+ const logger = require('../../utils/logger');
20
+ logger.debug(`Inicializando Kinesis Firehose Service na porta ${this.port}...`);
21
+
22
+ this.simulator = new KinesisFirehoseSimulator(this.config);
23
+ await this.simulator.initialize();
24
+
25
+ this.server = new KinesisFirehoseServer(this.port, this.config);
26
+ this.server.simulator = this.simulator;
27
+
28
+ await this.server.initialize();
29
+
30
+ logger.debug('Kinesis Firehose Service inicializado');
31
+ }
32
+
33
+ injectDependencies(server) {
34
+ // Aqui você pode injetar dependências de outros serviços se necessário
35
+ }
36
+
37
+ async start() {
38
+ const logger = require('../../utils/logger');
39
+
40
+ if (this.isRunning) {
41
+ logger.warn('Kinesis Firehose Service já está em execução');
42
+ return;
43
+ }
44
+
45
+ try {
46
+ await this.server.start();
47
+ this.isRunning = true;
48
+ logger.info('Kinesis Firehose Service iniciado com sucesso');
49
+ } catch (error) {
50
+ logger.error(`Erro ao iniciar Kinesis Firehose Service: ${error.message}`);
51
+ throw error;
52
+ }
53
+ }
54
+
55
+ async stop() {
56
+ const logger = require('../../utils/logger');
57
+
58
+ if (!this.isRunning) {
59
+ logger.warn('Kinesis Firehose Service não está em execução');
60
+ return;
61
+ }
62
+
63
+ try {
64
+ await this.server.stop();
65
+ this.isRunning = false;
66
+ logger.info('Kinesis Firehose Service parado com sucesso');
67
+ } catch (error) {
68
+ logger.error(`Erro ao parar Kinesis Firehose Service: ${error.message}`);
69
+ throw error;
70
+ }
71
+ }
72
+
73
+ async reset() {
74
+ const logger = require('../../utils/logger');
75
+ try {
76
+ await this.simulator.reset();
77
+ logger.info('Kinesis Firehose Service resetado');
78
+ } catch (error) {
79
+ logger.error(`Erro ao resetar Kinesis Firehose Service: ${error.message}`);
80
+ throw error;
81
+ }
82
+ }
83
+
84
+ getSimulator() {
85
+ return this.simulator;
86
+ }
87
+
88
+ getStatus() {
89
+ const stats = this.simulator?.getStats() || { deliveryStreamsCount: 0, totalRecords: 0, totalDeliveredRecords: 0 };
90
+
91
+ return {
92
+ name: this.name,
93
+ running: this.isRunning,
94
+ port: this.port,
95
+ endpoint: `http://localhost:${this.port}`,
96
+ resources: {
97
+ deliveryStreamsCount: stats.deliveryStreamsCount,
98
+ totalRecords: stats.totalRecords,
99
+ totalDeliveredRecords: stats.totalDeliveredRecords,
100
+ totalFailedRecords: stats.totalFailedRecords
101
+ }
102
+ };
103
+ }
104
+ }
105
+
106
+ module.exports = KinesisFirehoseService;
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Kinesis Data Firehose - DeliveryStream Model
3
+ * Representa um stream de entrega (delivery stream)
4
+ */
5
+
6
+ const { v4: uuidv4 } = require('uuid');
7
+
8
+ class DeliveryStream {
9
+ constructor(deliveryStreamName, config = {}) {
10
+ this.deliveryStreamName = deliveryStreamName;
11
+ this.deliveryStreamArn = `arn:aws:firehose:us-east-1:123456789012:deliverystream/${deliveryStreamName}`;
12
+ this.deliveryStreamStatus = 'ACTIVE';
13
+ this.deliveryStreamType = config.deliveryStreamType || 'DirectPut';
14
+ this.deliveryStreamCreationTimestamp = new Date().toISOString();
15
+ this.lastUpdateTimestamp = new Date().toISOString();
16
+
17
+ // Fonte de dados (pode ser Kinesis Data Stream)
18
+ this.sourceDescription = config.sourceDescription || null;
19
+
20
+ // Destinos (S3, HTTP, Redshift, etc)
21
+ this.destinations = [];
22
+ this.failedDestinationCount = 0;
23
+
24
+ // Configurações de destino
25
+ this.s3DestinationDescription = config.s3DestinationDescription || null;
26
+ this.httpDestinationDescription = config.httpDestinationDescription || null;
27
+ this.redshiftDestinationDescription = config.redshiftDestinationDescription || null;
28
+
29
+ // Versão
30
+ this.versionId = config.versionId || '1';
31
+
32
+ // Buffer de entrega
33
+ this.deliveryBuffer = new DeliveryBuffer();
34
+
35
+ // Estatísticas
36
+ this.recordCount = 0;
37
+ this.deliveredRecordCount = 0;
38
+ this.failedDeliveryRecordCount = 0;
39
+ this.incomingRecords = 0;
40
+ this.incomingBytes = 0;
41
+ this.deliveredBytes = 0;
42
+
43
+ // Tags
44
+ this.tags = config.tags || {};
45
+ }
46
+
47
+ /**
48
+ * Adiciona destino
49
+ */
50
+ addDestination(destination) {
51
+ this.destinations.push(destination);
52
+ if (destination.type === 's3') {
53
+ this.s3DestinationDescription = destination;
54
+ } else if (destination.type === 'http') {
55
+ this.httpDestinationDescription = destination;
56
+ } else if (destination.type === 'redshift') {
57
+ this.redshiftDestinationDescription = destination;
58
+ }
59
+ this.lastUpdateTimestamp = new Date().toISOString();
60
+ }
61
+
62
+ /**
63
+ * Obtém primeira destination
64
+ */
65
+ getFirstDestination() {
66
+ return this.destinations[0] || null;
67
+ }
68
+
69
+ /**
70
+ * Adiciona record ao buffer
71
+ */
72
+ addRecordToBuffer(recordData) {
73
+ if (!recordData) {
74
+ throw new Error('recordData is required');
75
+ }
76
+
77
+ const record = {
78
+ recordId: uuidv4(),
79
+ data: recordData,
80
+ timestamp: new Date().toISOString(),
81
+ deliveryAttempts: 0,
82
+ deliveryStatus: 'PENDING'
83
+ };
84
+
85
+ this.deliveryBuffer.addRecord(record);
86
+ this.recordCount++;
87
+ this.incomingRecords++;
88
+
89
+ // Calcula tamanho do record
90
+ try {
91
+ const dataStr = typeof recordData === 'string' ? recordData : JSON.stringify(recordData);
92
+ this.incomingBytes += Buffer.byteLength(dataStr);
93
+ } catch (e) {
94
+ // Fallback para tamanho aproximado se conversão falhar
95
+ this.incomingBytes += 100;
96
+ }
97
+
98
+ return record;
99
+ }
100
+
101
+ /**
102
+ * Obtém records pendentes do buffer
103
+ */
104
+ getPendingRecords(limit = 500) {
105
+ return this.deliveryBuffer.getPendingRecords(limit);
106
+ }
107
+
108
+ /**
109
+ * Marca record como entregue
110
+ */
111
+ markRecordAsDelivered(recordId) {
112
+ const record = this.deliveryBuffer.getRecord(recordId);
113
+ if (record) {
114
+ record.deliveryStatus = 'DELIVERED';
115
+ this.deliveredRecordCount++;
116
+ this.deliveredBytes += Buffer.byteLength(JSON.stringify(record.data));
117
+ this.lastUpdateTimestamp = new Date().toISOString();
118
+ return true;
119
+ }
120
+ return false;
121
+ }
122
+
123
+ /**
124
+ * Marca record como falha de entrega
125
+ */
126
+ markRecordAsFailed(recordId) {
127
+ const record = this.deliveryBuffer.getRecord(recordId);
128
+ if (record) {
129
+ record.deliveryAttempts++;
130
+ record.deliveryStatus = 'FAILED';
131
+ this.failedDeliveryRecordCount++;
132
+ this.lastUpdateTimestamp = new Date().toISOString();
133
+ return true;
134
+ }
135
+ return false;
136
+ }
137
+
138
+ /**
139
+ * Retorna descrição do delivery stream
140
+ */
141
+ describe() {
142
+ return {
143
+ DeliveryStreamDescription: {
144
+ DeliveryStreamName: this.deliveryStreamName,
145
+ DeliveryStreamArn: this.deliveryStreamArn,
146
+ DeliveryStreamStatus: this.deliveryStreamStatus,
147
+ DeliveryStreamType: this.deliveryStreamType,
148
+ VersionId: this.versionId,
149
+ CreationTimestamp: this.deliveryStreamCreationTimestamp,
150
+ LastUpdateTimestamp: this.lastUpdateTimestamp,
151
+ Source: this.sourceDescription,
152
+ Destinations: this.destinations.map(d => ({
153
+ DestinationId: d.destinationId || 'destination-1',
154
+ DestinationStatus: d.destinationStatus || 'ACTIVE',
155
+ S3DestinationDescription: d.type === 's3' ? d : undefined,
156
+ HttpEndpointDestinationDescription: d.type === 'http' ? d : undefined,
157
+ RedshiftDestinationDescription: d.type === 'redshift' ? d : undefined
158
+ })),
159
+ HasMoreDestinations: false,
160
+ FailureDescription: null
161
+ }
162
+ };
163
+ }
164
+
165
+ toJSON() {
166
+ return {
167
+ deliveryStreamName: this.deliveryStreamName,
168
+ deliveryStreamArn: this.deliveryStreamArn,
169
+ deliveryStreamStatus: this.deliveryStreamStatus,
170
+ deliveryStreamType: this.deliveryStreamType,
171
+ creationTimestamp: this.deliveryStreamCreationTimestamp,
172
+ lastUpdateTimestamp: this.lastUpdateTimestamp,
173
+ recordCount: this.recordCount,
174
+ deliveredRecordCount: this.deliveredRecordCount,
175
+ failedDeliveryRecordCount: this.failedDeliveryRecordCount,
176
+ incomingRecords: this.incomingRecords,
177
+ incomingBytes: this.incomingBytes,
178
+ deliveredBytes: this.deliveredBytes
179
+ };
180
+ }
181
+ }
182
+
183
+ /**
184
+ * DeliveryBuffer Model - Buffer de records a serem entregues
185
+ */
186
+ class DeliveryBuffer {
187
+ constructor(config = {}) {
188
+ this.bufferSizeMB = config.bufferSizeMB || 128;
189
+ this.bufferIntervalSeconds = config.bufferIntervalSeconds || 60;
190
+ this.records = new Map();
191
+ this.createdAt = new Date();
192
+ this.lastFlushTime = new Date();
193
+ }
194
+
195
+ /**
196
+ * Adiciona record ao buffer
197
+ */
198
+ addRecord(record) {
199
+ this.records.set(record.recordId, record);
200
+ }
201
+
202
+ /**
203
+ * Obtém record
204
+ */
205
+ getRecord(recordId) {
206
+ return this.records.get(recordId);
207
+ }
208
+
209
+ /**
210
+ * Obtém records pendentes
211
+ */
212
+ getPendingRecords(limit = 500) {
213
+ const pending = Array.from(this.records.values())
214
+ .filter(r => r.deliveryStatus === 'PENDING')
215
+ .slice(0, limit);
216
+ return pending;
217
+ }
218
+
219
+ /**
220
+ * Obtém todos os records
221
+ */
222
+ getAllRecords() {
223
+ return Array.from(this.records.values());
224
+ }
225
+
226
+ /**
227
+ * Remove record
228
+ */
229
+ removeRecord(recordId) {
230
+ return this.records.delete(recordId);
231
+ }
232
+
233
+ /**
234
+ * Limpa buffer (para reset)
235
+ */
236
+ clear() {
237
+ this.records.clear();
238
+ this.createdAt = new Date();
239
+ this.lastFlushTime = new Date();
240
+ }
241
+
242
+ /**
243
+ * Obtém estatísticas do buffer
244
+ */
245
+ getStats() {
246
+ const records = Array.from(this.records.values());
247
+ const totalRecords = records.length;
248
+ const pendingRecords = records.filter(r => r.deliveryStatus === 'PENDING').length;
249
+ const deliveredRecords = records.filter(r => r.deliveryStatus === 'DELIVERED').length;
250
+ const failedRecords = records.filter(r => r.deliveryStatus === 'FAILED').length;
251
+
252
+ return {
253
+ totalRecords,
254
+ pendingRecords,
255
+ deliveredRecords,
256
+ failedRecords,
257
+ bufferAge: Date.now() - this.createdAt.getTime()
258
+ };
259
+ }
260
+ }
261
+
262
+ module.exports = {
263
+ DeliveryStream,
264
+ DeliveryBuffer
265
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Kinesis Data Firehose Models
3
+ */
4
+
5
+ const { DeliveryStream, DeliveryBuffer } = require('./delivery-stream');
6
+
7
+ module.exports = {
8
+ DeliveryStream,
9
+ DeliveryBuffer
10
+ };
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Kinesis Data Firehose Server - Servidor HTTP REST/JSON para Firehose
3
+ */
4
+
5
+ const express = require('express');
6
+ const cors = require('cors');
7
+ const logger = require('../../utils/logger');
8
+
9
+ class KinesisFirehoseServer {
10
+ constructor(port, config) {
11
+ this.port = port;
12
+ this.config = config;
13
+ this.app = express();
14
+ this.simulator = null;
15
+ this.server = null;
16
+ this.setupMiddlewares();
17
+ }
18
+
19
+ setupMiddlewares() {
20
+ this.app.use(cors());
21
+ this.app.use(express.json({ limit: '10mb' }));
22
+
23
+ // Custom header parsing para AWS SDK
24
+ this.app.use((req, res, next) => {
25
+ const target = req.headers['x-amz-target'];
26
+ if (target) {
27
+ const [, action] = target.split('.');
28
+ req.action = action;
29
+ }
30
+
31
+ logger.debug(`Kinesis Firehose: ${req.method} ${req.path} - Action: ${req.action || 'none'}`);
32
+ next();
33
+ });
34
+ }
35
+
36
+ async initialize() {
37
+ logger.debug(`Inicializando Kinesis Firehose Server na porta ${this.port}`);
38
+ this.setupRoutes();
39
+ }
40
+
41
+ setupRoutes() {
42
+ this.app.post('/', (req, res) => {
43
+ const action = req.action || req.body.Action;
44
+
45
+ try {
46
+ switch (action) {
47
+ case 'CreateDeliveryStream':
48
+ return this.createDeliveryStream(req, res);
49
+ case 'DescribeDeliveryStream':
50
+ return this.describeDeliveryStream(req, res);
51
+ case 'ListDeliveryStreams':
52
+ return this.listDeliveryStreams(req, res);
53
+ case 'DeleteDeliveryStream':
54
+ return this.deleteDeliveryStream(req, res);
55
+ case 'PutRecord':
56
+ return this.putRecord(req, res);
57
+ case 'PutRecordBatch':
58
+ return this.putRecordBatch(req, res);
59
+ case 'UpdateDeliveryStream':
60
+ return this.updateDeliveryStream(req, res);
61
+ case 'DescribeDestination':
62
+ return this.describeDestination(req, res);
63
+ default:
64
+ res.status(400).json({ __type: 'UnknownAction', message: `Unknown action: ${action}` });
65
+ }
66
+ } catch (error) {
67
+ res.status(400).json({ __type: 'InternalFailure', message: error.message });
68
+ }
69
+ });
70
+
71
+ // Health check
72
+ this.app.get('/health', (req, res) => {
73
+ res.json({
74
+ status: 'healthy',
75
+ service: 'kinesis-firehose',
76
+ port: this.port,
77
+ stats: this.simulator.getStats()
78
+ });
79
+ });
80
+ }
81
+
82
+ async createDeliveryStream(req, res) {
83
+ const {
84
+ DeliveryStreamName,
85
+ DeliveryStreamType = 'DirectPut',
86
+ S3DestinationConfiguration,
87
+ HttpEndpointDestinationConfiguration,
88
+ RedshiftDestinationConfiguration
89
+ } = req.body;
90
+
91
+ if (!DeliveryStreamName) {
92
+ throw new Error('DeliveryStreamName is required');
93
+ }
94
+
95
+ const result = await this.simulator.createDeliveryStream(DeliveryStreamName, {
96
+ deliveryStreamType: DeliveryStreamType,
97
+ s3DestinationConfiguration: S3DestinationConfiguration,
98
+ httpEndpointDestinationConfiguration: HttpEndpointDestinationConfiguration,
99
+ redshiftDestinationConfiguration: RedshiftDestinationConfiguration
100
+ });
101
+
102
+ res.status(201).json(result);
103
+ }
104
+
105
+ async describeDeliveryStream(req, res) {
106
+ const { DeliveryStreamName } = req.body;
107
+
108
+ if (!DeliveryStreamName) {
109
+ throw new Error('DeliveryStreamName is required');
110
+ }
111
+
112
+ const result = this.simulator.describeDeliveryStream(DeliveryStreamName);
113
+ res.json(result);
114
+ }
115
+
116
+ async listDeliveryStreams(req, res) {
117
+ const { Limit, ExclusiveStartDeliveryStreamName } = req.body;
118
+
119
+ const result = this.simulator.listDeliveryStreams({
120
+ Limit,
121
+ ExclusiveStartDeliveryStreamName
122
+ });
123
+
124
+ res.json(result);
125
+ }
126
+
127
+ async deleteDeliveryStream(req, res) {
128
+ const { DeliveryStreamName } = req.body;
129
+
130
+ if (!DeliveryStreamName) {
131
+ throw new Error('DeliveryStreamName is required');
132
+ }
133
+
134
+ const result = await this.simulator.deleteDeliveryStream(DeliveryStreamName);
135
+ res.json(result);
136
+ }
137
+
138
+ async putRecord(req, res) {
139
+ const { DeliveryStreamName, Record } = req.body;
140
+
141
+ if (!DeliveryStreamName || !Record) {
142
+ throw new Error('DeliveryStreamName and Record are required');
143
+ }
144
+
145
+ const result = await this.simulator.putRecord(DeliveryStreamName, Record);
146
+ res.json(result);
147
+ }
148
+
149
+ async putRecordBatch(req, res) {
150
+ const { DeliveryStreamName, Records } = req.body;
151
+
152
+ if (!DeliveryStreamName || !Records || !Array.isArray(Records)) {
153
+ throw new Error('DeliveryStreamName and Records array are required');
154
+ }
155
+
156
+ const result = await this.simulator.putRecordBatch(DeliveryStreamName, Records);
157
+ res.json(result);
158
+ }
159
+
160
+ async updateDeliveryStream(req, res) {
161
+ const { DeliveryStreamName, ...config } = req.body;
162
+
163
+ if (!DeliveryStreamName) {
164
+ throw new Error('DeliveryStreamName is required');
165
+ }
166
+
167
+ const result = this.simulator.updateDeliveryStream(DeliveryStreamName, config);
168
+ res.json(result);
169
+ }
170
+
171
+ async describeDestination(req, res) {
172
+ const { DeliveryStreamName, DestinationId } = req.body;
173
+
174
+ if (!DeliveryStreamName || !DestinationId) {
175
+ throw new Error('DeliveryStreamName and DestinationId are required');
176
+ }
177
+
178
+ const result = this.simulator.describeDestination(DeliveryStreamName, DestinationId);
179
+ res.json(result);
180
+ }
181
+
182
+ async start() {
183
+ return new Promise((resolve, reject) => {
184
+ try {
185
+ this.server = this.app.listen(this.port, () => {
186
+ logger.info(`✅ Kinesis Firehose Server iniciado na porta ${this.port}`);
187
+ resolve();
188
+ });
189
+ } catch (error) {
190
+ logger.error(`❌ Erro ao iniciar Kinesis Firehose Server: ${error.message}`);
191
+ reject(error);
192
+ }
193
+ });
194
+ }
195
+
196
+ async stop() {
197
+ return new Promise((resolve, reject) => {
198
+ if (this.server) {
199
+ this.server.close((err) => {
200
+ if (err) {
201
+ logger.error(`Erro ao parar Kinesis Firehose Server: ${err.message}`);
202
+ reject(err);
203
+ } else {
204
+ logger.info('Kinesis Firehose Server parado');
205
+ resolve();
206
+ }
207
+ });
208
+ } else {
209
+ resolve();
210
+ }
211
+ });
212
+ }
213
+ }
214
+
215
+ module.exports = KinesisFirehoseServer;