Skip to content

Commit a3f49d9

Browse files
authored
Merge branch 'main' into support_putevents_in_apigatewayv2_eventbridge_integrations
2 parents 958d03e + 15d92d1 commit a3f49d9

File tree

71 files changed

+35618
-427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+35618
-427
lines changed

allowed-breaking-changes.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4023,6 +4023,10 @@ removed:aws-cdk-lib.aws_ecs.AsgCapacityProviderProps.canContainersAccessInstance
40234023
# Exposed struct with a ref interface
40244024
weakened:aws-cdk-lib.aws_batch.OrderedComputeEnvironment
40254025

4026+
# Weakened guarantees of a data structure that's intended for internal construct usage
4027+
weakened:aws-cdk-lib.aws_ec2.FlowLogDestinationConfig
4028+
weakened:aws-cdk-lib.aws_ecs.ExecuteCommandLogConfiguration
4029+
40264030
# Revert of PR #36378 which introduced reference interfaces that caused runtime errors
40274031
# https://github.com/aws/aws-cdk/issues/36621
40284032
removed:aws-cdk-lib.aws_apigatewayv2.HttpApiHelper

packages/@aws-cdk/aws-iot-actions-alpha/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,26 @@ topicRule.addAction(
371371
);
372372
```
373373

374+
You can enable batching to reduce costs and improve efficiency:
375+
376+
```ts
377+
import { Size } from 'aws-cdk-lib';
378+
379+
declare const topicRule: iot.TopicRule;
380+
381+
topicRule.addAction(
382+
new actions.HttpsAction('https://example.com/endpoint', {
383+
batchConfig: {
384+
maxBatchOpenDuration: Duration.millis(100),
385+
maxBatchSize: 5,
386+
maxBatchSizeBytes: Size.kibibytes(1),
387+
},
388+
}),
389+
);
390+
```
391+
392+
For more information about the batching configuration, see the [AWS IoT Core documentation](https://docs.aws.amazon.com/iot/latest/developerguide/http_batching.html).
393+
374394
## Write Data to Open Search Service
375395

376396
The code snippet below creates an AWS IoT Rule that writes data

packages/@aws-cdk/aws-iot-actions-alpha/lib/https-action.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as iot from '@aws-cdk/aws-iot-alpha';
2+
import { Duration, Size, UnscopedValidationError } from 'aws-cdk-lib';
23
import * as iam from 'aws-cdk-lib/aws-iam';
34
import { CommonActionProps } from './common-action-props';
45
import { singletonActionRole } from './private/role';
@@ -25,6 +26,40 @@ export interface HttpActionHeader {
2526
readonly value: string;
2627
}
2728

29+
/**
30+
* Configuration for batching HTTP action messages.
31+
*
32+
* @see https://docs.aws.amazon.com/iot/latest/developerguide/http_batching.html
33+
*/
34+
export interface HttpActionBatchConfig {
35+
/**
36+
* The maximum amount of time an outgoing message waits for other messages to create the batch.
37+
*
38+
* Must be between 5 ms and 200 ms.
39+
*
40+
* @default Duration.millis(20)
41+
*/
42+
readonly maxBatchOpenDuration?: Duration;
43+
44+
/**
45+
* The maximum number of messages that are batched together in a single IoT rule action execution.
46+
*
47+
* Must be between 2 and 10.
48+
*
49+
* @default 10
50+
*/
51+
readonly maxBatchSize?: number;
52+
53+
/**
54+
* Maximum size of a message batch.
55+
*
56+
* Must be between 100 bytes and 128 KiB.
57+
*
58+
* @default Size.kibibytes(5)
59+
*/
60+
readonly maxBatchSizeBytes?: Size;
61+
}
62+
2863
/**
2964
* Configuration properties of an HTTPS action.
3065
*
@@ -45,6 +80,16 @@ export interface HttpsActionProps extends CommonActionProps {
4580
* Use Sigv4 authorization.
4681
*/
4782
readonly auth?: HttpActionSigV4Auth;
83+
84+
/**
85+
* Configuration for batching HTTP action messages.
86+
*
87+
* When provided, batching is automatically enabled.
88+
*
89+
* @see https://docs.aws.amazon.com/iot/latest/developerguide/http_batching.html
90+
* @default - Batching is disabled
91+
*/
92+
readonly batchConfig?: HttpActionBatchConfig;
4893
}
4994

5095
/**
@@ -56,17 +101,47 @@ export class HttpsAction implements iot.IAction {
56101
private readonly confirmationUrl?: string;
57102
private readonly headers?: Array<HttpActionHeader>;
58103
private readonly auth?: HttpActionSigV4Auth;
104+
private readonly batchConfig?: HttpActionBatchConfig;
59105

60106
/**
61107
* @param url The url to which to send post request.
62108
* @param props Optional properties to not use default.
63109
*/
64-
constructor( url: string, props: HttpsActionProps={}) {
110+
constructor(url: string, props: HttpsActionProps = {}) {
65111
this.url = url;
66112
this.confirmationUrl = props.confirmationUrl;
67113
this.headers = props.headers;
68114
this.role = props.role;
69115
this.auth = props.auth;
116+
this.batchConfig = props.batchConfig;
117+
118+
this.validateBatchConfig();
119+
}
120+
121+
private validateBatchConfig(): void {
122+
if (!this.batchConfig) {
123+
return;
124+
}
125+
126+
if (this.batchConfig.maxBatchOpenDuration) {
127+
const ms = this.batchConfig.maxBatchOpenDuration.toMilliseconds();
128+
if (ms < Duration.millis(5).toMilliseconds() || ms > Duration.millis(200).toMilliseconds()) {
129+
throw new UnscopedValidationError(`maxBatchOpenDuration must be between 5 ms and 200 ms, got ${ms} ms`);
130+
}
131+
}
132+
133+
if (this.batchConfig.maxBatchSize) {
134+
if (this.batchConfig.maxBatchSize < 2 || this.batchConfig.maxBatchSize > 10) {
135+
throw new UnscopedValidationError(`maxBatchSize must be between 2 and 10, got ${this.batchConfig.maxBatchSize}`);
136+
}
137+
}
138+
139+
if (this.batchConfig.maxBatchSizeBytes) {
140+
const bytes = this.batchConfig.maxBatchSizeBytes.toBytes();
141+
if (bytes < Size.bytes(100).toBytes() || bytes > Size.kibibytes(128).toBytes()) {
142+
throw new UnscopedValidationError(`maxBatchSizeBytes must be between 100 bytes and 128 KiB, got ${bytes} bytes`);
143+
}
144+
}
70145
}
71146

72147
/**
@@ -82,13 +157,21 @@ export class HttpsAction implements iot.IAction {
82157
},
83158
} : this.auth;
84159

160+
const batchConfig = this.batchConfig ? {
161+
maxBatchOpenMs: this.batchConfig.maxBatchOpenDuration?.toMilliseconds(),
162+
maxBatchSize: this.batchConfig.maxBatchSize,
163+
maxBatchSizeBytes: this.batchConfig.maxBatchSizeBytes?.toBytes(),
164+
} : undefined;
165+
85166
return {
86167
configuration: {
87168
http: {
88169
url: this.url,
89170
confirmationUrl: this.confirmationUrl,
90171
headers: this.headers,
91172
auth: sigV4,
173+
enableBatching: this.batchConfig ? true : false,
174+
batchConfig,
92175
},
93176
},
94177
};

packages/@aws-cdk/aws-iot-actions-alpha/test/https/https-action.test.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as iot from '@aws-cdk/aws-iot-alpha';
22
import * as cdk from 'aws-cdk-lib';
3+
import { Duration, Size } from 'aws-cdk-lib';
34
import { Template, Match } from 'aws-cdk-lib/assertions';
45
import * as actions from '../../lib';
56

@@ -159,3 +160,116 @@ test('can set http auth', () => {
159160
},
160161
});
161162
});
163+
164+
describe('batchConfig', () => {
165+
test('can set batch config', () => {
166+
// GIVEN
167+
const stack = new cdk.Stack();
168+
const topicRule = new iot.TopicRule(stack, 'TopicRule', {
169+
sql: iot.IotSql.fromStringAsVer20160323(
170+
"SELECT topic(2) as device_id FROM 'device/+/data'",
171+
),
172+
});
173+
const expectedUrl = 'https://example.com';
174+
175+
// WHEN
176+
topicRule.addAction(
177+
new actions.HttpsAction(expectedUrl, {
178+
batchConfig: {
179+
maxBatchOpenDuration: Duration.millis(100),
180+
maxBatchSize: 5,
181+
maxBatchSizeBytes: Size.kibibytes(1),
182+
},
183+
}),
184+
);
185+
186+
// THEN
187+
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
188+
TopicRulePayload: {
189+
Actions: [
190+
{
191+
Http: {
192+
Url: expectedUrl,
193+
EnableBatching: true,
194+
BatchConfig: {
195+
MaxBatchOpenMs: 100,
196+
MaxBatchSize: 5,
197+
MaxBatchSizeBytes: 1024,
198+
},
199+
},
200+
},
201+
],
202+
},
203+
});
204+
});
205+
206+
test('sets enableBatching to false when batchConfig is not provided', () => {
207+
// GIVEN
208+
const stack = new cdk.Stack();
209+
const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
210+
sql: iot.IotSql.fromStringAsVer20160323(
211+
"SELECT topic(2) as device_id FROM 'device/+/data'",
212+
),
213+
});
214+
const expectedUrl = 'https://example.com';
215+
216+
// WHEN
217+
topicRule.addAction(new actions.HttpsAction(expectedUrl));
218+
219+
// THEN
220+
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
221+
TopicRulePayload: {
222+
Actions: [
223+
{
224+
Http: {
225+
Url: expectedUrl,
226+
EnableBatching: false,
227+
},
228+
},
229+
],
230+
},
231+
});
232+
});
233+
234+
test.each([1, 11])('throws if maxBatchSize is %i', (maxBatchSize) => {
235+
// GIVEN
236+
const expectedUrl = 'https://example.com';
237+
238+
// THEN
239+
expect(() => {
240+
new actions.HttpsAction(expectedUrl, {
241+
batchConfig: {
242+
maxBatchSize,
243+
},
244+
});
245+
}).toThrow(`maxBatchSize must be between 2 and 10, got ${maxBatchSize}`);
246+
});
247+
248+
test.each([Size.bytes(99), Size.kibibytes(129)])('throws if maxBatchSizeBytes is %s', (maxBatchSizeBytes) => {
249+
// GIVEN
250+
const expectedUrl = 'https://example.com';
251+
252+
// THEN
253+
expect(() => {
254+
new actions.HttpsAction(expectedUrl, {
255+
batchConfig: {
256+
maxBatchSizeBytes,
257+
},
258+
});
259+
}).toThrow(`maxBatchSizeBytes must be between 100 bytes and 128 KiB, got ${maxBatchSizeBytes.toBytes()} bytes`);
260+
});
261+
262+
test.each([Duration.millis(4), Duration.millis(201)])('throws if maxBatchOpenDuration is %s', (maxBatchOpenDuration) => {
263+
// GIVEN
264+
const expectedUrl = 'https://example.com';
265+
266+
// THEN
267+
expect(() => {
268+
new actions.HttpsAction(expectedUrl, {
269+
batchConfig: {
270+
maxBatchOpenDuration,
271+
},
272+
});
273+
}).toThrow(`maxBatchOpenDuration must be between 5 ms and 200 ms, got ${maxBatchOpenDuration.toMilliseconds()} ms`);
274+
});
275+
});

packages/@aws-cdk/aws-iot-actions-alpha/test/https/integ.https-action.js.snapshot/IoTHttpsActionDefaultTestDeployAssert019947CA.assets.json

Lines changed: 18 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)