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