@reventlessdev/rescript-aws-sdk 2.2.0-alpha.20
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/CHANGELOG.md +174 -0
- package/LICENSE +202 -0
- package/README.md +21 -0
- package/package.json +44 -0
- package/rescript.json +23 -0
- package/src/CloudWatchEvents.res +162 -0
- package/src/CloudWatchEvents.res.mjs +94 -0
- package/src/CognitoIdentityServiceProvider.res +117 -0
- package/src/CognitoIdentityServiceProvider.res.mjs +70 -0
- package/src/DynamoDb.res +3 -0
- package/src/DynamoDb.res.mjs +15 -0
- package/src/DynamoDb_DocumentClient.res +905 -0
- package/src/DynamoDb_DocumentClient.res.mjs +338 -0
- package/src/DynamoDb_DynamoDb.res +189 -0
- package/src/DynamoDb_DynamoDb.res.mjs +70 -0
- package/src/DynamoDb_Util.res +128 -0
- package/src/DynamoDb_Util.res.mjs +35 -0
- package/src/DynamoDb_Util_Helpers.res +7 -0
- package/src/DynamoDb_Util_Helpers.res.mjs +23 -0
- package/src/ECS.res +96 -0
- package/src/ECS.res.mjs +46 -0
- package/src/IAM.res +20 -0
- package/src/IAM.res.mjs +9 -0
- package/src/Kinesis.res +50 -0
- package/src/Kinesis.res.mjs +39 -0
- package/src/Metadata.res +9 -0
- package/src/Metadata.res.mjs +2 -0
- package/src/NodeHttpHandler.res +6 -0
- package/src/NodeHttpHandler.res.mjs +2 -0
- package/src/S3.res +152 -0
- package/src/S3.res.mjs +61 -0
- package/src/S3_Helpers.res +20 -0
- package/src/S3_Helpers.res.mjs +26 -0
- package/src/SES.res +113 -0
- package/src/SES.res.mjs +59 -0
- package/src/SNS.res +167 -0
- package/src/SNS.res.mjs +98 -0
- package/src/SNS_Helpers.res +45 -0
- package/src/SNS_Helpers.res.mjs +57 -0
- package/src/SQS.res +241 -0
- package/src/SQS.res.mjs +121 -0
- package/src/SQS_Helpers.res +267 -0
- package/src/SQS_Helpers.res.mjs +227 -0
- package/src/SecretsManager.res +61 -0
- package/src/SecretsManager.res.mjs +46 -0
- package/src/example/DynamoDbUtilExample.res +20 -0
- package/src/example/DynamoDbUtilExample.res.mjs +66 -0
package/src/SQS.res
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/*** @aws-sdk/client-sqs
|
|
2
|
+
see: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sqs/
|
|
3
|
+
*/
|
|
4
|
+
type client
|
|
5
|
+
|
|
6
|
+
type options = {
|
|
7
|
+
region?: string,
|
|
8
|
+
maxAttempts?: int,
|
|
9
|
+
requestHandler?: NodeHttpHandler.t,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module Raw = {
|
|
13
|
+
@module("@aws-sdk/client-sqs") @new
|
|
14
|
+
external client: (~options: options, unit) => client = "SQSClient"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let clientInstance = ref(None)
|
|
18
|
+
|
|
19
|
+
let client = () =>
|
|
20
|
+
switch clientInstance.contents {
|
|
21
|
+
| None =>
|
|
22
|
+
let client = Raw.client(
|
|
23
|
+
~options={
|
|
24
|
+
maxAttempts: 5,
|
|
25
|
+
requestHandler: NodeHttpHandler.make({
|
|
26
|
+
connectionTimeout: 1000,
|
|
27
|
+
requestTimeout: 5000,
|
|
28
|
+
}),
|
|
29
|
+
},
|
|
30
|
+
(),
|
|
31
|
+
)
|
|
32
|
+
clientInstance := Some(client)
|
|
33
|
+
client
|
|
34
|
+
| Some(client) => client
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type messageAttribute = {
|
|
38
|
+
@as("Type") type_: string,
|
|
39
|
+
@as("Value") value: string,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module SendMessageCommand = {
|
|
43
|
+
type t
|
|
44
|
+
|
|
45
|
+
type input = {
|
|
46
|
+
@as("MessageBody") messageBody: string,
|
|
47
|
+
@as("QueueUrl") queueUrl: string,
|
|
48
|
+
@as("MessageAttributes") messageAttributes?: dict<messageAttribute>,
|
|
49
|
+
@as("DelaySeconds") delaySeconds?: int, // 0 - 900
|
|
50
|
+
@as("MessageDeduplicationId") messageDeduplicationId?: string,
|
|
51
|
+
@as("MessageGroupId") messageGroupId?: string,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type output = {
|
|
55
|
+
@as("MessageId") messageId: option<string>,
|
|
56
|
+
@as("MD5OfMessageBody") md5OfMessageBody: option<string>,
|
|
57
|
+
@as("MD5OfMessageAttributes") md5OfMessageAttributes: option<string>,
|
|
58
|
+
@as("SequenceNumber") sequenceNumber: option<string>,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@new @module("@aws-sdk/client-sqs")
|
|
62
|
+
external make: input => t = "SendMessageCommand"
|
|
63
|
+
|
|
64
|
+
module Raw = {
|
|
65
|
+
@send
|
|
66
|
+
external send: (client, t) => promise<output> = "send"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module BatchResultErrorEntry = {
|
|
73
|
+
type t = {
|
|
74
|
+
@as("Id") id: string,
|
|
75
|
+
@as("SenderFault") senderFault: bool,
|
|
76
|
+
@as("Code") code: string,
|
|
77
|
+
@as("Message") message: option<string>,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module SendMessageBatchCommand = {
|
|
82
|
+
type t
|
|
83
|
+
|
|
84
|
+
type sendMessageBatchEntry = {
|
|
85
|
+
@as("Id") id: string,
|
|
86
|
+
@as("MessageBody") messageBody: string,
|
|
87
|
+
@as("MessageAttributes") messageAttributes?: dict<messageAttribute>,
|
|
88
|
+
@as("DelaySeconds") delaySeconds?: int, // 0 - 900
|
|
89
|
+
@as("MessageDeduplicationId") messageDeduplicationId?: string,
|
|
90
|
+
@as("MessageGroupId") messageGroupId?: string,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type input = {
|
|
94
|
+
@as("Entries") entries: array<sendMessageBatchEntry>,
|
|
95
|
+
@as("QueueUrl") queueUrl: string,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type sendMessageBatchResultEntry = {
|
|
99
|
+
@as("Id") id: string,
|
|
100
|
+
@as("MessageId") messageId: option<string>,
|
|
101
|
+
@as("MD5OfMessageBody") md5OfMessageBody: option<string>,
|
|
102
|
+
@as("MD5OfMessageAttributes") md5OfMessageAttributes: option<string>,
|
|
103
|
+
@as("SequenceNumber") sequenceNumber: option<string>,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type output = {
|
|
107
|
+
@as("Successful") successful?: array<sendMessageBatchResultEntry>,
|
|
108
|
+
@as("Failed") failed?: array<BatchResultErrorEntry.t>,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@new @module("@aws-sdk/client-sqs")
|
|
112
|
+
external make: input => t = "SendMessageBatchCommand"
|
|
113
|
+
|
|
114
|
+
module Raw = {
|
|
115
|
+
@send
|
|
116
|
+
external send: (client, t) => promise<output> = "send"
|
|
117
|
+
}
|
|
118
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module DeleteMessageCommand = {
|
|
122
|
+
type t
|
|
123
|
+
|
|
124
|
+
type input = {
|
|
125
|
+
@as("QueueUrl") queueUrl: string,
|
|
126
|
+
@as("ReceiptHandle") receiptHandle: string,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
type output = {.}
|
|
130
|
+
|
|
131
|
+
@new @module("@aws-sdk/client-sqs")
|
|
132
|
+
external make: input => t = "DeleteMessageCommand"
|
|
133
|
+
|
|
134
|
+
module Raw = {
|
|
135
|
+
@send
|
|
136
|
+
external send: (client, t) => promise<output> = "send"
|
|
137
|
+
}
|
|
138
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module DeleteMessageBatchCommand = {
|
|
142
|
+
type t
|
|
143
|
+
|
|
144
|
+
type deleteMessageBatchEntry = {
|
|
145
|
+
@as("Id") id: string,
|
|
146
|
+
@as("ReceiptHandle") receiptHandle: string,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
type input = {
|
|
150
|
+
@as("QueueUrl") queueUrl: string,
|
|
151
|
+
@as("Entries") entries: array<deleteMessageBatchEntry>,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type deleteMessageBatchResultEntry = {@as("Id") id: string}
|
|
155
|
+
|
|
156
|
+
type output = {
|
|
157
|
+
@as("Successful") successful?: array<deleteMessageBatchResultEntry>,
|
|
158
|
+
@as("Failed") failed?: array<BatchResultErrorEntry.t>,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@new @module("@aws-sdk/client-sqs")
|
|
162
|
+
external make: input => t = "DeleteMessageBatchCommand"
|
|
163
|
+
|
|
164
|
+
module Raw = {
|
|
165
|
+
@send
|
|
166
|
+
external send: (client, t) => promise<output> = "send"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module AddPermissionCommand = {
|
|
173
|
+
type t
|
|
174
|
+
|
|
175
|
+
type input = {
|
|
176
|
+
@as("AWSAccountIds") awsAccountIds: array<string>,
|
|
177
|
+
@as("Actions") actions: array<string>,
|
|
178
|
+
@as("Label") label: string,
|
|
179
|
+
@as("QueueUrl") queueUrl: string,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
type output = {.}
|
|
183
|
+
|
|
184
|
+
@new @module("@aws-sdk/client-sqs")
|
|
185
|
+
external make: input => t = "AddPermissionCommand"
|
|
186
|
+
|
|
187
|
+
module Raw = {
|
|
188
|
+
@send
|
|
189
|
+
external send: (client, t) => promise<output> = "send"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module GetQueueAttributesCommand = {
|
|
196
|
+
type t
|
|
197
|
+
|
|
198
|
+
type input = {
|
|
199
|
+
@as("AttributeNames") attributeNames: array<string>,
|
|
200
|
+
@as("QueueUrl") queueUrl: string,
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
type policy
|
|
204
|
+
|
|
205
|
+
@val @scope("JSON")
|
|
206
|
+
external unsafeParsePolicy: policy => IAM.Policy.t = "parse"
|
|
207
|
+
|
|
208
|
+
type attributes = {@as("Policy") policy: policy}
|
|
209
|
+
|
|
210
|
+
type output = {@as("Attributes") attributes: attributes}
|
|
211
|
+
|
|
212
|
+
@new @module("@aws-sdk/client-sqs")
|
|
213
|
+
external make: input => t = "GetQueueAttributesCommand"
|
|
214
|
+
|
|
215
|
+
module Raw = {
|
|
216
|
+
@send
|
|
217
|
+
external send: (client, t) => promise<output> = "send"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module SetQueueAttributesCommand = {
|
|
224
|
+
type t
|
|
225
|
+
|
|
226
|
+
type attributes = {@as("Policy") policy?: string}
|
|
227
|
+
|
|
228
|
+
type input = {@as("Attributes") attributes: attributes, @as("QueueUrl") queueUrl: string}
|
|
229
|
+
|
|
230
|
+
type output = {.}
|
|
231
|
+
|
|
232
|
+
@new @module("@aws-sdk/client-sqs")
|
|
233
|
+
external make: input => t = "SetQueueAttributesCommand"
|
|
234
|
+
|
|
235
|
+
module Raw = {
|
|
236
|
+
@send
|
|
237
|
+
external send: (client, t) => promise<output> = "send"
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
let send: t => promise<output> = command => Raw.send(client(), command)
|
|
241
|
+
}
|
package/src/SQS.res.mjs
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
4
|
+
import * as ClientSqs from "@aws-sdk/client-sqs";
|
|
5
|
+
import * as NodeHttpHandler from "@smithy/node-http-handler";
|
|
6
|
+
|
|
7
|
+
let Raw = {};
|
|
8
|
+
|
|
9
|
+
let clientInstance = {
|
|
10
|
+
contents: undefined
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function client() {
|
|
14
|
+
let client$1 = clientInstance.contents;
|
|
15
|
+
if (client$1 !== undefined) {
|
|
16
|
+
return Primitive_option.valFromOption(client$1);
|
|
17
|
+
}
|
|
18
|
+
let client$2 = new ClientSqs.SQSClient({
|
|
19
|
+
maxAttempts: 5,
|
|
20
|
+
requestHandler: Primitive_option.some(new NodeHttpHandler.NodeHttpHandler({
|
|
21
|
+
connectionTimeout: 1000,
|
|
22
|
+
requestTimeout: 5000
|
|
23
|
+
}))
|
|
24
|
+
});
|
|
25
|
+
clientInstance.contents = Primitive_option.some(client$2);
|
|
26
|
+
return client$2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let Raw$1 = {};
|
|
30
|
+
|
|
31
|
+
function send(command) {
|
|
32
|
+
return client().send(command);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let SendMessageCommand = {
|
|
36
|
+
Raw: Raw$1,
|
|
37
|
+
send: send
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let BatchResultErrorEntry = {};
|
|
41
|
+
|
|
42
|
+
let Raw$2 = {};
|
|
43
|
+
|
|
44
|
+
function send$1(command) {
|
|
45
|
+
return client().send(command);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let SendMessageBatchCommand = {
|
|
49
|
+
Raw: Raw$2,
|
|
50
|
+
send: send$1
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
let Raw$3 = {};
|
|
54
|
+
|
|
55
|
+
function send$2(command) {
|
|
56
|
+
return client().send(command);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let DeleteMessageCommand = {
|
|
60
|
+
Raw: Raw$3,
|
|
61
|
+
send: send$2
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let Raw$4 = {};
|
|
65
|
+
|
|
66
|
+
function send$3(command) {
|
|
67
|
+
return client().send(command);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let DeleteMessageBatchCommand = {
|
|
71
|
+
Raw: Raw$4,
|
|
72
|
+
send: send$3
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
let Raw$5 = {};
|
|
76
|
+
|
|
77
|
+
function send$4(command) {
|
|
78
|
+
return client().send(command);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let AddPermissionCommand = {
|
|
82
|
+
Raw: Raw$5,
|
|
83
|
+
send: send$4
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let Raw$6 = {};
|
|
87
|
+
|
|
88
|
+
function send$5(command) {
|
|
89
|
+
return client().send(command);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let GetQueueAttributesCommand = {
|
|
93
|
+
Raw: Raw$6,
|
|
94
|
+
send: send$5
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let Raw$7 = {};
|
|
98
|
+
|
|
99
|
+
function send$6(command) {
|
|
100
|
+
return client().send(command);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let SetQueueAttributesCommand = {
|
|
104
|
+
Raw: Raw$7,
|
|
105
|
+
send: send$6
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
Raw,
|
|
110
|
+
clientInstance,
|
|
111
|
+
client,
|
|
112
|
+
SendMessageCommand,
|
|
113
|
+
BatchResultErrorEntry,
|
|
114
|
+
SendMessageBatchCommand,
|
|
115
|
+
DeleteMessageCommand,
|
|
116
|
+
DeleteMessageBatchCommand,
|
|
117
|
+
AddPermissionCommand,
|
|
118
|
+
GetQueueAttributesCommand,
|
|
119
|
+
SetQueueAttributesCommand,
|
|
120
|
+
}
|
|
121
|
+
/* @aws-sdk/client-sqs Not a pure module */
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// Example ARN: arn:aws:sqs:eu-west-1:xxxxxx:MarketplaceServiceExtensionPointCommandTopic-0101023
|
|
2
|
+
// Example URL: https://sqs.eu-west-1.amazonaws.com/xxxxxx/MarketplaceServiceExtensionPointCommandTopic-0101023
|
|
3
|
+
let arn2Url = arn =>
|
|
4
|
+
switch arn->String.split(":") {
|
|
5
|
+
| [_, _, service, region, account, queueName] =>
|
|
6
|
+
`https://${service}.${region}.amazonaws.com/${account}/${queueName}`
|
|
7
|
+
| _ => ""
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let validateDelay = Option.map(_, delay =>
|
|
11
|
+
if delay > 900 {
|
|
12
|
+
Console.log2(
|
|
13
|
+
"WARNING: [" ++
|
|
14
|
+
(__MODULE__ ++
|
|
15
|
+
(":" ++
|
|
16
|
+
(__LINE__->Int.toString ++
|
|
17
|
+
("] SQS.sendMessage was called with a delay set to higher than 900 seconds, " ++ "which is the maximum amount supported by AWS.")))),
|
|
18
|
+
"DelaySeconds was automatically set to 900 to prevent failure.",
|
|
19
|
+
)
|
|
20
|
+
900
|
|
21
|
+
} else {
|
|
22
|
+
delay
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
let sendMessage = async (
|
|
27
|
+
~queueId,
|
|
28
|
+
~messageBody,
|
|
29
|
+
~messageGroupId=?,
|
|
30
|
+
~messageDeduplicationId=?,
|
|
31
|
+
~delay=?,
|
|
32
|
+
) =>
|
|
33
|
+
(
|
|
34
|
+
await SQS.SendMessageCommand.send(
|
|
35
|
+
SQS.SendMessageCommand.make({
|
|
36
|
+
queueUrl: queueId,
|
|
37
|
+
messageBody,
|
|
38
|
+
messageGroupId: ?(messageGroupId->Option.map(id => id->String.replaceRegExp(/ /g, ""))),
|
|
39
|
+
?messageDeduplicationId,
|
|
40
|
+
delaySeconds: ?(
|
|
41
|
+
delay->Option.map(delay =>
|
|
42
|
+
if delay > 900 {
|
|
43
|
+
Console.log2(
|
|
44
|
+
"WARNING: [" ++
|
|
45
|
+
(__MODULE__ ++
|
|
46
|
+
(":" ++
|
|
47
|
+
(__LINE__->Int.toString ++
|
|
48
|
+
("] SQS.sendMessage was called with a delay set to higher than 900 seconds, " ++ "which is the maximum amount supported by AWS.")))),
|
|
49
|
+
"DelaySeconds was automatically set to 900 to prevent failure.",
|
|
50
|
+
)
|
|
51
|
+
900
|
|
52
|
+
} else {
|
|
53
|
+
delay
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
),
|
|
57
|
+
}),
|
|
58
|
+
)
|
|
59
|
+
)->ignore
|
|
60
|
+
|
|
61
|
+
let makeBatchEntry = (
|
|
62
|
+
~messageBody,
|
|
63
|
+
~messageId,
|
|
64
|
+
~delay=?,
|
|
65
|
+
): SQS.SendMessageBatchCommand.sendMessageBatchEntry => {
|
|
66
|
+
messageBody,
|
|
67
|
+
id: messageId,
|
|
68
|
+
delaySeconds: ?(delay->validateDelay),
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let makeBatchEntryFifo = (
|
|
72
|
+
~groupId,
|
|
73
|
+
~messageBody,
|
|
74
|
+
~messageId,
|
|
75
|
+
~delay=?,
|
|
76
|
+
): SQS.SendMessageBatchCommand.sendMessageBatchEntry => {
|
|
77
|
+
messageBody,
|
|
78
|
+
id: messageId,
|
|
79
|
+
delaySeconds: ?(delay->validateDelay),
|
|
80
|
+
messageGroupId: groupId->String.replaceRegExp(/ /g, ""),
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let maxBatchMessages = 10 // defined by SQS
|
|
84
|
+
let maxBatchBytes = 262144 // defined by SQS
|
|
85
|
+
|
|
86
|
+
//FIXME: 1:1 like handleDeleteBatchPromises, only difference is in types of parameters
|
|
87
|
+
let handleSendBatchPromises: (
|
|
88
|
+
array<promise<SQS.SendMessageBatchCommand.output>>,
|
|
89
|
+
array<SQS.SendMessageBatchCommand.sendMessageBatchEntry>,
|
|
90
|
+
string,
|
|
91
|
+
) => promise<array<array<string>>> = (promises, entries, name) => {
|
|
92
|
+
promises
|
|
93
|
+
->Array.mapWithIndex(async (promise, idx) => {
|
|
94
|
+
let batchNr = (idx + 1)->Int.toString
|
|
95
|
+
switch await promise {
|
|
96
|
+
| response =>
|
|
97
|
+
response.failed
|
|
98
|
+
->Option.getOr([])
|
|
99
|
+
->Array.map(failure => {
|
|
100
|
+
let id = failure.id
|
|
101
|
+
let failureCode = failure.code
|
|
102
|
+
let failureMessage = failure.message->Option.getOr("unknown message")
|
|
103
|
+
Console.log(
|
|
104
|
+
`Error: SQS.${name} batch ${batchNr} entry failed: ${id}, ${failureCode}, ${failureMessage}`,
|
|
105
|
+
)
|
|
106
|
+
id
|
|
107
|
+
})
|
|
108
|
+
| exception exn =>
|
|
109
|
+
let error =
|
|
110
|
+
exn
|
|
111
|
+
->JsExn.fromException
|
|
112
|
+
->Option.flatMap(exn => exn->JsExn.message)
|
|
113
|
+
->Option.getOr("unknown error")
|
|
114
|
+
Console.log(`Error: SQS.${name} batch ${batchNr} failed: ${error}`)
|
|
115
|
+
let start = idx * maxBatchMessages
|
|
116
|
+
let end = start + maxBatchMessages
|
|
117
|
+
entries
|
|
118
|
+
->Array.slice(~start, ~end)
|
|
119
|
+
->Array.map(entry => entry.id)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
->Promise.all
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let handleBatchResult = failedIds =>
|
|
126
|
+
switch failedIds->Array.flat {
|
|
127
|
+
| [] => Ok()
|
|
128
|
+
| failedIds => Error(failedIds)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let sendMessagesParallel = async (
|
|
132
|
+
~queueId,
|
|
133
|
+
entries: array<SQS.SendMessageBatchCommand.sendMessageBatchEntry>,
|
|
134
|
+
) => {
|
|
135
|
+
let totalMessageCount = entries->Array.length
|
|
136
|
+
let batchNr = ref(0)
|
|
137
|
+
let start = ref(0)
|
|
138
|
+
let batchPromises = []
|
|
139
|
+
|
|
140
|
+
let sliceBatch = start => {
|
|
141
|
+
let end = ref(start)
|
|
142
|
+
let batchBytes = ref(0)
|
|
143
|
+
let messageBytes = () => (entries->Array.getUnsafe(end.contents)).messageBody->String.length
|
|
144
|
+
while (
|
|
145
|
+
end.contents < totalMessageCount &&
|
|
146
|
+
end.contents < start + maxBatchMessages &&
|
|
147
|
+
batchBytes.contents + messageBytes() <= maxBatchBytes
|
|
148
|
+
) {
|
|
149
|
+
batchBytes := batchBytes.contents + messageBytes()
|
|
150
|
+
end := end.contents + 1
|
|
151
|
+
}
|
|
152
|
+
if end.contents == start {
|
|
153
|
+
Console.log("SQS.sendMessagesParallel: no message sent !!")
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
(end.contents, entries->Array.slice(~start, ~end=end.contents))
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
while start.contents < totalMessageCount {
|
|
160
|
+
let (nextStart, batchEntries) = sliceBatch(start.contents)
|
|
161
|
+
batchNr := batchNr.contents + 1
|
|
162
|
+
start := nextStart
|
|
163
|
+
|
|
164
|
+
let messages = batchEntries->Array.map(({messageBody}) => messageBody)
|
|
165
|
+
let messageCountStr = messages->Array.length->Int.toString
|
|
166
|
+
let messageBytes = messages->Array.map(message => message->String.length)
|
|
167
|
+
let batchBytes = messageBytes->Array.reduce(0, (acc, a) => acc + a)
|
|
168
|
+
let messageBytesStr = messageBytes->Array.map(size => size->Int.toString)->Array.joinUnsafe(",")
|
|
169
|
+
Console.log(
|
|
170
|
+
`SQS.sendMessagesParallel: batchNr:${batchNr.contents->Int.toString} messageCount:${messageCountStr} batchBytes: ${batchBytes->Int.toString}, messageBytes: ${messageBytesStr}`,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
let _ = batchPromises->Array.push(
|
|
174
|
+
SQS.SendMessageBatchCommand.make({
|
|
175
|
+
queueUrl: queueId,
|
|
176
|
+
entries: batchEntries,
|
|
177
|
+
})->SQS.SendMessageBatchCommand.send,
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
(await batchPromises->handleSendBatchPromises(entries, "sendMessagesParallel"))->handleBatchResult
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//FIXME: 1:1 like handleSendBatchPromises, only difference is in types of parameters
|
|
185
|
+
let handleDeleteBatchPromises: (
|
|
186
|
+
array<promise<SQS.DeleteMessageBatchCommand.output>>,
|
|
187
|
+
array<SQS.DeleteMessageBatchCommand.deleteMessageBatchEntry>,
|
|
188
|
+
string,
|
|
189
|
+
) => promise<array<array<string>>> = (promises, entries, name) => {
|
|
190
|
+
promises
|
|
191
|
+
->Array.mapWithIndex(async (promise, idx) => {
|
|
192
|
+
let batchNr = (idx + 1)->Int.toString
|
|
193
|
+
switch await promise {
|
|
194
|
+
| output =>
|
|
195
|
+
output.failed
|
|
196
|
+
->Option.getOr([])
|
|
197
|
+
->Array.map(failure => {
|
|
198
|
+
let id = failure.id
|
|
199
|
+
let failureCode = failure.code
|
|
200
|
+
let failureMessage = failure.message->Option.getOr("unknown message")
|
|
201
|
+
Console.log(
|
|
202
|
+
`Error: SQS.${name} batch ${batchNr} entry failed: ${id}, ${failureCode}, ${failureMessage}`,
|
|
203
|
+
)
|
|
204
|
+
id
|
|
205
|
+
})
|
|
206
|
+
| exception exn =>
|
|
207
|
+
let error =
|
|
208
|
+
exn
|
|
209
|
+
->JsExn.fromException
|
|
210
|
+
->Option.flatMap(exn => exn->JsExn.message)
|
|
211
|
+
->Option.getOr("unknown error")
|
|
212
|
+
Console.log(`Error: SQS.${name} batch ${batchNr} failed: ${error}`)
|
|
213
|
+
let start = idx * maxBatchMessages
|
|
214
|
+
let end = start + maxBatchMessages
|
|
215
|
+
entries
|
|
216
|
+
->Array.slice(~start, ~end)
|
|
217
|
+
->Array.map(entry => entry.id)
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
->Promise.all
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
let deleteMessagesParallel = async (
|
|
224
|
+
~queueId,
|
|
225
|
+
entries: array<SQS.DeleteMessageBatchCommand.deleteMessageBatchEntry>,
|
|
226
|
+
) => {
|
|
227
|
+
let arraySize =
|
|
228
|
+
(entries->Array.length->Int.toFloat /. maxBatchMessages->Int.toFloat)->Math.Int.ceil
|
|
229
|
+
|
|
230
|
+
(
|
|
231
|
+
await Array.fromInitializer(~length=arraySize, batchNr => {
|
|
232
|
+
let start = batchNr * maxBatchMessages
|
|
233
|
+
let end = start + maxBatchMessages
|
|
234
|
+
SQS.DeleteMessageBatchCommand.send(
|
|
235
|
+
SQS.DeleteMessageBatchCommand.make({
|
|
236
|
+
queueUrl: queueId,
|
|
237
|
+
entries: entries->Array.slice(~start, ~end),
|
|
238
|
+
}),
|
|
239
|
+
)
|
|
240
|
+
})->handleDeleteBatchPromises(entries, "deleteMessagesParallel")
|
|
241
|
+
)->handleBatchResult
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
let getQueuePolicy = async queueArn => {
|
|
245
|
+
let response = await SQS.GetQueueAttributesCommand.send(
|
|
246
|
+
SQS.GetQueueAttributesCommand.make({
|
|
247
|
+
attributeNames: ["Policy"],
|
|
248
|
+
queueUrl: queueArn->arn2Url,
|
|
249
|
+
}),
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
response.attributes.policy->SQS.GetQueueAttributesCommand.unsafeParsePolicy
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
let setQueuePolicy = async (queueArn, policy: IAM.Policy.t) =>
|
|
256
|
+
switch policy->JSON.stringifyAny {
|
|
257
|
+
| Some(newPolicy) =>
|
|
258
|
+
let _setQueueAttributesResponse = await SQS.SetQueueAttributesCommand.send(
|
|
259
|
+
SQS.SetQueueAttributesCommand.make({
|
|
260
|
+
attributes: {
|
|
261
|
+
policy: newPolicy,
|
|
262
|
+
},
|
|
263
|
+
queueUrl: queueArn->arn2Url,
|
|
264
|
+
}),
|
|
265
|
+
)
|
|
266
|
+
| None => Console.log("Couldn't stringify policy")
|
|
267
|
+
}
|