@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.
Files changed (212) hide show
  1. package/dist/__test__/api/handler-factory.test.d.mts +1 -0
  2. package/dist/__test__/api/handler-factory.test.mjs +43 -0
  3. package/dist/__test__/api/response.test.d.mts +1 -0
  4. package/dist/__test__/api/response.test.mjs +86 -0
  5. package/dist/__test__/imports.test.d.mts +1 -0
  6. package/dist/__test__/imports.test.mjs +332 -0
  7. package/dist/__test__/marine/id_utils.test.d.mts +1 -0
  8. package/dist/__test__/marine/id_utils.test.mjs +44 -0
  9. package/dist/__test__/promise/promise.test.d.mts +1 -0
  10. package/dist/__test__/promise/promise.test.mjs +130 -0
  11. package/dist/__test__/runtime/dt-logger.test.d.mts +1 -0
  12. package/dist/__test__/runtime/dt-logger.test.mjs +108 -0
  13. package/dist/__test__/secrets/secret-holder.test.d.mts +1 -0
  14. package/dist/__test__/secrets/secret-holder.test.mjs +86 -0
  15. package/dist/__test__/secrets/secret.test.d.mts +1 -0
  16. package/dist/__test__/secrets/secret.test.mjs +38 -0
  17. package/dist/__test__/test/httpserver.test.d.mts +1 -0
  18. package/dist/__test__/test/httpserver.test.mjs +154 -0
  19. package/dist/__test__/test/mock-ky.test.d.mts +1 -0
  20. package/dist/__test__/test/mock-ky.test.mjs +46 -0
  21. package/dist/__test__/types/lambda-response.test.d.mts +1 -0
  22. package/dist/__test__/types/lambda-response.test.mjs +58 -0
  23. package/dist/__test__/utils/date-utils.test.d.mts +1 -0
  24. package/dist/__test__/utils/date-utils.test.mjs +27 -0
  25. package/dist/__test__/utils/geometry.test.d.mts +1 -0
  26. package/dist/__test__/utils/geometry.test.mjs +24 -0
  27. package/dist/__test__/utils/logging.test.d.mts +1 -0
  28. package/dist/__test__/utils/logging.test.mjs +78 -0
  29. package/dist/__test__/utils/utils.test.d.mts +1 -0
  30. package/dist/__test__/utils/utils.test.mjs +43 -0
  31. package/dist/aws/infra/api/handler-factory.mjs +4 -0
  32. package/dist/aws/infra/api/integration.d.mts +2 -2
  33. package/dist/aws/infra/api/integration.mjs +4 -1
  34. package/dist/aws/infra/api/response.d.mts +1 -1
  35. package/dist/aws/infra/api/responses.d.mts +1 -1
  36. package/dist/aws/infra/api/responses.mjs +2 -0
  37. package/dist/aws/infra/api/static-integration.mjs +1 -1
  38. package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
  39. package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
  40. package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
  41. package/dist/aws/infra/canaries/canary-role.mjs +1 -0
  42. package/dist/aws/infra/canaries/canary.d.mts +2 -2
  43. package/dist/aws/infra/canaries/canary.mjs +2 -0
  44. package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
  45. package/dist/aws/infra/canaries/database-canary.mjs +2 -0
  46. package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
  47. package/dist/aws/infra/canaries/database-checker.mjs +7 -1
  48. package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
  49. package/dist/aws/infra/canaries/url-canary.mjs +3 -0
  50. package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
  51. package/dist/aws/infra/canaries/url-checker.mjs +4 -1
  52. package/dist/aws/infra/documentation.mjs +5 -1
  53. package/dist/aws/infra/import-util.d.mts +1 -1
  54. package/dist/aws/infra/import-util.mjs +4 -3
  55. package/dist/aws/infra/scheduler.mjs +2 -0
  56. package/dist/aws/infra/security-rule.d.mts +1 -1
  57. package/dist/aws/infra/security-rule.mjs +1 -0
  58. package/dist/aws/infra/sqs-integration.d.mts +1 -1
  59. package/dist/aws/infra/sqs-integration.mjs +3 -1
  60. package/dist/aws/infra/sqs-queue.d.mts +1 -1
  61. package/dist/aws/infra/sqs-queue.mjs +2 -1
  62. package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
  63. package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
  64. package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
  65. package/dist/aws/infra/stack/monitoredfunction.mjs +23 -18
  66. package/dist/aws/infra/stack/parameters.mjs +1 -0
  67. package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
  68. package/dist/aws/infra/stack/rest_apis.mjs +6 -1
  69. package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
  70. package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
  71. package/dist/aws/infra/stack/stack.d.mts +5 -5
  72. package/dist/aws/infra/stack/stack.mjs +9 -0
  73. package/dist/aws/infra/stack/subscription.mjs +4 -0
  74. package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
  75. package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
  76. package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
  77. package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
  78. package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
  79. package/dist/aws/infra/stacks/db-stack.mjs +11 -7
  80. package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
  81. package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
  82. package/dist/aws/infra/stacks/network-stack.mjs +8 -0
  83. package/dist/aws/infra/usage-plans.d.mts +1 -1
  84. package/dist/aws/infra/usage-plans.mjs +1 -0
  85. package/dist/aws/runtime/apikey.d.mts +2 -2
  86. package/dist/aws/runtime/apikey.mjs +2 -2
  87. package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
  88. package/dist/aws/runtime/dt-logger.mjs +6 -2
  89. package/dist/aws/runtime/messaging.d.mts +2 -2
  90. package/dist/aws/runtime/messaging.mjs +5 -4
  91. package/dist/aws/runtime/s3.d.mts +4 -2
  92. package/dist/aws/runtime/s3.mjs +15 -10
  93. package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
  94. package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
  95. package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
  96. package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
  97. package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
  98. package/dist/aws/runtime/secrets/secret.mjs +5 -6
  99. package/dist/aws/types/errors.mjs +1 -0
  100. package/dist/aws/types/lambda-response.mjs +5 -0
  101. package/dist/aws/types/model-with-reference.mjs +1 -1
  102. package/dist/database/cached.d.mts +1 -1
  103. package/dist/database/database.mjs +1 -0
  104. package/dist/database/last-updated.d.mts +1 -1
  105. package/dist/test/db-testutils.d.mts +1 -1
  106. package/dist/test/db-testutils.mjs +1 -1
  107. package/dist/test/httpserver.mjs +7 -3
  108. package/dist/test/mock-ky.d.mts +2 -0
  109. package/dist/test/mock-ky.mjs +15 -0
  110. package/dist/test/secrets-manager.d.mts +3 -2
  111. package/dist/test/secrets-manager.mjs +14 -16
  112. package/dist/test/testutils.mjs +1 -1
  113. package/dist/types/http-error.mjs +1 -0
  114. package/dist/types/nullable.d.mts +1 -1
  115. package/dist/utils/api-model.d.mts +2 -2
  116. package/dist/utils/api-model.mjs +1 -1
  117. package/dist/utils/geojson-types.d.mts +1 -1
  118. package/dist/utils/geojson-types.mjs +4 -2
  119. package/dist/utils/geometry.d.mts +1 -1
  120. package/dist/utils/geometry.mjs +3 -0
  121. package/dist/utils/logging.mjs +2 -2
  122. package/dist/utils/retry.d.mts +2 -2
  123. package/dist/utils/retry.mjs +2 -2
  124. package/dist/utils/slack.mjs +4 -3
  125. package/dist/utils/utils.d.mts +2 -2
  126. package/package.json +25 -15
  127. package/src/@types/geojson-validation/index.d.mts +0 -4
  128. package/src/aws/infra/api/handler-factory.mts +0 -86
  129. package/src/aws/infra/api/integration.mts +0 -147
  130. package/src/aws/infra/api/response.mts +0 -165
  131. package/src/aws/infra/api/responses.mts +0 -127
  132. package/src/aws/infra/api/static-integration.mts +0 -108
  133. package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
  134. package/src/aws/infra/canaries/canary-alarm.mts +0 -33
  135. package/src/aws/infra/canaries/canary-keys.mts +0 -3
  136. package/src/aws/infra/canaries/canary-parameters.mts +0 -19
  137. package/src/aws/infra/canaries/canary-role.mts +0 -73
  138. package/src/aws/infra/canaries/canary.mts +0 -44
  139. package/src/aws/infra/canaries/database-canary.mts +0 -98
  140. package/src/aws/infra/canaries/database-checker.mts +0 -163
  141. package/src/aws/infra/canaries/url-canary.mts +0 -98
  142. package/src/aws/infra/canaries/url-checker.mts +0 -388
  143. package/src/aws/infra/documentation.mts +0 -142
  144. package/src/aws/infra/import-util.mts +0 -57
  145. package/src/aws/infra/scheduler.mts +0 -59
  146. package/src/aws/infra/security-rule.mts +0 -38
  147. package/src/aws/infra/sqs-integration.mts +0 -106
  148. package/src/aws/infra/sqs-queue.mts +0 -162
  149. package/src/aws/infra/stack/lambda-configs.mts +0 -135
  150. package/src/aws/infra/stack/monitoredfunction.mts +0 -352
  151. package/src/aws/infra/stack/parameters.mts +0 -74
  152. package/src/aws/infra/stack/rest_apis.mts +0 -322
  153. package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
  154. package/src/aws/infra/stack/stack.mts +0 -144
  155. package/src/aws/infra/stack/subscription.mts +0 -58
  156. package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
  157. package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
  158. package/src/aws/infra/stacks/db-stack.mts +0 -292
  159. package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
  160. package/src/aws/infra/stacks/network-stack.mts +0 -76
  161. package/src/aws/infra/usage-plans.mts +0 -50
  162. package/src/aws/runtime/apikey.mts +0 -9
  163. package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
  164. package/src/aws/runtime/dt-logger-default.mts +0 -11
  165. package/src/aws/runtime/dt-logger.mts +0 -184
  166. package/src/aws/runtime/environment.mts +0 -22
  167. package/src/aws/runtime/messaging.mts +0 -26
  168. package/src/aws/runtime/s3.mts +0 -44
  169. package/src/aws/runtime/secrets/dbsecret.mts +0 -31
  170. package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
  171. package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
  172. package/src/aws/runtime/secrets/rds-holder.mts +0 -34
  173. package/src/aws/runtime/secrets/secret-holder.mts +0 -106
  174. package/src/aws/runtime/secrets/secret.mts +0 -58
  175. package/src/aws/types/errors.mts +0 -14
  176. package/src/aws/types/lambda-response.mts +0 -100
  177. package/src/aws/types/mediatypes.mts +0 -12
  178. package/src/aws/types/model-with-reference.mts +0 -8
  179. package/src/aws/types/proxytypes.mts +0 -27
  180. package/src/aws/types/tags.mts +0 -3
  181. package/src/database/cached.mts +0 -64
  182. package/src/database/database.mts +0 -107
  183. package/src/database/last-updated.mts +0 -103
  184. package/src/database/models.mts +0 -7
  185. package/src/index.mts +0 -2
  186. package/src/marine/id_utils.mts +0 -30
  187. package/src/marine/rtz.mts +0 -57
  188. package/src/test/asserter.mts +0 -58
  189. package/src/test/db-testutils.mts +0 -52
  190. package/src/test/httpserver.mts +0 -111
  191. package/src/test/secrets-manager.mts +0 -37
  192. package/src/test/testutils.mts +0 -39
  193. package/src/types/async-timeout-error.mts +0 -5
  194. package/src/types/aws-env.mts +0 -3
  195. package/src/types/either.mts +0 -9
  196. package/src/types/http-error.mts +0 -8
  197. package/src/types/input-error.mts +0 -2
  198. package/src/types/language.mts +0 -3
  199. package/src/types/nullable.mts +0 -21
  200. package/src/types/traffictype.mts +0 -8
  201. package/src/types/urn.mts +0 -1
  202. package/src/types/util-types.mts +0 -10
  203. package/src/types/validator.mts +0 -10
  204. package/src/utils/api-model.mts +0 -133
  205. package/src/utils/base64.mts +0 -16
  206. package/src/utils/date-utils.mts +0 -53
  207. package/src/utils/geojson-types.mts +0 -22
  208. package/src/utils/geometry.mts +0 -171
  209. package/src/utils/logging.mts +0 -75
  210. package/src/utils/retry.mts +0 -200
  211. package/src/utils/slack.mts +0 -26
  212. 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
- };