-
Notifications
You must be signed in to change notification settings - Fork 4k
/
Copy pathintegration.ts
446 lines (394 loc) · 13.5 KB
/
integration.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
import { Construct } from 'constructs';
import { IHttpApi } from './api';
import { HttpMethod, IHttpRoute } from './route';
import { CfnIntegration } from '.././index';
import { IRole } from '../../../aws-iam';
import { Aws, Duration, Resource } from '../../../core';
import { IIntegration } from '../common';
import { ParameterMapping } from '../parameter-mapping';
/**
* Represents an Integration for an HTTP API.
*/
export interface IHttpIntegration extends IIntegration {
/** The HTTP API associated with this integration */
readonly httpApi: IHttpApi;
}
/**
* Supported integration types
*/
export enum HttpIntegrationType {
/**
* Integration type is an HTTP proxy.
*
* For integrating the route or method request with an HTTP endpoint, with the
* client request passed through as-is. This is also referred to as HTTP proxy
* integration. For HTTP API private integrations, use an HTTP_PROXY integration.
*
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-http.html
*/
HTTP_PROXY = 'HTTP_PROXY',
/**
* Integration type is an AWS proxy.
*
* For integrating the route or method request with a Lambda function or other
* AWS service action. This integration is also referred to as a Lambda proxy
* integration.
*
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services.html
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
*/
AWS_PROXY = 'AWS_PROXY',
}
/**
* Supported integration subtypes
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services-reference.html
*/
export enum HttpIntegrationSubtype {
/**
* EventBridge PutEvents integration
*/
EVENTBRIDGE_PUT_EVENTS = 'EventBridge-PutEvents',
/**
* SQS SendMessage integration
*/
SQS_SEND_MESSAGE = 'SQS-SendMessage',
/**
* SQS ReceiveMessage integration,
*/
SQS_RECEIVE_MESSAGE = 'SQS-ReceiveMessage',
/**
* SQS DeleteMessage integration,
*/
SQS_DELETE_MESSAGE = 'SQS-DeleteMessage',
/**
* SQS PurgeQueue integration
*/
SQS_PURGE_QUEUE = 'SQS-PurgeQueue',
/**
* AppConfig GetConfiguration integration
*/
APPCONFIG_GET_CONFIGURATION = 'AppConfig-GetConfiguration',
/**
* Kinesis PutRecord integration
*/
KINESIS_PUT_RECORD = 'Kinesis-PutRecord',
/**
* Step Functions StartExecution integration
*/
STEPFUNCTIONS_START_EXECUTION = 'StepFunctions-StartExecution',
/**
* Step Functions StartSyncExecution integration
*/
STEPFUNCTIONS_START_SYNC_EXECUTION = 'StepFunctions-StartSyncExecution',
/**
* Step Functions StopExecution integration
*/
STEPFUNCTIONS_STOP_EXECUTION = 'StepFunctions-StopExecution',
}
/**
* Credentials used for AWS Service integrations.
*/
export abstract class IntegrationCredentials {
/**
* Use the specified role for integration requests
*/
public static fromRole(role: IRole): IntegrationCredentials {
return { credentialsArn: role.roleArn };
}
/** Use the calling user's identity to call the integration */
public static useCallerIdentity(): IntegrationCredentials {
return { credentialsArn: `arn:${Aws.PARTITION}:iam::*:user/*` };
}
/**
* The ARN of the credentials
*/
public abstract readonly credentialsArn: string;
}
/**
* Supported connection types
*/
export enum HttpConnectionType {
/**
* For private connections between API Gateway and resources in a VPC
*/
VPC_LINK = 'VPC_LINK',
/**
* For connections through public routable internet
*/
INTERNET = 'INTERNET',
}
/**
* Payload format version for lambda proxy integration
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
*/
export class PayloadFormatVersion {
/** Version 1.0 */
public static readonly VERSION_1_0 = new PayloadFormatVersion('1.0');
/** Version 2.0 */
public static readonly VERSION_2_0 = new PayloadFormatVersion('2.0');
/**
* A custom payload version.
* Typically used if there is a version number that the CDK doesn't support yet
*/
public static custom(version: string) {
return new PayloadFormatVersion(version);
}
/** version as a string */
public readonly version: string;
private constructor(version: string) {
this.version = version;
}
}
/**
* The integration properties
*/
export interface HttpIntegrationProps {
/**
* The HTTP API to which this integration should be bound.
*/
readonly httpApi: IHttpApi;
/**
* Integration type
*/
readonly integrationType: HttpIntegrationType;
/**
* Integration subtype.
*
* Used for AWS Service integrations, specifies the target of the integration.
*
* @default - none, required if no `integrationUri` is defined.
*/
readonly integrationSubtype?: HttpIntegrationSubtype;
/**
* Integration URI.
* This will be the function ARN in the case of `HttpIntegrationType.AWS_PROXY`,
* or HTTP URL in the case of `HttpIntegrationType.HTTP_PROXY`.
*
* @default - none, required if no `integrationSubtype` is defined.
*/
readonly integrationUri?: string;
/**
* The HTTP method to use when calling the underlying HTTP proxy
* @default - none. required if the integration type is `HttpIntegrationType.HTTP_PROXY`.
*/
readonly method?: HttpMethod;
/**
* The ID of the VPC link for a private integration. Supported only for HTTP APIs.
*
* @default - undefined
*/
readonly connectionId?: string;
/**
* The type of the network connection to the integration endpoint
*
* @default HttpConnectionType.INTERNET
*/
readonly connectionType?: HttpConnectionType;
/**
* The version of the payload format
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
* @default - defaults to latest in the case of HttpIntegrationType.AWS_PROXY`, irrelevant otherwise.
*/
readonly payloadFormatVersion?: PayloadFormatVersion;
/**
* Specifies the TLS configuration for a private integration
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-integration-tlsconfig.html
* @default undefined private integration traffic will use HTTP protocol
*/
readonly secureServerName?: string;
/**
* The maximum amount of time an integration will run before it returns without a response.
* Must be between 50 milliseconds and 29 seconds.
*
* @default Duration.seconds(29)
*/
readonly timeout?: Duration;
/**
* Specifies how to transform HTTP requests before sending them to the backend
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-parameter-mapping.html
* @default undefined requests are sent to the backend unmodified
*/
readonly parameterMapping?: ParameterMapping;
/**
* The credentials with which to invoke the integration.
*
* @default - no credentials, use resource-based permissions on supported AWS services
*/
readonly credentials?: IntegrationCredentials;
}
/**
* The integration for an API route.
* @resource AWS::ApiGatewayV2::Integration
*/
export class HttpIntegration extends Resource implements IHttpIntegration {
public readonly integrationId: string;
public readonly httpApi: IHttpApi;
constructor(scope: Construct, id: string, props: HttpIntegrationProps) {
super(scope, id);
if (!props.integrationSubtype && !props.integrationUri) {
throw new Error('Either `integrationSubtype` or `integrationUri` must be specified.');
}
if (props.timeout && !props.timeout.isUnresolved() && (props.timeout.toMilliseconds() < 50 || props.timeout.toMilliseconds() > 29000)) {
throw new Error('Integration timeout must be between 50 milliseconds and 29 seconds.');
}
const integ = new CfnIntegration(this, 'Resource', {
apiId: props.httpApi.apiId,
integrationType: props.integrationType,
integrationSubtype: props.integrationSubtype,
integrationUri: props.integrationUri,
integrationMethod: props.method,
connectionId: props.connectionId,
connectionType: props.connectionType,
payloadFormatVersion: props.payloadFormatVersion?.version,
requestParameters: props.parameterMapping?.mappings,
credentialsArn: props.credentials?.credentialsArn,
timeoutInMillis: props.timeout?.toMilliseconds(),
});
if (props.secureServerName) {
integ.tlsConfig = {
serverNameToVerify: props.secureServerName,
};
}
this.integrationId = integ.ref;
this.httpApi = props.httpApi;
}
}
/**
* Options to the HttpRouteIntegration during its bind operation.
*/
export interface HttpRouteIntegrationBindOptions {
/**
* The route to which this is being bound.
*/
readonly route: IHttpRoute;
/**
* The current scope in which the bind is occurring.
* If the `HttpRouteIntegration` being bound creates additional constructs,
* this will be used as their parent scope.
*/
readonly scope: Construct;
}
/**
* The interface that various route integration classes will inherit.
*/
export abstract class HttpRouteIntegration {
private integration?: HttpIntegration;
/**
* Initialize an integration for a route on http api.
* @param id id of the underlying `HttpIntegration` construct.
*/
constructor(private readonly id: string) {}
/**
* Internal method called when binding this integration to the route.
* @internal
*/
public _bindToRoute(options: HttpRouteIntegrationBindOptions): { readonly integrationId: string } {
if (this.integration && this.integration.httpApi.node.addr !== options.route.httpApi.node.addr) {
throw new Error('A single integration cannot be associated with multiple APIs.');
}
if (!this.integration) {
const config = this.bind(options);
this.integration = new HttpIntegration(options.scope, this.id, {
httpApi: options.route.httpApi,
integrationType: config.type,
integrationSubtype: config.subtype,
integrationUri: config.uri,
method: config.method,
connectionId: config.connectionId,
connectionType: config.connectionType,
payloadFormatVersion: config.payloadFormatVersion,
secureServerName: config.secureServerName,
parameterMapping: config.parameterMapping,
credentials: config.credentials,
timeout: config.timeout,
});
}
this.completeBind(options);
return { integrationId: this.integration.integrationId };
}
/**
* Complete the binding of the integration to the route. In some cases, there is
* some additional work to do, such as adding permissions for the API to access
* the target. This work is necessary whether the integration has just been
* created for this route or it is an existing one, previously created for other
* routes. In most cases, however, concrete implementations do not need to
* override this method.
*/
protected completeBind(_options: HttpRouteIntegrationBindOptions): void {
// no-op by default
}
/**
* Bind this integration to the route.
*/
public abstract bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig;
}
/**
* Config returned back as a result of the bind.
*/
export interface HttpRouteIntegrationConfig {
/**
* Integration type.
*/
readonly type: HttpIntegrationType;
/**
* Integration subtype.
*
* @default - none, required if no `integrationUri` is defined.
*/
readonly subtype?: HttpIntegrationSubtype;
/**
* Integration URI
*
* @default - none, required if no `integrationSubtype` is defined.
*/
readonly uri?: string;
/**
* The HTTP method that must be used to invoke the underlying proxy.
* Required for `HttpIntegrationType.HTTP_PROXY`
* @default - undefined
*/
readonly method?: HttpMethod;
/**
* The ID of the VPC link for a private integration. Supported only for HTTP APIs.
*
* @default - undefined
*/
readonly connectionId?: string;
/**
* The type of the network connection to the integration endpoint
*
* @default HttpConnectionType.INTERNET
*/
readonly connectionType?: HttpConnectionType;
/**
* Payload format version in the case of lambda proxy integration
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
* @default - undefined
*/
readonly payloadFormatVersion: PayloadFormatVersion;
/**
* Specifies the server name to verified by HTTPS when calling the backend integration
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigatewayv2-integration-tlsconfig.html
* @default undefined private integration traffic will use HTTP protocol
*/
readonly secureServerName?: string;
/**
* The maximum amount of time an integration will run before it returns without a response.
* Must be between 50 milliseconds and 29 seconds.
*
* @default Duration.seconds(29)
*/
readonly timeout?: Duration;
/**
* Specifies how to transform HTTP requests before sending them to the backend
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-parameter-mapping.html
* @default undefined requests are sent to the backend unmodified
*/
readonly parameterMapping?: ParameterMapping;
/**
* The credentials with which to invoke the integration.
*
* @default - no credentials, use resource-based permissions on supported AWS services
*/
readonly credentials?: IntegrationCredentials;
}