@digitraffic/common 2023.1.18-2 → 2023.1.23-2
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/aws/infra/api/integration.d.ts +2 -1
- package/dist/aws/infra/api/integration.js +3 -2
- package/dist/aws/infra/api/response.d.ts +2 -1
- package/dist/aws/infra/api/response.js +13 -7
- package/dist/aws/infra/canaries/canary-alarm.js +11 -13
- package/dist/aws/infra/canaries/canary.js +2 -4
- package/dist/aws/infra/canaries/database-checker.js +4 -1
- package/dist/aws/infra/canaries/url-canary.js +1 -0
- package/dist/aws/infra/canaries/url-checker.d.ts +2 -2
- package/dist/aws/infra/canaries/url-checker.js +24 -5
- package/dist/aws/infra/sqs-integration.d.ts +1 -3
- package/dist/aws/infra/sqs-integration.js +28 -32
- package/dist/aws/infra/sqs-queue.d.ts +0 -2
- package/dist/aws/infra/sqs-queue.js +31 -24
- package/dist/aws/infra/stack/lambda-configs.d.ts +2 -31
- package/dist/aws/infra/stack/lambda-configs.js +5 -38
- package/dist/aws/infra/stack/monitoredfunction.js +3 -1
- package/dist/aws/infra/stacks/db-stack.js +1 -1
- package/dist/aws/infra/stacks/network-stack.d.ts +2 -1
- package/dist/aws/infra/stacks/network-stack.js +4 -2
- package/dist/aws/runtime/digitraffic-integration-response.d.ts +2 -2
- package/dist/aws/runtime/digitraffic-integration-response.js +6 -4
- package/dist/aws/runtime/secrets/dbsecret.d.ts +0 -39
- package/dist/aws/runtime/secrets/dbsecret.js +1 -71
- package/dist/aws/runtime/secrets/proxy-holder.js +5 -4
- package/dist/aws/runtime/secrets/rds-holder.js +5 -4
- package/dist/aws/runtime/secrets/secret-holder.d.ts +0 -4
- package/dist/aws/runtime/secrets/secret-holder.js +6 -12
- package/dist/aws/runtime/secrets/secret.d.ts +0 -6
- package/dist/aws/runtime/secrets/secret.js +8 -17
- package/dist/database/database.d.ts +7 -0
- package/dist/database/database.js +19 -8
- package/dist/test/db-testutils.js +4 -5
- package/package.json +1 -1
- package/src/aws/infra/api/integration.ts +8 -3
- package/src/aws/infra/api/response.ts +16 -16
- package/src/aws/infra/canaries/canary-alarm.ts +26 -24
- package/src/aws/infra/canaries/canary.ts +2 -4
- package/src/aws/infra/canaries/database-checker.ts +4 -1
- package/src/aws/infra/canaries/url-canary.ts +2 -1
- package/src/aws/infra/canaries/url-checker.ts +28 -11
- package/src/aws/infra/sqs-integration.ts +51 -47
- package/src/aws/infra/sqs-queue.ts +85 -53
- package/src/aws/infra/stack/lambda-configs.ts +6 -69
- package/src/aws/infra/stack/monitoredfunction.ts +2 -1
- package/src/aws/infra/stacks/db-stack.ts +1 -1
- package/src/aws/infra/stacks/network-stack.ts +7 -3
- package/src/aws/runtime/digitraffic-integration-response.ts +16 -9
- package/src/aws/runtime/secrets/dbsecret.ts +1 -117
- package/src/aws/runtime/secrets/proxy-holder.ts +2 -5
- package/src/aws/runtime/secrets/rds-holder.ts +2 -1
- package/src/aws/runtime/secrets/secret-holder.ts +8 -20
- package/src/aws/runtime/secrets/secret.ts +17 -22
- package/src/database/database.ts +14 -3
- package/src/test/db-testutils.ts +5 -2
- package/dist/test/secret.d.ts +0 -3
- package/dist/test/secret.js +0 -25
- package/src/test/secret.ts +0 -23
@@ -1,12 +1,6 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
|
4
|
-
JsonSchemaVersion,
|
5
|
-
JsonSchema,
|
6
|
-
MethodResponse,
|
7
|
-
Model,
|
8
|
-
} from "aws-cdk-lib/aws-apigateway";
|
9
|
-
import { IModel } from "aws-cdk-lib/aws-apigateway/lib/model";
|
1
|
+
import {MediaType} from "../../types/mediatypes";
|
2
|
+
import {JsonSchema, JsonSchemaType, JsonSchemaVersion, MethodResponse, Model,} from "aws-cdk-lib/aws-apigateway";
|
3
|
+
import {IModel} from "aws-cdk-lib/aws-apigateway/lib/model";
|
10
4
|
|
11
5
|
/**
|
12
6
|
* This is velocity-script, that assumes the response to be LambdaResponse(status and body).
|
@@ -31,6 +25,12 @@ $util.base64Decode($inputRoot.body)
|
|
31
25
|
#end
|
32
26
|
`;
|
33
27
|
|
28
|
+
export const getDeprecatedDefaultLambdaResponse = (sunset: string) => {
|
29
|
+
const setDeprecationHeaders = `#set ($context.responseOverride.header.Deprecation = 'true')
|
30
|
+
#set ($context.responseOverride.header.Sunset = '${sunset}')`;
|
31
|
+
return RESPONSE_DEFAULT_LAMBDA.concat(setDeprecationHeaders);
|
32
|
+
};
|
33
|
+
|
34
34
|
const BODY_FROM_INPUT_PATH = "$input.path('$').body";
|
35
35
|
|
36
36
|
/// @deprecated
|
@@ -100,19 +100,19 @@ export class DigitrafficMethodResponse {
|
|
100
100
|
statusCode: string,
|
101
101
|
model: IModel,
|
102
102
|
mediaType: MediaType,
|
103
|
-
disableCors = false
|
103
|
+
disableCors = false,
|
104
|
+
deprecation = false
|
104
105
|
): MethodResponse {
|
105
106
|
return {
|
106
107
|
statusCode,
|
107
108
|
responseModels: {
|
108
109
|
[mediaType]: model,
|
109
110
|
},
|
110
|
-
responseParameters:
|
111
|
-
|
112
|
-
:
|
113
|
-
|
114
|
-
|
115
|
-
},
|
111
|
+
responseParameters: {
|
112
|
+
"method.response.header.Access-Control-Allow-Origin": !disableCors,
|
113
|
+
"method.response.header.Deprecation": deprecation,
|
114
|
+
"method.response.header.Sunset": deprecation,
|
115
|
+
},
|
116
116
|
};
|
117
117
|
}
|
118
118
|
|
@@ -1,31 +1,33 @@
|
|
1
|
-
import {Construct} from "constructs";
|
2
|
-
import {CanaryParameters} from "./canary-parameters";
|
3
|
-
import {Alarm, ComparisonOperator} from "aws-cdk-lib/aws-cloudwatch";
|
4
|
-
import {Canary} from "@aws-cdk/aws-synthetics-alpha";
|
5
|
-
import {SnsAction} from "aws-cdk-lib/aws-cloudwatch-actions";
|
6
|
-
import {Topic} from "aws-cdk-lib/aws-sns";
|
1
|
+
import { Construct } from "constructs";
|
2
|
+
import { CanaryParameters } from "./canary-parameters";
|
3
|
+
import { Alarm, ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch";
|
4
|
+
import { Canary } from "@aws-cdk/aws-synthetics-alpha";
|
5
|
+
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
|
6
|
+
import { Topic } from "aws-cdk-lib/aws-sns";
|
7
7
|
|
8
8
|
export class CanaryAlarm {
|
9
|
-
constructor(stack: Construct,
|
10
|
-
|
11
|
-
params: CanaryParameters) {
|
12
|
-
if (params.alarm ?? true) {
|
13
|
-
const alarmName = params.alarm?.alarmName ?? `${params.name}-alarm`;
|
9
|
+
constructor(stack: Construct, canary: Canary, params: CanaryParameters) {
|
10
|
+
const alarmName = params.alarm?.alarmName ?? `${params.name}-alarm`;
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
const alarm = new Alarm(stack, alarmName, {
|
13
|
+
alarmName,
|
14
|
+
alarmDescription: params.alarm?.description ?? "",
|
15
|
+
metric: canary.metricSuccessPercent(),
|
16
|
+
evaluationPeriods: params.alarm?.evalutionPeriods ?? 1,
|
17
|
+
threshold: params.alarm?.threshold ?? 100,
|
18
|
+
comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD,
|
19
|
+
});
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
if (params.alarm?.topicArn) {
|
22
|
+
alarm.addAlarmAction(
|
23
|
+
new SnsAction(
|
24
|
+
Topic.fromTopicArn(
|
25
|
+
stack,
|
26
|
+
`${alarmName}-action`,
|
27
|
+
params.alarm.topicArn
|
28
|
+
)
|
29
|
+
)
|
30
|
+
);
|
29
31
|
}
|
30
32
|
}
|
31
33
|
}
|
@@ -31,7 +31,7 @@ export class DigitrafficCanary extends Canary {
|
|
31
31
|
}),
|
32
32
|
environmentVariables: {
|
33
33
|
...environmentVariables,
|
34
|
-
...params
|
34
|
+
...params.canaryEnv,
|
35
35
|
},
|
36
36
|
canaryName,
|
37
37
|
schedule: params.schedule ?? Schedule.rate(Duration.minutes(15)),
|
@@ -39,8 +39,6 @@ export class DigitrafficCanary extends Canary {
|
|
39
39
|
|
40
40
|
this.artifactsBucket.grantWrite(role);
|
41
41
|
|
42
|
-
|
43
|
-
new CanaryAlarm(scope, this, params);
|
44
|
-
}
|
42
|
+
new CanaryAlarm(scope, this, params);
|
45
43
|
}
|
46
44
|
}
|
@@ -4,7 +4,7 @@ import { RdsHolder } from "../../runtime/secrets/rds-holder";
|
|
4
4
|
import { getEnvVariable } from "../../../utils/utils";
|
5
5
|
import { Countable } from "../../../database/models";
|
6
6
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
8
8
|
const synthetics = require("Synthetics");
|
9
9
|
|
10
10
|
abstract class DatabaseCheck<T> {
|
@@ -88,7 +88,9 @@ export class DatabaseCountChecker {
|
|
88
88
|
private constructor(credentialsFunction: () => Promise<void>) {
|
89
89
|
this.credentialsFunction = credentialsFunction;
|
90
90
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
91
92
|
synthetics.getConfiguration().disableRequestMetrics();
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
92
94
|
synthetics.getConfiguration().withFailedCanaryMetric(true);
|
93
95
|
}
|
94
96
|
|
@@ -146,6 +148,7 @@ export class DatabaseCountChecker {
|
|
146
148
|
check.check(value);
|
147
149
|
};
|
148
150
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
149
152
|
synthetics.executeStep(check.name, checkFunction, stepConfig);
|
150
153
|
}
|
151
154
|
});
|
@@ -48,7 +48,8 @@ export class UrlCanary extends DigitrafficCanary {
|
|
48
48
|
): UrlCanary {
|
49
49
|
return new UrlCanary(stack, role, {
|
50
50
|
...{
|
51
|
-
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
52
|
+
handler: `${params.name!}.handler`,
|
52
53
|
hostname: publicApi.hostname(),
|
53
54
|
apiKeyId: this.getApiKey(publicApi),
|
54
55
|
},
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { IncomingMessage, RequestOptions } from "http";
|
2
2
|
import { Asserter } from "../../../test/asserter";
|
3
3
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
5
5
|
const synthetics = require("Synthetics");
|
6
6
|
import zlib = require("zlib");
|
7
7
|
import { MediaType } from "../../types/mediatypes";
|
@@ -19,12 +19,12 @@ const baseHeaders = {
|
|
19
19
|
Accept: "*/*",
|
20
20
|
} as Record<string, string>;
|
21
21
|
|
22
|
-
type CheckerFunction = (Res: IncomingMessage) => void
|
22
|
+
type CheckerFunction = (Res: IncomingMessage) => Promise<void>;
|
23
23
|
type JsonCheckerFunction<T> = (
|
24
24
|
json: T,
|
25
25
|
body: string,
|
26
26
|
message: IncomingMessage
|
27
|
-
) => void
|
27
|
+
) => Promise<void>;
|
28
28
|
|
29
29
|
export class UrlChecker {
|
30
30
|
private readonly requestOptions: RequestOptions;
|
@@ -43,8 +43,10 @@ export class UrlChecker {
|
|
43
43
|
headers,
|
44
44
|
};
|
45
45
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
46
47
|
synthetics.getConfiguration().disableRequestMetrics();
|
47
48
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
48
50
|
synthetics
|
49
51
|
.getConfiguration()
|
50
52
|
.withIncludeRequestBody(false)
|
@@ -79,6 +81,7 @@ export class UrlChecker {
|
|
79
81
|
},
|
80
82
|
};
|
81
83
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
|
82
85
|
return synthetics.executeHttpStep(
|
83
86
|
`Verify ${statusCode} for ${url.replace(/auth=.*/, "")}`,
|
84
87
|
requestOptions,
|
@@ -109,6 +112,7 @@ export class UrlChecker {
|
|
109
112
|
},
|
110
113
|
};
|
111
114
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
|
112
116
|
return synthetics.executeHttpStep(
|
113
117
|
`Verify 404 for ${url}`,
|
114
118
|
requestOptions,
|
@@ -124,6 +128,7 @@ export class UrlChecker {
|
|
124
128
|
},
|
125
129
|
};
|
126
130
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
|
127
132
|
return synthetics.executeHttpStep(
|
128
133
|
`Verify 400 for ${url}`,
|
129
134
|
requestOptions,
|
@@ -133,6 +138,7 @@ export class UrlChecker {
|
|
133
138
|
|
134
139
|
expect403WithoutApiKey(url: string, mediaType?: MediaType): Promise<void> {
|
135
140
|
if (
|
141
|
+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
136
142
|
!this.requestOptions.headers ||
|
137
143
|
!this.requestOptions.headers[API_KEY_HEADER]
|
138
144
|
) {
|
@@ -147,6 +153,7 @@ export class UrlChecker {
|
|
147
153
|
},
|
148
154
|
};
|
149
155
|
|
156
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return
|
150
157
|
return synthetics.executeHttpStep(
|
151
158
|
`Verify 403 for ${url}`,
|
152
159
|
requestOptions,
|
@@ -202,12 +209,14 @@ function validateStatusCodeAndContentType(
|
|
202
209
|
return (res: IncomingMessage) => {
|
203
210
|
return new Promise((resolve) => {
|
204
211
|
if (res.statusCode !== statusCode) {
|
205
|
-
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
213
|
+
throw new Error(`${res.statusCode!} ${res.statusMessage!}`);
|
206
214
|
}
|
207
215
|
|
208
216
|
if (res.headers["content-type"] !== contentType) {
|
209
217
|
throw new Error(
|
210
|
-
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
219
|
+
`Wrong content-type ${res.headers["content-type"]!}`
|
211
220
|
);
|
212
221
|
}
|
213
222
|
|
@@ -251,7 +260,7 @@ export class ResponseChecker {
|
|
251
260
|
fn: (json: T, body: string, res: IncomingMessage) => void
|
252
261
|
): CheckerFunction {
|
253
262
|
return this.responseChecker((body: string, res: IncomingMessage) => {
|
254
|
-
fn(JSON.parse(body), body, res);
|
263
|
+
fn(JSON.parse(body) as unknown as T, body, res);
|
255
264
|
});
|
256
265
|
}
|
257
266
|
|
@@ -264,7 +273,8 @@ export class ResponseChecker {
|
|
264
273
|
}
|
265
274
|
|
266
275
|
if (res.statusCode < 200 || res.statusCode > 299) {
|
267
|
-
|
276
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
277
|
+
throw new Error(`${res.statusCode} ${res.statusMessage!}`);
|
268
278
|
}
|
269
279
|
|
270
280
|
if (this.checkCors && !res.headers["access-control-allow-origin"]) {
|
@@ -273,7 +283,8 @@ export class ResponseChecker {
|
|
273
283
|
|
274
284
|
if (res.headers["content-type"] !== this.contentType) {
|
275
285
|
throw new Error(
|
276
|
-
|
286
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
287
|
+
`Wrong content-type ${res.headers["content-type"]!}`
|
277
288
|
);
|
278
289
|
}
|
279
290
|
|
@@ -291,7 +302,7 @@ export class ContentChecker {
|
|
291
302
|
return async (res: IncomingMessage): Promise<void> => {
|
292
303
|
const body = await getResponseBody(res);
|
293
304
|
|
294
|
-
fn(JSON.parse(body), body, res);
|
305
|
+
fn(JSON.parse(body) as unknown as T, body, res);
|
295
306
|
};
|
296
307
|
}
|
297
308
|
|
@@ -314,7 +325,8 @@ export class ContentTypeChecker {
|
|
314
325
|
}
|
315
326
|
|
316
327
|
if (res.statusCode < 200 || res.statusCode > 299) {
|
317
|
-
|
328
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
329
|
+
throw new Error(`${res.statusCode} ${res.statusMessage!}`);
|
318
330
|
}
|
319
331
|
|
320
332
|
if (!res.headers["access-control-allow-origin"]) {
|
@@ -323,7 +335,8 @@ export class ContentTypeChecker {
|
|
323
335
|
|
324
336
|
if (res.headers["content-type"] !== contentType) {
|
325
337
|
throw new Error(
|
326
|
-
|
338
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
339
|
+
`Wrong content-type ${res.headers["content-type"]!}`
|
327
340
|
);
|
328
341
|
}
|
329
342
|
};
|
@@ -353,6 +366,8 @@ export class HeaderChecker {
|
|
353
366
|
if (!res.headers[headerName]) {
|
354
367
|
throw new Error("Missing header: " + headerName);
|
355
368
|
}
|
369
|
+
|
370
|
+
return Promise.resolve();
|
356
371
|
};
|
357
372
|
}
|
358
373
|
|
@@ -361,6 +376,8 @@ export class HeaderChecker {
|
|
361
376
|
if (res.headers[headerName]) {
|
362
377
|
throw new Error("Header should not exist: " + headerName);
|
363
378
|
}
|
379
|
+
|
380
|
+
return Promise.resolve();
|
364
381
|
};
|
365
382
|
}
|
366
383
|
}
|
@@ -1,9 +1,14 @@
|
|
1
|
-
import {Aws} from "aws-cdk-lib";
|
2
|
-
import {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
import { Aws } from "aws-cdk-lib";
|
2
|
+
import {
|
3
|
+
AwsIntegration,
|
4
|
+
PassthroughBehavior,
|
5
|
+
RequestValidator,
|
6
|
+
Resource,
|
7
|
+
} from "aws-cdk-lib/aws-apigateway";
|
8
|
+
import { Queue } from "aws-cdk-lib/aws-sqs";
|
9
|
+
import { PolicyStatement, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
|
10
|
+
import { IModel } from "aws-cdk-lib/aws-apigateway/lib/model";
|
11
|
+
import { Construct } from "constructs";
|
7
12
|
|
8
13
|
export function attachQueueToApiGatewayResource(
|
9
14
|
stack: Construct,
|
@@ -12,89 +17,88 @@ export function attachQueueToApiGatewayResource(
|
|
12
17
|
requestValidator: RequestValidator,
|
13
18
|
resourceName: string,
|
14
19
|
apiKeyRequired: boolean,
|
15
|
-
requestModels?:
|
20
|
+
requestModels?: Record<string, IModel>
|
16
21
|
) {
|
17
22
|
// role for API Gateway
|
18
23
|
const apiGwRole = new Role(stack, `${resourceName}APIGatewayToSQSRole`, {
|
19
|
-
assumedBy: new ServicePrincipal(
|
24
|
+
assumedBy: new ServicePrincipal("apigateway.amazonaws.com"),
|
20
25
|
});
|
21
26
|
// grants API Gateway the right to send SQS messages
|
22
|
-
apiGwRole.addToPolicy(
|
23
|
-
|
24
|
-
queue.queueArn,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
],
|
29
|
-
}));
|
27
|
+
apiGwRole.addToPolicy(
|
28
|
+
new PolicyStatement({
|
29
|
+
resources: [queue.queueArn],
|
30
|
+
actions: ["sqs:SendMessage"],
|
31
|
+
})
|
32
|
+
);
|
30
33
|
// grants API Gateway the right write CloudWatch Logs
|
31
|
-
apiGwRole.addToPolicy(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
34
|
+
apiGwRole.addToPolicy(
|
35
|
+
new PolicyStatement({
|
36
|
+
resources: ["*"],
|
37
|
+
actions: [
|
38
|
+
"logs:CreateLogGroup",
|
39
|
+
"logs:CreateLogStream",
|
40
|
+
"logs:DescribeLogGroups",
|
41
|
+
"logs:DescribeLogStreams",
|
42
|
+
"logs:PutLogEvents",
|
43
|
+
"logs:GetLogEvents",
|
44
|
+
"logs:FilterLogEvents",
|
45
|
+
],
|
46
|
+
})
|
47
|
+
);
|
45
48
|
// create an integration between API Gateway and an SQS queue
|
46
|
-
const fifoMessageGroupId = queue.fifo
|
49
|
+
const fifoMessageGroupId = queue.fifo
|
50
|
+
? "&MessageGroupId=AlwaysSameFifoGroup"
|
51
|
+
: "";
|
47
52
|
const sqsIntegration = new AwsIntegration({
|
48
|
-
service:
|
49
|
-
integrationHttpMethod:
|
53
|
+
service: "sqs",
|
54
|
+
integrationHttpMethod: "POST",
|
50
55
|
options: {
|
51
56
|
passthroughBehavior: PassthroughBehavior.NEVER,
|
52
57
|
credentialsRole: apiGwRole,
|
53
58
|
requestParameters: {
|
54
59
|
// SQS requires the Content-Type of the HTTP request to be application/x-www-form-urlencoded
|
55
|
-
|
60
|
+
"integration.request.header.Content-Type":
|
61
|
+
"'application/x-www-form-urlencoded'",
|
56
62
|
},
|
57
63
|
requestTemplates: {
|
58
64
|
// map the JSON request to a form parameter, FIFO needs also MessageGroupId
|
59
65
|
// https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
|
60
|
-
|
66
|
+
"application/json": `Action=SendMessage${fifoMessageGroupId}&MessageBody=$util.urlEncode($input.body)`,
|
61
67
|
},
|
62
68
|
// these are required by SQS
|
63
69
|
integrationResponses: [
|
64
70
|
{
|
65
|
-
statusCode:
|
71
|
+
statusCode: "200",
|
66
72
|
responseTemplates: {
|
67
|
-
|
73
|
+
"text/html": "Success",
|
68
74
|
},
|
69
75
|
},
|
70
76
|
{
|
71
|
-
statusCode:
|
77
|
+
statusCode: "500",
|
72
78
|
responseTemplates: {
|
73
|
-
|
79
|
+
"text/html": "Error",
|
74
80
|
},
|
75
|
-
selectionPattern:
|
81
|
+
selectionPattern: "500",
|
76
82
|
},
|
77
|
-
|
78
83
|
],
|
79
|
-
|
80
84
|
},
|
81
85
|
path: `${Aws.ACCOUNT_ID}/${queue.queueName}`,
|
82
86
|
});
|
83
|
-
resource.addMethod(
|
87
|
+
resource.addMethod("POST", sqsIntegration, {
|
84
88
|
requestValidator,
|
85
89
|
apiKeyRequired,
|
86
90
|
requestModels: requestModels ?? {},
|
87
91
|
methodResponses: [
|
88
92
|
{
|
89
|
-
statusCode:
|
93
|
+
statusCode: "200",
|
90
94
|
responseParameters: {
|
91
|
-
|
95
|
+
"method.response.header.Content-Type": true,
|
92
96
|
},
|
93
97
|
},
|
94
98
|
{
|
95
|
-
statusCode:
|
99
|
+
statusCode: "500",
|
96
100
|
responseParameters: {
|
97
|
-
|
101
|
+
"method.response.header.Content-Type": true,
|
98
102
|
},
|
99
103
|
},
|
100
104
|
],
|