@digitraffic/common 2024.1.24-3 → 2024.3.11-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/__test__/api/handler-factory.test.d.mts +1 -0
- package/dist/__test__/api/handler-factory.test.mjs +43 -0
- package/dist/__test__/api/response.test.d.mts +1 -0
- package/dist/__test__/api/response.test.mjs +86 -0
- package/dist/__test__/imports.test.d.mts +1 -0
- package/dist/__test__/imports.test.mjs +332 -0
- package/dist/__test__/marine/id_utils.test.d.mts +1 -0
- package/dist/__test__/marine/id_utils.test.mjs +44 -0
- package/dist/__test__/promise/promise.test.d.mts +1 -0
- package/dist/__test__/promise/promise.test.mjs +130 -0
- package/dist/__test__/runtime/dt-logger.test.d.mts +1 -0
- package/dist/__test__/runtime/dt-logger.test.mjs +108 -0
- package/dist/__test__/secrets/secret-holder.test.d.mts +1 -0
- package/dist/__test__/secrets/secret-holder.test.mjs +86 -0
- package/dist/__test__/secrets/secret.test.d.mts +1 -0
- package/dist/__test__/secrets/secret.test.mjs +38 -0
- package/dist/__test__/test/httpserver.test.d.mts +1 -0
- package/dist/__test__/test/httpserver.test.mjs +154 -0
- package/dist/__test__/test/mock-ky.test.d.mts +1 -0
- package/dist/__test__/test/mock-ky.test.mjs +46 -0
- package/dist/__test__/types/lambda-response.test.d.mts +1 -0
- package/dist/__test__/types/lambda-response.test.mjs +58 -0
- package/dist/__test__/utils/date-utils.test.d.mts +1 -0
- package/dist/__test__/utils/date-utils.test.mjs +27 -0
- package/dist/__test__/utils/geometry.test.d.mts +1 -0
- package/dist/__test__/utils/geometry.test.mjs +24 -0
- package/dist/__test__/utils/logging.test.d.mts +1 -0
- package/dist/__test__/utils/logging.test.mjs +78 -0
- package/dist/__test__/utils/utils.test.d.mts +1 -0
- package/dist/__test__/utils/utils.test.mjs +43 -0
- package/dist/aws/infra/api/handler-factory.mjs +4 -0
- package/dist/aws/infra/api/integration.d.mts +2 -2
- package/dist/aws/infra/api/integration.mjs +4 -1
- package/dist/aws/infra/api/response.d.mts +1 -1
- package/dist/aws/infra/api/responses.d.mts +1 -1
- package/dist/aws/infra/api/responses.mjs +2 -0
- package/dist/aws/infra/api/static-integration.mjs +1 -1
- package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
- package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
- package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
- package/dist/aws/infra/canaries/canary-role.mjs +1 -0
- package/dist/aws/infra/canaries/canary.d.mts +2 -2
- package/dist/aws/infra/canaries/canary.mjs +2 -0
- package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
- package/dist/aws/infra/canaries/database-canary.mjs +2 -0
- package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
- package/dist/aws/infra/canaries/database-checker.mjs +7 -1
- package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
- package/dist/aws/infra/canaries/url-canary.mjs +3 -0
- package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
- package/dist/aws/infra/canaries/url-checker.mjs +4 -1
- package/dist/aws/infra/documentation.mjs +5 -1
- package/dist/aws/infra/import-util.d.mts +1 -1
- package/dist/aws/infra/import-util.mjs +4 -3
- package/dist/aws/infra/scheduler.mjs +2 -0
- package/dist/aws/infra/security-rule.d.mts +1 -1
- package/dist/aws/infra/security-rule.mjs +1 -0
- package/dist/aws/infra/sqs-integration.d.mts +1 -1
- package/dist/aws/infra/sqs-integration.mjs +3 -1
- package/dist/aws/infra/sqs-queue.d.mts +1 -1
- package/dist/aws/infra/sqs-queue.mjs +2 -1
- package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
- package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
- package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
- package/dist/aws/infra/stack/monitoredfunction.mjs +23 -18
- package/dist/aws/infra/stack/parameters.mjs +1 -0
- package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
- package/dist/aws/infra/stack/rest_apis.mjs +6 -1
- package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
- package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
- package/dist/aws/infra/stack/stack.d.mts +5 -5
- package/dist/aws/infra/stack/stack.mjs +9 -0
- package/dist/aws/infra/stack/subscription.mjs +4 -0
- package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
- package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
- package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
- package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
- package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
- package/dist/aws/infra/stacks/db-stack.mjs +11 -7
- package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
- package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
- package/dist/aws/infra/stacks/network-stack.mjs +8 -0
- package/dist/aws/infra/usage-plans.d.mts +1 -1
- package/dist/aws/infra/usage-plans.mjs +1 -0
- package/dist/aws/runtime/apikey.d.mts +2 -2
- package/dist/aws/runtime/apikey.mjs +2 -2
- package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
- package/dist/aws/runtime/dt-logger.mjs +6 -2
- package/dist/aws/runtime/messaging.d.mts +2 -2
- package/dist/aws/runtime/messaging.mjs +5 -4
- package/dist/aws/runtime/s3.d.mts +4 -2
- package/dist/aws/runtime/s3.mjs +15 -10
- package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
- package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
- package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
- package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
- package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
- package/dist/aws/runtime/secrets/secret.mjs +5 -6
- package/dist/aws/types/errors.mjs +1 -0
- package/dist/aws/types/lambda-response.mjs +5 -0
- package/dist/aws/types/model-with-reference.mjs +1 -1
- package/dist/database/cached.d.mts +1 -1
- package/dist/database/database.mjs +1 -0
- package/dist/database/last-updated.d.mts +1 -1
- package/dist/test/db-testutils.d.mts +1 -1
- package/dist/test/db-testutils.mjs +1 -1
- package/dist/test/httpserver.mjs +7 -3
- package/dist/test/mock-ky.d.mts +2 -0
- package/dist/test/mock-ky.mjs +15 -0
- package/dist/test/secrets-manager.d.mts +3 -2
- package/dist/test/secrets-manager.mjs +14 -16
- package/dist/test/testutils.mjs +1 -1
- package/dist/types/http-error.mjs +1 -0
- package/dist/types/nullable.d.mts +1 -1
- package/dist/utils/api-model.d.mts +2 -2
- package/dist/utils/api-model.mjs +1 -1
- package/dist/utils/geojson-types.d.mts +1 -1
- package/dist/utils/geojson-types.mjs +4 -2
- package/dist/utils/geometry.d.mts +1 -1
- package/dist/utils/geometry.mjs +3 -0
- package/dist/utils/logging.mjs +2 -2
- package/dist/utils/retry.d.mts +2 -2
- package/dist/utils/retry.mjs +2 -2
- package/dist/utils/slack.mjs +4 -3
- package/dist/utils/utils.d.mts +2 -2
- package/package.json +25 -15
- package/src/@types/geojson-validation/index.d.mts +0 -4
- package/src/aws/infra/api/handler-factory.mts +0 -86
- package/src/aws/infra/api/integration.mts +0 -147
- package/src/aws/infra/api/response.mts +0 -165
- package/src/aws/infra/api/responses.mts +0 -127
- package/src/aws/infra/api/static-integration.mts +0 -108
- package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
- package/src/aws/infra/canaries/canary-alarm.mts +0 -33
- package/src/aws/infra/canaries/canary-keys.mts +0 -3
- package/src/aws/infra/canaries/canary-parameters.mts +0 -19
- package/src/aws/infra/canaries/canary-role.mts +0 -73
- package/src/aws/infra/canaries/canary.mts +0 -44
- package/src/aws/infra/canaries/database-canary.mts +0 -98
- package/src/aws/infra/canaries/database-checker.mts +0 -163
- package/src/aws/infra/canaries/url-canary.mts +0 -98
- package/src/aws/infra/canaries/url-checker.mts +0 -388
- package/src/aws/infra/documentation.mts +0 -142
- package/src/aws/infra/import-util.mts +0 -57
- package/src/aws/infra/scheduler.mts +0 -59
- package/src/aws/infra/security-rule.mts +0 -38
- package/src/aws/infra/sqs-integration.mts +0 -106
- package/src/aws/infra/sqs-queue.mts +0 -162
- package/src/aws/infra/stack/lambda-configs.mts +0 -135
- package/src/aws/infra/stack/monitoredfunction.mts +0 -352
- package/src/aws/infra/stack/parameters.mts +0 -74
- package/src/aws/infra/stack/rest_apis.mts +0 -322
- package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
- package/src/aws/infra/stack/stack.mts +0 -144
- package/src/aws/infra/stack/subscription.mts +0 -58
- package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
- package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
- package/src/aws/infra/stacks/db-stack.mts +0 -292
- package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
- package/src/aws/infra/stacks/network-stack.mts +0 -76
- package/src/aws/infra/usage-plans.mts +0 -50
- package/src/aws/runtime/apikey.mts +0 -9
- package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
- package/src/aws/runtime/dt-logger-default.mts +0 -11
- package/src/aws/runtime/dt-logger.mts +0 -184
- package/src/aws/runtime/environment.mts +0 -22
- package/src/aws/runtime/messaging.mts +0 -26
- package/src/aws/runtime/s3.mts +0 -44
- package/src/aws/runtime/secrets/dbsecret.mts +0 -31
- package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
- package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
- package/src/aws/runtime/secrets/rds-holder.mts +0 -34
- package/src/aws/runtime/secrets/secret-holder.mts +0 -106
- package/src/aws/runtime/secrets/secret.mts +0 -58
- package/src/aws/types/errors.mts +0 -14
- package/src/aws/types/lambda-response.mts +0 -100
- package/src/aws/types/mediatypes.mts +0 -12
- package/src/aws/types/model-with-reference.mts +0 -8
- package/src/aws/types/proxytypes.mts +0 -27
- package/src/aws/types/tags.mts +0 -3
- package/src/database/cached.mts +0 -64
- package/src/database/database.mts +0 -107
- package/src/database/last-updated.mts +0 -103
- package/src/database/models.mts +0 -7
- package/src/index.mts +0 -2
- package/src/marine/id_utils.mts +0 -30
- package/src/marine/rtz.mts +0 -57
- package/src/test/asserter.mts +0 -58
- package/src/test/db-testutils.mts +0 -52
- package/src/test/httpserver.mts +0 -111
- package/src/test/secrets-manager.mts +0 -37
- package/src/test/testutils.mts +0 -39
- package/src/types/async-timeout-error.mts +0 -5
- package/src/types/aws-env.mts +0 -3
- package/src/types/either.mts +0 -9
- package/src/types/http-error.mts +0 -8
- package/src/types/input-error.mts +0 -2
- package/src/types/language.mts +0 -3
- package/src/types/nullable.mts +0 -21
- package/src/types/traffictype.mts +0 -8
- package/src/types/urn.mts +0 -1
- package/src/types/util-types.mts +0 -10
- package/src/types/validator.mts +0 -10
- package/src/utils/api-model.mts +0 -133
- package/src/utils/base64.mts +0 -16
- package/src/utils/date-utils.mts +0 -53
- package/src/utils/geojson-types.mts +0 -22
- package/src/utils/geometry.mts +0 -171
- package/src/utils/logging.mts +0 -75
- package/src/utils/retry.mts +0 -200
- package/src/utils/slack.mts +0 -26
- package/src/utils/utils.mts +0 -184
@@ -1,59 +0,0 @@
|
|
1
|
-
import { Rule, Schedule } from "aws-cdk-lib/aws-events";
|
2
|
-
import { Duration } from "aws-cdk-lib";
|
3
|
-
import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
|
4
|
-
import { Function as AWSFunction } from "aws-cdk-lib/aws-lambda";
|
5
|
-
import { Construct } from "constructs";
|
6
|
-
|
7
|
-
export class Scheduler extends Rule {
|
8
|
-
constructor(
|
9
|
-
stack: Construct,
|
10
|
-
ruleName: string,
|
11
|
-
schedule: Schedule,
|
12
|
-
lambda?: AWSFunction
|
13
|
-
) {
|
14
|
-
super(stack, ruleName, { ruleName, schedule });
|
15
|
-
|
16
|
-
if (lambda) {
|
17
|
-
this.addTarget(new LambdaFunction(lambda));
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
static everyMinute(
|
22
|
-
stack: Construct,
|
23
|
-
ruleName: string,
|
24
|
-
lambda?: AWSFunction
|
25
|
-
) {
|
26
|
-
return Scheduler.every(stack, ruleName, Duration.minutes(1), lambda);
|
27
|
-
}
|
28
|
-
|
29
|
-
static everyMinutes(
|
30
|
-
stack: Construct,
|
31
|
-
ruleName: string,
|
32
|
-
minutes: number,
|
33
|
-
lambda?: AWSFunction
|
34
|
-
) {
|
35
|
-
return Scheduler.every(
|
36
|
-
stack,
|
37
|
-
ruleName,
|
38
|
-
Duration.minutes(minutes),
|
39
|
-
lambda
|
40
|
-
);
|
41
|
-
}
|
42
|
-
|
43
|
-
static everyHour(stack: Construct, ruleName: string, lambda?: AWSFunction) {
|
44
|
-
return Scheduler.every(stack, ruleName, Duration.hours(1), lambda);
|
45
|
-
}
|
46
|
-
|
47
|
-
static everyDay(stack: Construct, ruleName: string, lambda?: AWSFunction) {
|
48
|
-
return Scheduler.every(stack, ruleName, Duration.days(1), lambda);
|
49
|
-
}
|
50
|
-
|
51
|
-
static every(
|
52
|
-
stack: Construct,
|
53
|
-
ruleName: string,
|
54
|
-
duration: Duration,
|
55
|
-
lambda?: AWSFunction
|
56
|
-
) {
|
57
|
-
return new Scheduler(stack, ruleName, Schedule.rate(duration), lambda);
|
58
|
-
}
|
59
|
-
}
|
@@ -1,38 +0,0 @@
|
|
1
|
-
import {Construct} from "constructs";
|
2
|
-
import {Rule} from "aws-cdk-lib/aws-events";
|
3
|
-
import {ITopic} from "aws-cdk-lib/aws-sns";
|
4
|
-
import {SnsTopic} from "aws-cdk-lib/aws-events-targets";
|
5
|
-
|
6
|
-
/**
|
7
|
-
* Automatic rule for Security Hub. Send notification to given topic if the following conditions apply:
|
8
|
-
* * There is a finding with a status of NEW
|
9
|
-
* * It has severity of HIGH or CRITICAL
|
10
|
-
* * It is in a FAILED state
|
11
|
-
*/
|
12
|
-
export class DigitrafficSecurityRule extends Rule {
|
13
|
-
constructor(scope: Construct, topic: ITopic) {
|
14
|
-
const ruleName = 'SecurityHubRule';
|
15
|
-
super(scope, ruleName, {
|
16
|
-
ruleName,
|
17
|
-
eventPattern: {
|
18
|
-
source: ['aws.securityhub'],
|
19
|
-
detailType: ["Security Hub Findings - Imported"],
|
20
|
-
detail: {
|
21
|
-
findings: {
|
22
|
-
"Compliance": {
|
23
|
-
"Status": ["FAILED"],
|
24
|
-
},
|
25
|
-
"Workflow": {
|
26
|
-
"Status": ["NEW"],
|
27
|
-
},
|
28
|
-
"Severity": {
|
29
|
-
"Label": ["HIGH", "CRITICAL"],
|
30
|
-
},
|
31
|
-
},
|
32
|
-
},
|
33
|
-
},
|
34
|
-
});
|
35
|
-
|
36
|
-
this.addTarget(new SnsTopic(topic));
|
37
|
-
}
|
38
|
-
}
|
@@ -1,106 +0,0 @@
|
|
1
|
-
import { Aws } from "aws-cdk-lib";
|
2
|
-
import {
|
3
|
-
AwsIntegration,
|
4
|
-
PassthroughBehavior,
|
5
|
-
RequestValidator,
|
6
|
-
Resource,
|
7
|
-
IModel
|
8
|
-
} from "aws-cdk-lib/aws-apigateway";
|
9
|
-
import { Queue } from "aws-cdk-lib/aws-sqs";
|
10
|
-
import { PolicyStatement, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
|
11
|
-
import { Construct } from "constructs";
|
12
|
-
|
13
|
-
export function attachQueueToApiGatewayResource(
|
14
|
-
stack: Construct,
|
15
|
-
queue: Queue,
|
16
|
-
resource: Resource,
|
17
|
-
requestValidator: RequestValidator,
|
18
|
-
resourceName: string,
|
19
|
-
apiKeyRequired: boolean,
|
20
|
-
requestModels?: Record<string, IModel>
|
21
|
-
) {
|
22
|
-
// role for API Gateway
|
23
|
-
const apiGwRole = new Role(stack, `${resourceName}APIGatewayToSQSRole`, {
|
24
|
-
assumedBy: new ServicePrincipal("apigateway.amazonaws.com"),
|
25
|
-
});
|
26
|
-
// grants API Gateway the right to send SQS messages
|
27
|
-
apiGwRole.addToPolicy(
|
28
|
-
new PolicyStatement({
|
29
|
-
resources: [queue.queueArn],
|
30
|
-
actions: ["sqs:SendMessage"],
|
31
|
-
})
|
32
|
-
);
|
33
|
-
// grants API Gateway the right write CloudWatch Logs
|
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
|
-
);
|
48
|
-
// create an integration between API Gateway and an SQS queue
|
49
|
-
const fifoMessageGroupId = queue.fifo
|
50
|
-
? "&MessageGroupId=AlwaysSameFifoGroup"
|
51
|
-
: "";
|
52
|
-
const sqsIntegration = new AwsIntegration({
|
53
|
-
service: "sqs",
|
54
|
-
integrationHttpMethod: "POST",
|
55
|
-
options: {
|
56
|
-
passthroughBehavior: PassthroughBehavior.NEVER,
|
57
|
-
credentialsRole: apiGwRole,
|
58
|
-
requestParameters: {
|
59
|
-
// SQS requires the Content-Type of the HTTP request to be application/x-www-form-urlencoded
|
60
|
-
"integration.request.header.Content-Type":
|
61
|
-
"'application/x-www-form-urlencoded'",
|
62
|
-
},
|
63
|
-
requestTemplates: {
|
64
|
-
// map the JSON request to a form parameter, FIFO needs also MessageGroupId
|
65
|
-
// https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
|
66
|
-
"application/json": `Action=SendMessage${fifoMessageGroupId}&MessageBody=$util.urlEncode($input.body)`,
|
67
|
-
},
|
68
|
-
// these are required by SQS
|
69
|
-
integrationResponses: [
|
70
|
-
{
|
71
|
-
statusCode: "200",
|
72
|
-
responseTemplates: {
|
73
|
-
"text/html": "Success",
|
74
|
-
},
|
75
|
-
},
|
76
|
-
{
|
77
|
-
statusCode: "500",
|
78
|
-
responseTemplates: {
|
79
|
-
"text/html": "Error",
|
80
|
-
},
|
81
|
-
selectionPattern: "500",
|
82
|
-
},
|
83
|
-
],
|
84
|
-
},
|
85
|
-
path: `${Aws.ACCOUNT_ID}/${queue.queueName}`,
|
86
|
-
});
|
87
|
-
resource.addMethod("POST", sqsIntegration, {
|
88
|
-
requestValidator,
|
89
|
-
apiKeyRequired,
|
90
|
-
requestModels: requestModels ?? {},
|
91
|
-
methodResponses: [
|
92
|
-
{
|
93
|
-
statusCode: "200",
|
94
|
-
responseParameters: {
|
95
|
-
"method.response.header.Content-Type": true,
|
96
|
-
},
|
97
|
-
},
|
98
|
-
{
|
99
|
-
statusCode: "500",
|
100
|
-
responseParameters: {
|
101
|
-
"method.response.header.Content-Type": true,
|
102
|
-
},
|
103
|
-
},
|
104
|
-
],
|
105
|
-
});
|
106
|
-
}
|
@@ -1,162 +0,0 @@
|
|
1
|
-
import { Queue, QueueEncryption, QueueProps } from "aws-cdk-lib/aws-sqs";
|
2
|
-
import { Duration } from "aws-cdk-lib";
|
3
|
-
import { BlockPublicAccess, Bucket } from "aws-cdk-lib/aws-s3";
|
4
|
-
import { PolicyStatement } from "aws-cdk-lib/aws-iam";
|
5
|
-
import { InlineCode, Runtime } from "aws-cdk-lib/aws-lambda";
|
6
|
-
import { RetentionDays } from "aws-cdk-lib/aws-logs";
|
7
|
-
import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
|
8
|
-
import { ComparisonOperator, TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
|
9
|
-
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
|
10
|
-
import { S3, S3Client } from "@aws-sdk/client-s3";
|
11
|
-
import { Upload } from "@aws-sdk/lib-storage";
|
12
|
-
import { SQSEvent, SQSHandler, SQSRecord } from "aws-lambda";
|
13
|
-
import { DigitrafficStack } from "./stack/stack.mjs";
|
14
|
-
import { MonitoredFunction } from "./stack/monitoredfunction.mjs";
|
15
|
-
|
16
|
-
/**
|
17
|
-
* Construct for creating SQS-queues.
|
18
|
-
*
|
19
|
-
* If you don't config your own deadLetterQueue, this will create a dlq for you, also a lambda function, a s3 bucket
|
20
|
-
* and an alarm for the queue. Anything that goes to the dlq will be written into the bucket and the alarm is activated.
|
21
|
-
*/
|
22
|
-
export class DigitrafficSqsQueue extends Queue {
|
23
|
-
static create(stack: DigitrafficStack, name: string, props: QueueProps): DigitrafficSqsQueue {
|
24
|
-
const queueName = `${stack.configuration.shortName}-${name}-Queue`;
|
25
|
-
const queueProps = {
|
26
|
-
...props,
|
27
|
-
...{
|
28
|
-
encryption: QueueEncryption.KMS_MANAGED,
|
29
|
-
queueName,
|
30
|
-
deadLetterQueue: props.deadLetterQueue ?? {
|
31
|
-
maxReceiveCount: 2,
|
32
|
-
queue: DigitrafficDLQueue.create(stack, name),
|
33
|
-
},
|
34
|
-
},
|
35
|
-
};
|
36
|
-
|
37
|
-
return new DigitrafficSqsQueue(stack, queueName, queueProps);
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
export class DigitrafficDLQueue {
|
42
|
-
static create(stack: DigitrafficStack, name: string): DigitrafficSqsQueue {
|
43
|
-
const dlqName = `${stack.configuration.shortName}-${name}-DLQ`;
|
44
|
-
|
45
|
-
const dlq = new DigitrafficSqsQueue(stack, dlqName, {
|
46
|
-
queueName: dlqName,
|
47
|
-
visibilityTimeout: Duration.seconds(60),
|
48
|
-
encryption: QueueEncryption.KMS_MANAGED,
|
49
|
-
});
|
50
|
-
|
51
|
-
const dlqBucket = new Bucket(stack, `${dlqName}-Bucket`, {
|
52
|
-
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
53
|
-
});
|
54
|
-
|
55
|
-
const dlqFunctionName = `${dlqName}-Function`;
|
56
|
-
const lambda = MonitoredFunction.create(stack, dlqFunctionName, {
|
57
|
-
runtime: Runtime.NODEJS_20_X,
|
58
|
-
logRetention: RetentionDays.ONE_YEAR,
|
59
|
-
functionName: dlqFunctionName,
|
60
|
-
code: getDlqCode(dlqBucket.bucketName),
|
61
|
-
timeout: Duration.seconds(10),
|
62
|
-
handler: "index.handler",
|
63
|
-
memorySize: 128,
|
64
|
-
reservedConcurrentExecutions: 1,
|
65
|
-
});
|
66
|
-
|
67
|
-
const statement = new PolicyStatement();
|
68
|
-
statement.addActions("s3:PutObject");
|
69
|
-
statement.addActions("s3:PutObjectAcl");
|
70
|
-
statement.addResources(dlqBucket.bucketArn + "/*");
|
71
|
-
|
72
|
-
lambda.addToRolePolicy(statement);
|
73
|
-
lambda.addEventSource(new SqsEventSource(dlq));
|
74
|
-
|
75
|
-
addDLQAlarm(stack, dlqName, dlq);
|
76
|
-
|
77
|
-
return dlq;
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
function addDLQAlarm(stack: DigitrafficStack, dlqName: string, dlq: Queue) {
|
82
|
-
const alarmName = `${dlqName}-Alarm`;
|
83
|
-
dlq.metricNumberOfMessagesReceived({
|
84
|
-
period: Duration.minutes(5),
|
85
|
-
})
|
86
|
-
.createAlarm(stack, alarmName, {
|
87
|
-
alarmName,
|
88
|
-
threshold: 0,
|
89
|
-
evaluationPeriods: 1,
|
90
|
-
treatMissingData: TreatMissingData.NOT_BREACHING,
|
91
|
-
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
|
92
|
-
})
|
93
|
-
.addAlarmAction(new SnsAction(stack.warningTopic));
|
94
|
-
}
|
95
|
-
|
96
|
-
function getDlqCode(Bucket: string): InlineCode {
|
97
|
-
const functionBody = DLQ_LAMBDA_CODE.replace("__bucketName__", Bucket)
|
98
|
-
.replace("__upload__", uploadToS3.toString())
|
99
|
-
.replace("__doUpload__", doUpload.toString())
|
100
|
-
.replace("__handler__", createHandler().toString().substring(23)); // remove function handler() from signature
|
101
|
-
|
102
|
-
return new InlineCode(functionBody);
|
103
|
-
}
|
104
|
-
|
105
|
-
async function uploadToS3(s3: S3 | S3Client, Bucket: string, Body: string, Key: string): Promise<void> {
|
106
|
-
try {
|
107
|
-
console.info("writing %s to %s", Key, Bucket);
|
108
|
-
await doUpload(s3, Bucket, Body, Key);
|
109
|
-
} catch (error) {
|
110
|
-
console.warn(error);
|
111
|
-
console.warn("method=uploadToS3 retrying upload to bucket %s", Bucket);
|
112
|
-
try {
|
113
|
-
await doUpload(s3, Bucket, Body, Key);
|
114
|
-
} catch (e2) {
|
115
|
-
console.error("method=uploadToS3 failed retrying upload to bucket %s", Bucket);
|
116
|
-
}
|
117
|
-
}
|
118
|
-
}
|
119
|
-
|
120
|
-
async function doUpload(s3: S3 | S3Client, Bucket: string, Body: string, Key: string) {
|
121
|
-
try {
|
122
|
-
const upload = new Upload({
|
123
|
-
client: s3,
|
124
|
-
params: { Bucket, Key, Body },
|
125
|
-
});
|
126
|
-
|
127
|
-
await upload.done();
|
128
|
-
} catch (error) {
|
129
|
-
console.error(error);
|
130
|
-
}
|
131
|
-
}
|
132
|
-
|
133
|
-
// bucketName is unused, will be overridden in the actual lambda code below
|
134
|
-
const bucketName = "";
|
135
|
-
|
136
|
-
function createHandler(): SQSHandler {
|
137
|
-
return async function handler(event: SQSEvent): Promise<void> {
|
138
|
-
|
139
|
-
const millis = new Date().getTime();
|
140
|
-
await Promise.all(
|
141
|
-
event.Records.map((e: SQSRecord, idx: number) =>
|
142
|
-
uploadToS3(
|
143
|
-
new S3(),
|
144
|
-
bucketName,
|
145
|
-
e.body,
|
146
|
-
`dlq-${millis}-${idx}.json`
|
147
|
-
)
|
148
|
-
)
|
149
|
-
);
|
150
|
-
};
|
151
|
-
}
|
152
|
-
|
153
|
-
const DLQ_LAMBDA_CODE = `
|
154
|
-
import { S3, S3Client } from "@aws-sdk/client-s3";
|
155
|
-
import { Upload } from "@aws-sdk/lib-storage";
|
156
|
-
const bucketName = "__bucketName__";
|
157
|
-
|
158
|
-
__upload__
|
159
|
-
__doUpload__
|
160
|
-
|
161
|
-
exports.handler = async (event) => __handler__
|
162
|
-
`;
|
@@ -1,135 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Architecture,
|
3
|
-
AssetCode,
|
4
|
-
Code,
|
5
|
-
FunctionProps,
|
6
|
-
Runtime,
|
7
|
-
} from "aws-cdk-lib/aws-lambda";
|
8
|
-
import { Duration } from "aws-cdk-lib";
|
9
|
-
import { IVpc, SubnetSelection } from "aws-cdk-lib/aws-ec2";
|
10
|
-
import { RetentionDays } from "aws-cdk-lib/aws-logs";
|
11
|
-
import { Role } from "aws-cdk-lib/aws-iam";
|
12
|
-
import { DigitrafficStack } from "./stack.mjs";
|
13
|
-
import { MonitoredFunctionAlarmProps } from "./monitoredfunction.mjs";
|
14
|
-
|
15
|
-
export type LambdaEnvironment = Record<string, string>;
|
16
|
-
|
17
|
-
export type DBLambdaEnvironment = LambdaEnvironment & {
|
18
|
-
SECRET_ID?: string;
|
19
|
-
DB_APPLICATION: string;
|
20
|
-
};
|
21
|
-
|
22
|
-
export function databaseFunctionProps(
|
23
|
-
stack: DigitrafficStack,
|
24
|
-
environment: LambdaEnvironment,
|
25
|
-
lambdaName: string,
|
26
|
-
simpleLambdaName: string,
|
27
|
-
config?: Partial<FunctionParameters>,
|
28
|
-
): FunctionProps {
|
29
|
-
const vpcSubnets = stack.vpc
|
30
|
-
? {
|
31
|
-
subnets: stack.vpc.privateSubnets,
|
32
|
-
}
|
33
|
-
: undefined;
|
34
|
-
|
35
|
-
return {
|
36
|
-
...lambdaFunctionProps(
|
37
|
-
stack,
|
38
|
-
environment,
|
39
|
-
lambdaName,
|
40
|
-
simpleLambdaName,
|
41
|
-
config,
|
42
|
-
),
|
43
|
-
...{
|
44
|
-
vpc: stack.vpc ?? undefined,
|
45
|
-
vpcSubnets,
|
46
|
-
securityGroup: stack.lambdaDbSg ?? undefined,
|
47
|
-
},
|
48
|
-
};
|
49
|
-
}
|
50
|
-
|
51
|
-
export function lambdaFunctionProps(
|
52
|
-
stack: DigitrafficStack,
|
53
|
-
environment: LambdaEnvironment,
|
54
|
-
lambdaName: string,
|
55
|
-
simpleLambdaName: string,
|
56
|
-
config?: Partial<FunctionParameters>,
|
57
|
-
): FunctionProps {
|
58
|
-
return {
|
59
|
-
runtime: config?.runtime ?? Runtime.NODEJS_20_X,
|
60
|
-
architecture: config?.architecture ?? Architecture.ARM_64,
|
61
|
-
memorySize: config?.memorySize ?? 128,
|
62
|
-
functionName: lambdaName,
|
63
|
-
role: config?.role,
|
64
|
-
timeout: Duration.seconds(config?.timeout ?? 60),
|
65
|
-
logRetention: RetentionDays.ONE_YEAR,
|
66
|
-
reservedConcurrentExecutions: config?.reservedConcurrentExecutions ?? 2,
|
67
|
-
code: getAssetCode(simpleLambdaName, config?.singleLambda ?? false),
|
68
|
-
handler: `${simpleLambdaName}.handler`,
|
69
|
-
environment,
|
70
|
-
};
|
71
|
-
}
|
72
|
-
|
73
|
-
function getAssetCode(
|
74
|
-
simpleLambdaName: string,
|
75
|
-
isSingleLambda: boolean,
|
76
|
-
): AssetCode {
|
77
|
-
const lambdaPath = isSingleLambda
|
78
|
-
? `dist/lambda/`
|
79
|
-
: `dist/lambda/${simpleLambdaName}`;
|
80
|
-
|
81
|
-
return new AssetCode(lambdaPath);
|
82
|
-
}
|
83
|
-
|
84
|
-
export function defaultLambdaConfiguration(
|
85
|
-
config: FunctionParameters,
|
86
|
-
): FunctionProps {
|
87
|
-
const props: FunctionProps = {
|
88
|
-
runtime: Runtime.NODEJS_20_X,
|
89
|
-
memorySize: config.memorySize ?? 128,
|
90
|
-
functionName: config.functionName,
|
91
|
-
handler: config.handler,
|
92
|
-
environment: config.environment ?? {},
|
93
|
-
logRetention: RetentionDays.ONE_YEAR,
|
94
|
-
reservedConcurrentExecutions: config.reservedConcurrentExecutions,
|
95
|
-
code: config.code,
|
96
|
-
role: config.role,
|
97
|
-
timeout: Duration.seconds(config.timeout ?? 10),
|
98
|
-
};
|
99
|
-
if (config.vpc) {
|
100
|
-
return {
|
101
|
-
...props,
|
102
|
-
...{
|
103
|
-
vpc: config.vpc,
|
104
|
-
vpcSubnets: {
|
105
|
-
subnets: config.vpc.privateSubnets,
|
106
|
-
},
|
107
|
-
},
|
108
|
-
};
|
109
|
-
}
|
110
|
-
return props;
|
111
|
-
}
|
112
|
-
|
113
|
-
export interface FunctionParameters {
|
114
|
-
memorySize?: number;
|
115
|
-
timeout?: number;
|
116
|
-
functionName?: string;
|
117
|
-
code: Code;
|
118
|
-
handler: string;
|
119
|
-
readOnly?: boolean;
|
120
|
-
environment?: Record<string, string>;
|
121
|
-
reservedConcurrentExecutions?: number;
|
122
|
-
role?: Role;
|
123
|
-
vpc?: IVpc;
|
124
|
-
vpcSubnets?: SubnetSelection;
|
125
|
-
runtime?: Runtime;
|
126
|
-
architecture?: Architecture;
|
127
|
-
singleLambda?: boolean;
|
128
|
-
}
|
129
|
-
|
130
|
-
export type MonitoredFunctionParameters = FunctionParameters & {
|
131
|
-
readonly durationAlarmProps?: MonitoredFunctionAlarmProps;
|
132
|
-
readonly durationWarningProps?: MonitoredFunctionAlarmProps;
|
133
|
-
readonly errorAlarmProps?: MonitoredFunctionAlarmProps;
|
134
|
-
readonly throttleAlarmProps?: MonitoredFunctionAlarmProps;
|
135
|
-
};
|