@gradientedge/cdk-utils 5.14.0 → 6.0.0

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 (30) hide show
  1. package/dist/src/lib/construct/api-to-eventbridge-target/index.d.ts +0 -3
  2. package/dist/src/lib/construct/api-to-eventbridge-target/index.js +0 -3
  3. package/dist/src/lib/construct/api-to-eventbridge-target/main.d.ts +23 -68
  4. package/dist/src/lib/construct/api-to-eventbridge-target/main.js +120 -241
  5. package/dist/src/lib/construct/{api-to-eventbridge-target → api-to-eventbridge-target-with-sns}/api-destined-lambda.d.ts +1 -1
  6. package/dist/src/lib/construct/{api-to-eventbridge-target → api-to-eventbridge-target-with-sns}/api-destined-lambda.js +1 -1
  7. package/dist/src/lib/construct/api-to-eventbridge-target-with-sns/index.d.ts +2 -0
  8. package/dist/src/lib/construct/api-to-eventbridge-target-with-sns/index.js +18 -0
  9. package/dist/src/lib/construct/api-to-eventbridge-target-with-sns/main.d.ts +193 -0
  10. package/dist/src/lib/construct/api-to-eventbridge-target-with-sns/main.js +631 -0
  11. package/dist/src/lib/construct/index.d.ts +1 -0
  12. package/dist/src/lib/construct/index.js +1 -0
  13. package/dist/src/lib/{construct/api-to-eventbridge-target/api-destination-event.d.ts → helper/api-to-eventbridge-target-event.d.ts} +5 -3
  14. package/dist/src/lib/{construct/api-to-eventbridge-target/api-destination-event.js → helper/api-to-eventbridge-target-event.js} +6 -4
  15. package/dist/src/lib/{construct/api-to-eventbridge-target/api-destined-rest-api.d.ts → helper/api-to-eventbridge-target-rest-api.d.ts} +4 -4
  16. package/dist/src/lib/{construct/api-to-eventbridge-target/api-destined-rest-api.js → helper/api-to-eventbridge-target-rest-api.js} +5 -5
  17. package/dist/src/lib/helper/index.d.ts +2 -0
  18. package/dist/src/lib/helper/index.js +18 -0
  19. package/dist/src/lib/types/aws/index.d.ts +10 -5
  20. package/package.json +1 -1
  21. package/src/lib/construct/api-to-eventbridge-target/index.ts +0 -3
  22. package/src/lib/construct/api-to-eventbridge-target/main.ts +127 -278
  23. package/src/lib/construct/{api-to-eventbridge-target → api-to-eventbridge-target-with-sns}/api-destined-lambda.ts +1 -1
  24. package/src/lib/construct/api-to-eventbridge-target-with-sns/index.ts +2 -0
  25. package/src/lib/construct/api-to-eventbridge-target-with-sns/main.ts +703 -0
  26. package/src/lib/construct/index.ts +1 -0
  27. package/src/lib/{construct/api-to-eventbridge-target/api-destination-event.ts → helper/api-to-eventbridge-target-event.ts} +5 -3
  28. package/src/lib/{construct/api-to-eventbridge-target/api-destined-rest-api.ts → helper/api-to-eventbridge-target-rest-api.ts} +4 -4
  29. package/src/lib/helper/index.ts +2 -0
  30. package/src/lib/types/aws/index.ts +10 -5
@@ -7,7 +7,7 @@ import * as types from '../../types/aws'
7
7
  * @stability stable
8
8
  * @category cdk-utils.api-to-eventbridge-target
9
9
  * @subcategory member
10
- * @classdesc Provides a construct to contain lambda resources for ApiToEventBridgeTarget
10
+ * @classdesc Provides a construct to contain lambda resources for ApiToEventBridgeTargetWithSns
11
11
  */
12
12
  export class ApiDestinedLambda implements types.ApiDestinedLambdaType {
13
13
  destinationFailure: destinations.EventBridgeDestination
@@ -0,0 +1,2 @@
1
+ export * from './api-destined-lambda'
2
+ export * from './main'
@@ -0,0 +1,703 @@
1
+ import * as cdk from 'aws-cdk-lib'
2
+ import * as apig from 'aws-cdk-lib/aws-apigateway'
3
+ import * as events from 'aws-cdk-lib/aws-events'
4
+ import * as eventstargets from 'aws-cdk-lib/aws-events-targets'
5
+ import * as iam from 'aws-cdk-lib/aws-iam'
6
+ import * as lambda from 'aws-cdk-lib/aws-lambda'
7
+ import * as destinations from 'aws-cdk-lib/aws-lambda-destinations'
8
+ import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'
9
+ import { Construct } from 'constructs'
10
+ import { CommonConstruct } from '../../common'
11
+ import * as helper from '../../helper'
12
+ import * as types from '../../types'
13
+ import { ApiDestinedLambda } from './api-destined-lambda'
14
+
15
+ /**
16
+ * @stability stable
17
+ * @category cdk-utils.api-to-eventbridge-target
18
+ * @subcategory construct
19
+ * @classdesc Provides a construct to create and deploy API Gateway invocations to EventBridge
20
+ *
21
+ * <b>Architecture</b> ![Architecture](./ApiToEventBridgeTargetWithSns.jpg)
22
+ *
23
+ * @example
24
+ * import { ApiToEventBridgeTargetWithSns, ApiToEventBridgeTargetProps } '@gradientedge/cdk-utils'
25
+ * import { Construct } from 'constructs'
26
+ *
27
+ * class CustomConstruct extends ApiToEventBridgeTargetWithSns {
28
+ * constructor(parent: Construct, id: string, props: ApiToEventBridgeTargetProps) {
29
+ * super(parent, id, props)
30
+ * this.props = props
31
+ * this.id = id
32
+ * this.initResources()
33
+ * }
34
+ * }
35
+ *
36
+ */
37
+ export class ApiToEventBridgeTargetWithSns extends CommonConstruct {
38
+ props: types.ApiToEventBridgeTargetProps
39
+ id: string
40
+
41
+ /* application related resources */
42
+ applicationSecrets: secretsmanager.ISecret[]
43
+
44
+ /* destined lambda related resources */
45
+ apiDestinedLambda: types.ApiDestinedLambdaType
46
+
47
+ /* event related resources */
48
+ apiEvent: types.ApiToEventBridgeTargetEventType
49
+
50
+ /* rest restApi related resources */
51
+ apiDestinedRestApi: types.ApiToEventBridgeTargetRestApiType
52
+ apiResource: string
53
+
54
+ constructor(parent: Construct, id: string, props: types.ApiToEventBridgeTargetProps) {
55
+ super(parent, id, props)
56
+
57
+ this.props = props
58
+ this.id = id
59
+
60
+ this.apiDestinedLambda = new ApiDestinedLambda()
61
+ this.apiEvent = new helper.ApiToEventbridgeTargetEvent()
62
+ this.apiDestinedRestApi = new helper.ApiToEventbridgeTargetRestApi()
63
+ this.apiResource = 'notify'
64
+ }
65
+
66
+ protected initResources() {
67
+ /* application related resources */
68
+ this.resolveSecrets()
69
+
70
+ /* core resources */
71
+ this.resolveHostedZone()
72
+ this.resolveCertificate()
73
+
74
+ /* optional custom event bus */
75
+ this.createApiDestinedEventBus()
76
+
77
+ /* destined lambda related resources */
78
+ this.createApiDestinedLambdaPolicy()
79
+ this.createApiDestinedLambdaRole()
80
+ this.createApiDestinedLambdaEnvironment()
81
+ this.createApiDestinedLambdaLayers()
82
+ this.createApiDestinedLambdaDestinations()
83
+ this.createApiDestinedLambdaFunction()
84
+
85
+ /* event related resources */
86
+ this.createApiDestinationLogGroupSuccess()
87
+ this.createApiDestinationRuleSuccess()
88
+ this.createApiDestinationLogGroupFailure()
89
+ this.createApiDestinationRuleFailure()
90
+
91
+ /* restApi related resources */
92
+ this.createApiDestinedTopicRole()
93
+ this.createApiDestinedTopic()
94
+ this.createApiDestinedIntegrationRequestParameters()
95
+ this.createApiDestinedIntegrationRequestTemplates()
96
+ this.createApiDestinedIntegrationResponse()
97
+ this.createApiDestinedIntegrationErrorResponse()
98
+ this.createApiDestinedIntegration()
99
+ this.createApiDestinedRestApi()
100
+ this.createApiDestinedResource()
101
+ this.createApiDestinedResponseModel()
102
+ this.createApiDestinedErrorResponseModel()
103
+ this.createApiDestinedMethodResponse()
104
+ this.createApiDestinedMethodErrorResponse()
105
+ this.createApiDestinedResourceMethod()
106
+ this.createApiDomain()
107
+ this.createApiBasePathMapping()
108
+ this.createApiRouteAssets()
109
+ }
110
+
111
+ /**
112
+ * @summary Method to resolve secrets from SecretsManager
113
+ * - To be implemented in the overriding method in the implementation class
114
+ * @protected
115
+ */
116
+ protected resolveSecrets() {
117
+ this.applicationSecrets = []
118
+ }
119
+
120
+ /**
121
+ * @summary Method to resolve a hosted zone based on domain attributes
122
+ * @protected
123
+ */
124
+ protected resolveHostedZone() {
125
+ this.apiDestinedRestApi.hostedZone = this.route53Manager.withHostedZoneFromFullyQualifiedDomainName(
126
+ `${this.id}-hosted-zone`,
127
+ this,
128
+ this.props.useExistingHostedZone
129
+ )
130
+ }
131
+
132
+ /**
133
+ * @summary Method to resolve a certificate based on attributes
134
+ * @protected
135
+ */
136
+ protected resolveCertificate() {
137
+ if (this.props.api.useExisting) return
138
+ if (
139
+ this.props.api.certificate.useExistingCertificate &&
140
+ this.props.api.certificate.certificateSsmName &&
141
+ this.props.api.certificate.certificateRegion
142
+ ) {
143
+ this.props.api.certificate.certificateArn = this.ssmManager.readStringParameterFromRegion(
144
+ `${this.id}-certificate-param`,
145
+ this,
146
+ this.props.api.certificate.certificateSsmName,
147
+ this.props.api.certificate.certificateRegion
148
+ )
149
+ }
150
+
151
+ this.apiDestinedRestApi.certificate = this.acmManager.resolveCertificate(
152
+ `${this.id}-certificate`,
153
+ this,
154
+ this.props.api.certificate
155
+ )
156
+ }
157
+
158
+ /**
159
+ * @summary Method to create iam policy for Api Destined Lambda function
160
+ * @protected
161
+ */
162
+ protected createApiDestinedLambdaPolicy() {
163
+ if (this.props.api.useExisting) return
164
+ this.apiDestinedLambda.policy = new iam.PolicyDocument({
165
+ statements: [this.iamManager.statementForReadSecrets(this), this.iamManager.statementForPutEvents()],
166
+ })
167
+ }
168
+
169
+ /**
170
+ * @summary Method to create iam role for Api Destined Lambda function
171
+ * @protected
172
+ */
173
+ protected createApiDestinedLambdaRole() {
174
+ if (this.props.api.useExisting) return
175
+ this.apiDestinedLambda.role = this.iamManager.createRoleForLambda(
176
+ `${this.id}-lambda-destined-role`,
177
+ this,
178
+ this.apiDestinedLambda.policy
179
+ )
180
+ }
181
+
182
+ /**
183
+ * @summary Method to create environment variables for Api Destined Lambda function
184
+ * @protected
185
+ */
186
+ protected createApiDestinedLambdaEnvironment() {
187
+ if (this.props.api.useExisting) return
188
+ this.apiDestinedLambda.environment = {
189
+ NODE_ENV: this.props.nodeEnv,
190
+ LOG_LEVEL: this.props.logLevel,
191
+ TZ: this.props.timezone,
192
+ SOURCE_ID: this.id,
193
+ }
194
+ }
195
+
196
+ /**
197
+ * @summary Method to create layers for Api Destined Lambda function
198
+ * @protected
199
+ */
200
+ protected createApiDestinedLambdaLayers() {
201
+ if (this.props.api.useExisting) return
202
+ const layers: lambda.LayerVersion[] = []
203
+ if (this.props.lambda && this.props.lambda.layerSource) {
204
+ layers.push(
205
+ this.lambdaManager.createLambdaLayer(`${this.id}-lambda-destined-layer`, this, this.props.lambda.layerSource)
206
+ )
207
+ }
208
+
209
+ this.apiDestinedLambda.layers = layers
210
+ }
211
+
212
+ /**
213
+ * @summary Method to create destination for Api Destined function
214
+ * @protected
215
+ */
216
+ protected createApiDestinedLambdaDestinations() {
217
+ if (this.props.api.useExisting) return
218
+ this.apiDestinedLambda.destinationSuccess = new destinations.EventBridgeDestination(this.apiEvent.eventBus)
219
+ this.apiDestinedLambda.destinationFailure = new destinations.EventBridgeDestination(this.apiEvent.eventBus)
220
+ }
221
+
222
+ /**
223
+ * @summary Method to create lambda function for Api Destined
224
+ * @protected
225
+ */
226
+ protected createApiDestinedLambdaFunction() {
227
+ if (this.props.api.useExisting) return
228
+ if (!this.props.lambda || !this.props.lambda.source) throw 'Api Destined Lambda props undefined'
229
+
230
+ this.apiDestinedLambda.function = this.lambdaManager.createLambdaFunction(
231
+ `${this.id}-lambda-destined`,
232
+ this,
233
+ {
234
+ ...this.props.lambda.function,
235
+ ...{
236
+ onSuccess: this.apiDestinedLambda.destinationSuccess,
237
+ onFailure: this.apiDestinedLambda.destinationFailure,
238
+ },
239
+ },
240
+ this.apiDestinedLambda.role,
241
+ this.apiDestinedLambda.layers,
242
+ this.props.lambda.source,
243
+ this.props.lambda.handler ?? 'lambda.handler',
244
+ this.apiDestinedLambda.environment
245
+ )
246
+ }
247
+
248
+ /**
249
+ * @summary Method to create or use an existing eventbus for api destined payload deliveries
250
+ * @protected
251
+ */
252
+ protected createApiDestinedEventBus() {
253
+ if (this.props.api.useExisting) {
254
+ this.apiEvent.eventBus = events.EventBus.fromEventBusName(
255
+ this,
256
+ `${this.id}-destined-event-bus`,
257
+ `${this.props.event.eventBusName}-${this.props.stage}`
258
+ )
259
+ return
260
+ }
261
+ this.apiEvent.eventBus = this.eventManager.createEventBus(`${this.id}-destined-event-bus`, this, {
262
+ eventBusName: `${this.props.event.eventBusName}`,
263
+ })
264
+ }
265
+
266
+ /**
267
+ * @summary Method to create a log group for successful api destined payload deliveries
268
+ * @protected
269
+ */
270
+ protected createApiDestinationLogGroupSuccess() {
271
+ if (this.props.api.useExisting) return
272
+ this.apiEvent.logGroupSuccess = this.logManager.createLogGroup(`${this.id}-destination-success-log`, this, {
273
+ ...{
274
+ logGroupName: `/${this.id}/events/api-destination-success`,
275
+ },
276
+ ...this.props.event.logGroupSuccess,
277
+ })
278
+ }
279
+
280
+ /**
281
+ * Method to create EventBridge rule with lambda target for success
282
+ * @protected
283
+ */
284
+ protected createApiDestinationRuleSuccess() {
285
+ if (this.props.api.useExisting) return
286
+ this.props.event.ruleSuccess = {
287
+ ...{
288
+ ruleName: `${this.id}-api-destination-success`,
289
+ eventPattern: {
290
+ detail: {
291
+ requestContext: {
292
+ condition: ['Success'],
293
+ },
294
+ responsePayload: {
295
+ source: ['custom:api-destined-lambda'],
296
+ sourceId: [this.id],
297
+ },
298
+ },
299
+ },
300
+ },
301
+ ...this.props.event.ruleSuccess,
302
+ }
303
+ this.apiEvent.ruleSuccess = this.eventManager.createRule(
304
+ `${this.id}-api-destination-rule-success`,
305
+ this,
306
+ this.props.event.ruleSuccess,
307
+ this.apiEvent.eventBus,
308
+ [new eventstargets.CloudWatchLogGroup(this.apiEvent.logGroupSuccess)]
309
+ )
310
+ }
311
+
312
+ /**
313
+ * @summary Method to create a log group for failed api destined payload deliveries
314
+ * @protected
315
+ */
316
+ protected createApiDestinationLogGroupFailure() {
317
+ if (this.props.api.useExisting) return
318
+ this.apiEvent.logGroupFailure = this.logManager.createLogGroup(`${this.id}-destination-failure-log`, this, {
319
+ ...{
320
+ logGroupName: `/${this.id}/events/api-destination-failure`,
321
+ },
322
+ ...this.props.event.logGroupFailure,
323
+ })
324
+ }
325
+
326
+ /**
327
+ * Method to create EventBridge rule with lambda target for failure
328
+ * @protected
329
+ */
330
+ protected createApiDestinationRuleFailure() {
331
+ if (this.props.api.useExisting) return
332
+ this.props.event.ruleFailure = {
333
+ ...{
334
+ ruleName: `${this.id}-api-destination-failure`,
335
+ eventPattern: {
336
+ detail: {
337
+ responsePayload: {
338
+ errorType: ['Error'],
339
+ },
340
+ },
341
+ },
342
+ },
343
+ ...this.props.event.ruleFailure,
344
+ }
345
+ this.apiEvent.ruleFailure = this.eventManager.createRule(
346
+ `${this.id}-api-destination-rule-failure`,
347
+ this,
348
+ this.props.event.ruleFailure,
349
+ this.apiEvent.eventBus,
350
+ [new eventstargets.CloudWatchLogGroup(this.apiEvent.logGroupFailure)]
351
+ )
352
+ }
353
+
354
+ /**
355
+ * @summary Method to create a role for sns topic
356
+ * @protected
357
+ */
358
+ protected createApiDestinedTopicRole() {
359
+ this.apiDestinedRestApi.role = new iam.Role(this, `${this.id}-sns-rest-api-role`, {
360
+ assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
361
+ })
362
+ }
363
+
364
+ /**
365
+ * @summary Method to create API destined SNS topic
366
+ * @protected
367
+ */
368
+ protected createApiDestinedTopic() {
369
+ if (!this.props.api.withResource) return
370
+ this.apiDestinedRestApi.topic = this.snsManager.createLambdaNotificationService(
371
+ `${this.id}-destined-topic`,
372
+ this,
373
+ {
374
+ topicName: `${this.id}-destined-topic`,
375
+ },
376
+ this.apiDestinedLambda.function
377
+ )
378
+
379
+ if (this.apiDestinedRestApi.role) {
380
+ this.apiDestinedRestApi.topic.grantPublish(this.apiDestinedRestApi.role)
381
+ }
382
+ }
383
+
384
+ /**
385
+ * @summary Method to create api integration request parameters
386
+ * @protected
387
+ */
388
+ protected createApiDestinedIntegrationRequestParameters() {
389
+ if (!this.props.api.withResource) return
390
+ this.apiDestinedRestApi.integrationRequestParameters = {
391
+ 'integration.request.header.Content-Type': "'application/x-www-form-urlencoded'",
392
+ }
393
+ }
394
+
395
+ /**
396
+ * @summary Method to create api integration request templates
397
+ * @protected
398
+ */
399
+ protected createApiDestinedIntegrationRequestTemplates() {
400
+ if (!this.props.api.withResource) return
401
+ if (!this.apiDestinedRestApi.topic) throw 'Topic undefined'
402
+ this.apiDestinedRestApi.integrationRequestTemplates = {
403
+ 'application/json': [
404
+ 'Action=Publish',
405
+ `TargetArn=$util.urlEncode('${this.apiDestinedRestApi.topic.topicArn}')`,
406
+ 'Message=$util.urlEncode($input.body)',
407
+ 'Version=2010-03-31',
408
+ ].join('&'),
409
+ }
410
+ }
411
+
412
+ /**
413
+ * @summary Method to create api integration response
414
+ * @protected
415
+ */
416
+ protected createApiDestinedIntegrationResponse() {
417
+ if (!this.props.api.withResource) return
418
+ this.apiDestinedRestApi.integrationResponse = this.props.api.integrationResponse ?? {
419
+ ...{
420
+ statusCode: '200',
421
+ responseTemplates: {
422
+ 'application/json': JSON.stringify({ message: 'Payload Submitted' }),
423
+ },
424
+ },
425
+ }
426
+ }
427
+
428
+ /**
429
+ * @summary Method to create api integration error response
430
+ * @protected
431
+ */
432
+ protected createApiDestinedIntegrationErrorResponse() {
433
+ if (!this.props.api.withResource) return
434
+ this.apiDestinedRestApi.integrationErrorResponse = {
435
+ ...{
436
+ selectionPattern: '^\\[Error\\].*',
437
+ statusCode: '400',
438
+ responseTemplates: {
439
+ 'application/json': JSON.stringify({
440
+ state: 'error',
441
+ message: "$util.escapeJavaScript($input.path('$.errorMessage'))",
442
+ }),
443
+ },
444
+ responseParameters: {
445
+ 'method.response.header.Content-Type': "'application/json'",
446
+ 'method.response.header.Access-Control-Allow-Origin': "'*'",
447
+ 'method.response.header.Access-Control-Allow-Credentials': "'true'",
448
+ },
449
+ },
450
+ ...this.props.api.integrationErrorResponse,
451
+ }
452
+ }
453
+
454
+ /**
455
+ * @summary Method to create api integration
456
+ * @protected
457
+ */
458
+ protected createApiDestinedIntegration() {
459
+ if (!this.props.api.withResource) return
460
+ this.apiDestinedRestApi.integration = new apig.Integration({
461
+ type: apig.IntegrationType.AWS,
462
+ integrationHttpMethod: 'POST',
463
+ uri: `arn:aws:apigateway:${this.props.region}:sns:path//`,
464
+ options: {
465
+ ...{
466
+ credentialsRole: this.apiDestinedRestApi.role,
467
+ requestParameters: this.apiDestinedRestApi.integrationRequestParameters,
468
+ requestTemplates: this.apiDestinedRestApi.integrationRequestTemplates,
469
+ passthroughBehavior: apig.PassthroughBehavior.NEVER,
470
+ integrationResponses: [
471
+ this.apiDestinedRestApi.integrationResponse,
472
+ this.apiDestinedRestApi.integrationErrorResponse,
473
+ ],
474
+ },
475
+ ...this.props.api.integrationOptions,
476
+ },
477
+ })
478
+ }
479
+
480
+ /**
481
+ * @summary Method to create api integration method response
482
+ * @protected
483
+ */
484
+ protected createApiDestinedMethodResponse() {
485
+ if (!this.props.api.withResource) return
486
+ this.apiDestinedRestApi.methodResponse = {
487
+ ...{
488
+ statusCode: '200',
489
+ responseParameters: {
490
+ 'method.response.header.Content-Type': true,
491
+ 'method.response.header.Access-Control-Allow-Origin': true,
492
+ 'method.response.header.Access-Control-Allow-Credentials': true,
493
+ },
494
+ responseModels: {
495
+ 'application/json': this.apiDestinedRestApi.responseModel,
496
+ },
497
+ },
498
+ ...this.props.api.methodResponse,
499
+ }
500
+ }
501
+
502
+ /**
503
+ * @summary Method to create api integration method error response
504
+ * @protected
505
+ */
506
+ protected createApiDestinedMethodErrorResponse() {
507
+ if (!this.props.api.withResource) return
508
+ this.apiDestinedRestApi.methodErrorResponse = {
509
+ ...{
510
+ statusCode: '400',
511
+ responseParameters: {
512
+ 'method.response.header.Content-Type': true,
513
+ 'method.response.header.Access-Control-Allow-Origin': true,
514
+ 'method.response.header.Access-Control-Allow-Credentials': true,
515
+ },
516
+ responseModels: {
517
+ 'application/json': this.apiDestinedRestApi.errorResponseModel,
518
+ },
519
+ },
520
+ ...this.props.api.methodErrorResponse,
521
+ }
522
+ }
523
+
524
+ /**
525
+ * @summary Method to create rest restApi for Api
526
+ * @protected
527
+ */
528
+ protected createApiDestinedRestApi() {
529
+ if (this.props.api.useExisting && this.props.api.importedRestApiRef) {
530
+ this.apiDestinedRestApi.api = apig.RestApi.fromRestApiId(
531
+ this,
532
+ `${this.id}-sns-rest-api`,
533
+ cdk.Fn.importValue(this.props.api.importedRestApiRef)
534
+ )
535
+ return
536
+ }
537
+
538
+ const accessLogGroup = this.logManager.createLogGroup(`${this.id}-sns-rest-api-access-log`, this, {
539
+ logGroupName: `/custom/api/${this.id}-destined-rest-api-access-${this.props.stage}`,
540
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
541
+ })
542
+
543
+ this.apiDestinedRestApi.api = new apig.RestApi(this, `${this.id}-sns-rest-api`, {
544
+ ...{
545
+ defaultIntegration: this.apiDestinedRestApi.integration,
546
+ defaultMethodOptions: {
547
+ methodResponses: [this.apiDestinedRestApi.methodResponse, this.apiDestinedRestApi.methodErrorResponse],
548
+ },
549
+ deployOptions: {
550
+ dataTraceEnabled: true,
551
+ description: `${this.id} - ${this.props.stage} stage`,
552
+ loggingLevel: apig.MethodLoggingLevel.INFO,
553
+ metricsEnabled: true,
554
+ stageName: this.props.stage,
555
+ accessLogDestination: new apig.LogGroupLogDestination(accessLogGroup),
556
+ accessLogFormat: apig.AccessLogFormat.jsonWithStandardFields(),
557
+ },
558
+ endpointConfiguration: {
559
+ types: [apig.EndpointType.REGIONAL],
560
+ },
561
+ defaultCorsPreflightOptions: {
562
+ allowOrigins: apig.Cors.ALL_ORIGINS,
563
+ allowMethods: ['POST'],
564
+ allowHeaders: apig.Cors.DEFAULT_HEADERS,
565
+ },
566
+ restApiName: `${this.id}-destined-rest-api-${this.props.stage}`,
567
+ },
568
+ ...this.props.api,
569
+ })
570
+ this.addCfnOutput(`${this.id}-restApiId`, this.apiDestinedRestApi.api.restApiId)
571
+ this.addCfnOutput(`${this.id}-restApiRootResourceId`, this.apiDestinedRestApi.api.root.resourceId)
572
+ }
573
+
574
+ /**
575
+ * @summary Method to create api integration response model
576
+ * @protected
577
+ */
578
+ protected createApiDestinedResponseModel() {
579
+ if (!this.props.api.withResource) return
580
+ this.apiDestinedRestApi.responseModel = new apig.Model(this, `${this.id}-response-model`, {
581
+ restApi: this.apiDestinedRestApi.api,
582
+ ...{
583
+ contentType: 'application/json',
584
+ modelName: 'ResponseModel',
585
+ schema: {
586
+ schema: apig.JsonSchemaVersion.DRAFT4,
587
+ title: 'pollResponse',
588
+ type: apig.JsonSchemaType.OBJECT,
589
+ properties: { message: { type: apig.JsonSchemaType.STRING } },
590
+ },
591
+ },
592
+ ...this.props.api.responseModel,
593
+ })
594
+ }
595
+
596
+ /**
597
+ * @summary Method to create api integration error response model
598
+ * @protected
599
+ */
600
+ protected createApiDestinedErrorResponseModel() {
601
+ if (!this.props.api.withResource) return
602
+ this.apiDestinedRestApi.errorResponseModel = new apig.Model(this, `${this.id}-error-response-model`, {
603
+ restApi: this.apiDestinedRestApi.api,
604
+ ...{
605
+ contentType: 'application/json',
606
+ modelName: 'ErrorResponseModel',
607
+ schema: {
608
+ schema: apig.JsonSchemaVersion.DRAFT4,
609
+ title: 'errorResponse',
610
+ type: apig.JsonSchemaType.OBJECT,
611
+ properties: {
612
+ state: { type: apig.JsonSchemaType.STRING },
613
+ message: { type: apig.JsonSchemaType.STRING },
614
+ },
615
+ },
616
+ },
617
+ ...this.props.api.errorResponseModel,
618
+ })
619
+ }
620
+
621
+ /**
622
+ * @summary Method to create api integration resource
623
+ * @protected
624
+ */
625
+ protected createApiDestinedResource() {
626
+ if (!this.props.api.withResource) return
627
+
628
+ let rootResource
629
+ if (this.props.api.withResource && this.props.api.importedRestApiRootResourceRef) {
630
+ rootResource = apig.Resource.fromResourceAttributes(this, `${this.id}-root-resource`, {
631
+ resourceId: cdk.Fn.importValue(this.props.api.importedRestApiRootResourceRef),
632
+ restApi: this.apiDestinedRestApi.api,
633
+ path: '/',
634
+ })
635
+ } else {
636
+ rootResource = this.apiDestinedRestApi.api.root
637
+ }
638
+
639
+ this.apiDestinedRestApi.resource = rootResource.addResource(this.props.api.resource ?? this.apiResource)
640
+ }
641
+
642
+ /**
643
+ * @summary Method to create api integration resource method
644
+ * @protected
645
+ */
646
+ protected createApiDestinedResourceMethod() {
647
+ if (!this.props.api.withResource) return
648
+ this.apiDestinedRestApi.method = this.apiDestinedRestApi.resource.addMethod(
649
+ 'POST',
650
+ this.apiDestinedRestApi.integration,
651
+ {
652
+ authorizer: this.apiDestinedRestApi.authoriser,
653
+ methodResponses: [this.apiDestinedRestApi.methodResponse, this.apiDestinedRestApi.methodErrorResponse],
654
+ }
655
+ )
656
+ }
657
+
658
+ /**
659
+ * @summary Method to create custom restApi domain for Api API
660
+ * @protected
661
+ */
662
+ protected createApiDomain() {
663
+ if (this.props.api.useExisting) return
664
+ this.apiDestinedRestApi.domain = this.apiManager.createApiDomain(
665
+ `${this.id}-api-domain`,
666
+ this,
667
+ this.isProductionStage() || this.props.skipStageForARecords
668
+ ? `${this.props.apiSubDomain}.${this.fullyQualifiedDomainName}`
669
+ : `${this.props.apiSubDomain}-${this.props.stage}.${this.fullyQualifiedDomainName}`,
670
+ this.apiDestinedRestApi.certificate
671
+ )
672
+ }
673
+
674
+ /**
675
+ * @summary Method to create base path mappings for Api API
676
+ * @protected
677
+ */
678
+ protected createApiBasePathMapping() {
679
+ if (this.props.api.useExisting) return
680
+ new apig.BasePathMapping(this, `${this.id}-base-bath-mapping`, {
681
+ basePath: '',
682
+ domainName: this.apiDestinedRestApi.domain,
683
+ restApi: this.apiDestinedRestApi.api,
684
+ stage: this.apiDestinedRestApi.api.deploymentStage,
685
+ })
686
+ }
687
+
688
+ /**
689
+ * @summary Method to create route53 records for Api API
690
+ * @protected
691
+ */
692
+ protected createApiRouteAssets() {
693
+ if (this.props.api.useExisting) return
694
+ this.route53Manager.createApiGatewayARecord(
695
+ `${this.id}-custom-domain-a-record`,
696
+ this,
697
+ this.props.apiSubDomain,
698
+ this.apiDestinedRestApi.domain,
699
+ this.apiDestinedRestApi.hostedZone,
700
+ this.props.skipStageForARecords
701
+ )
702
+ }
703
+ }