@lafken/queue 0.11.19 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/main/queue/queue.js +2 -0
- package/lib/main/queue/queue.types.d.ts +30 -5
- package/lib/resolver/queue/base/base.d.ts +16 -0
- package/lib/resolver/queue/base/base.js +60 -0
- package/lib/resolver/queue/external/external.d.ts +25 -0
- package/lib/resolver/queue/external/external.js +42 -0
- package/lib/resolver/queue/{queue.d.ts → internal/internal.d.ts} +12 -7
- package/lib/resolver/queue/internal/internal.js +50 -0
- package/lib/resolver/queue/queue.types.d.ts +7 -1
- package/lib/resolver/resolver.js +11 -2
- package/package.json +8 -9
- package/lib/resolver/queue/queue.js +0 -106
package/lib/main/queue/queue.js
CHANGED
|
@@ -92,6 +92,7 @@ exports.Standard = (0, common_1.createLambdaDecorator)({
|
|
|
92
92
|
getLambdaMetadata: (props, methodName) => ({
|
|
93
93
|
...props,
|
|
94
94
|
queueName: props.queueName || methodName,
|
|
95
|
+
isExternal: props.isExternal ?? false,
|
|
95
96
|
name: methodName,
|
|
96
97
|
isFifo: false,
|
|
97
98
|
}),
|
|
@@ -122,6 +123,7 @@ exports.Fifo = (0, common_1.createLambdaDecorator)({
|
|
|
122
123
|
getLambdaMetadata: (props, methodName) => ({
|
|
123
124
|
...props,
|
|
124
125
|
queueName: props.queueName || methodName,
|
|
126
|
+
isExternal: props.isExternal ?? false,
|
|
125
127
|
name: methodName,
|
|
126
128
|
isFifo: true,
|
|
127
129
|
}),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LambdaMetadata, LambdaProps, QueueNames, QueueReferenceNames, ResourceOutputType } from '@lafken/common';
|
|
1
|
+
import type { GetResourceProps, LambdaMetadata, LambdaProps, QueueNames, QueueReferenceNames, ResourceOutputType } from '@lafken/common';
|
|
2
2
|
/**
|
|
3
3
|
* Attributes that can be exported from an SQS queue resource.
|
|
4
4
|
*
|
|
@@ -18,7 +18,15 @@ export interface DlqProps {
|
|
|
18
18
|
*/
|
|
19
19
|
retentionPeriod?: number;
|
|
20
20
|
}
|
|
21
|
-
export interface
|
|
21
|
+
export interface InternalStandardProps {
|
|
22
|
+
/**
|
|
23
|
+
* Marks the queue as an external resource.
|
|
24
|
+
*
|
|
25
|
+
* When set to `true`, the SQS queue is not created by the framework.
|
|
26
|
+
* Instead, it references an existing queue by `queueName`. The Lambda
|
|
27
|
+
* handler and event source mapping are still created.
|
|
28
|
+
*/
|
|
29
|
+
isExternal?: false;
|
|
22
30
|
/**
|
|
23
31
|
* Delivery delay in seconds.
|
|
24
32
|
*
|
|
@@ -115,7 +123,21 @@ export interface StandardProps {
|
|
|
115
123
|
*/
|
|
116
124
|
dlq?: DlqProps;
|
|
117
125
|
}
|
|
118
|
-
export interface
|
|
126
|
+
export interface ExternalQueueProps {
|
|
127
|
+
/**
|
|
128
|
+
* Marks the queue as an external resource.
|
|
129
|
+
*
|
|
130
|
+
* When set to `true`, the SQS queue is not created by the framework.
|
|
131
|
+
* Instead, it references an existing queue by `queueName`. The Lambda
|
|
132
|
+
* handler and event source mapping are still created.
|
|
133
|
+
*/
|
|
134
|
+
isExternal: true;
|
|
135
|
+
/**
|
|
136
|
+
*
|
|
137
|
+
*/
|
|
138
|
+
queueName: string | ((props: GetResourceProps) => string);
|
|
139
|
+
}
|
|
140
|
+
export interface InternalFifoProps extends InternalStandardProps {
|
|
119
141
|
/**
|
|
120
142
|
* Enable content-based deduplication.
|
|
121
143
|
*
|
|
@@ -126,7 +148,10 @@ export interface FifoProps extends StandardProps {
|
|
|
126
148
|
*/
|
|
127
149
|
contentBasedDeduplication?: boolean;
|
|
128
150
|
}
|
|
129
|
-
export
|
|
130
|
-
|
|
151
|
+
export type StandardProps = InternalStandardProps | ExternalQueueProps;
|
|
152
|
+
export type FifoProps = InternalFifoProps | ExternalQueueProps;
|
|
153
|
+
export interface QueueLambdaMetadata extends LambdaMetadata, Omit<InternalFifoProps, 'queueName' | 'isExternal'> {
|
|
154
|
+
queueName: ExternalQueueProps['queueName'];
|
|
131
155
|
isFifo: boolean;
|
|
156
|
+
isExternal: boolean;
|
|
132
157
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Construct } from 'constructs';
|
|
2
|
+
import type { QueueProps } from '../queue.types';
|
|
3
|
+
type Constructor = new (...args: any[]) => Construct & {
|
|
4
|
+
arn: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function QueueBase<TBase extends Constructor>(Base: TBase): {
|
|
7
|
+
new (...args: any[]): {
|
|
8
|
+
addEventSource(id: string, props: QueueProps): void;
|
|
9
|
+
validateEventParams(props: QueueProps): void;
|
|
10
|
+
readonly node: import("constructs").Node;
|
|
11
|
+
with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
|
|
12
|
+
toString(): string;
|
|
13
|
+
arn: string;
|
|
14
|
+
};
|
|
15
|
+
} & TBase;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueBase = QueueBase;
|
|
4
|
+
const lambda_event_source_mapping_1 = require("@cdktn/provider-aws/lib/lambda-event-source-mapping");
|
|
5
|
+
const common_1 = require("@lafken/common");
|
|
6
|
+
const resolver_1 = require("@lafken/resolver");
|
|
7
|
+
const attributeAllowedTypes = new Set(['String', 'Number']);
|
|
8
|
+
const bodyUnparsedTypes = new Set(['String']);
|
|
9
|
+
function getParams(props) {
|
|
10
|
+
const { classResource, handler } = props;
|
|
11
|
+
const params = (0, common_1.getMetadataPrototypeByKey)(classResource, common_1.LambdaReflectKeys.event_param) || {};
|
|
12
|
+
return params[handler.name];
|
|
13
|
+
}
|
|
14
|
+
function validateParamType(param) {
|
|
15
|
+
if (param.source === 'attribute' && !attributeAllowedTypes.has(param.type)) {
|
|
16
|
+
throw new Error(`Attribute params only support ${[...attributeAllowedTypes].join(', ')} values`);
|
|
17
|
+
}
|
|
18
|
+
if (param?.source === 'body' && !param.parse && !bodyUnparsedTypes.has(param.type)) {
|
|
19
|
+
throw new Error(`Body params only support ${[...bodyUnparsedTypes].join(', ')} values`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function QueueBase(Base) {
|
|
23
|
+
class QueueWithBase extends Base {
|
|
24
|
+
addEventSource(id, props) {
|
|
25
|
+
const { handler, resourceMetadata } = props;
|
|
26
|
+
const lambdaHandler = new resolver_1.LambdaHandler(this, `${id}-handler`, {
|
|
27
|
+
...handler,
|
|
28
|
+
originalName: resourceMetadata.originalName,
|
|
29
|
+
filename: resourceMetadata.filename,
|
|
30
|
+
foldername: resourceMetadata.foldername,
|
|
31
|
+
suffix: 'queue',
|
|
32
|
+
});
|
|
33
|
+
new lambda_event_source_mapping_1.LambdaEventSourceMapping(this, 'event-mapping', {
|
|
34
|
+
batchSize: handler.batchSize,
|
|
35
|
+
eventSourceArn: this.arn,
|
|
36
|
+
functionName: lambdaHandler.arn,
|
|
37
|
+
maximumBatchingWindowInSeconds: handler.maxBatchingWindow,
|
|
38
|
+
functionResponseTypes: handler.isFifo ? ['ReportBatchItemFailures'] : undefined,
|
|
39
|
+
scalingConfig: handler.maxConcurrency
|
|
40
|
+
? { maximumConcurrency: handler.maxConcurrency }
|
|
41
|
+
: undefined,
|
|
42
|
+
dependsOn: [lambdaHandler],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
validateEventParams(props) {
|
|
46
|
+
const param = getParams(props);
|
|
47
|
+
if (!param)
|
|
48
|
+
return;
|
|
49
|
+
let bodyCount = 0;
|
|
50
|
+
for (const property of param.properties) {
|
|
51
|
+
validateParamType(property);
|
|
52
|
+
if (property.source === 'body')
|
|
53
|
+
bodyCount++;
|
|
54
|
+
if (bodyCount >= 2)
|
|
55
|
+
throw new Error('Queue event only support one body param');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return QueueWithBase;
|
|
60
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DataAwsSqsQueue } from '@cdktn/provider-aws/lib/data-aws-sqs-queue';
|
|
2
|
+
import { type AppModule } from '@lafken/resolver';
|
|
3
|
+
import type { QueueProps } from '../queue.types';
|
|
4
|
+
declare const ExternalQueue_base: {
|
|
5
|
+
new (...args: any[]): {
|
|
6
|
+
addEventSource(id: string, props: QueueProps): void;
|
|
7
|
+
validateEventParams(props: QueueProps): void;
|
|
8
|
+
readonly node: import("constructs").Node;
|
|
9
|
+
with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
|
|
10
|
+
toString(): string;
|
|
11
|
+
arn: string;
|
|
12
|
+
};
|
|
13
|
+
} & (new (...args: any[]) => {
|
|
14
|
+
register(namespaces: import("@lafken/common").RegisterNamespaces | (string & {}), id: string): void;
|
|
15
|
+
onResolve(callback: () => void): void;
|
|
16
|
+
readonly node: import("constructs").Node;
|
|
17
|
+
with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
|
|
18
|
+
toString(): string;
|
|
19
|
+
}) & typeof DataAwsSqsQueue;
|
|
20
|
+
export declare class ExternalQueue extends ExternalQueue_base {
|
|
21
|
+
private props;
|
|
22
|
+
constructor(scope: AppModule, id: string, props: QueueProps);
|
|
23
|
+
private setName;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExternalQueue = void 0;
|
|
4
|
+
const data_aws_sqs_queue_1 = require("@cdktn/provider-aws/lib/data-aws-sqs-queue");
|
|
5
|
+
const resolver_1 = require("@lafken/resolver");
|
|
6
|
+
const base_1 = require("../base/base");
|
|
7
|
+
const queue_utils_1 = require("../queue.utils");
|
|
8
|
+
class ExternalQueue extends (0, base_1.QueueBase)(resolver_1.lafkenResource.make(data_aws_sqs_queue_1.DataAwsSqsQueue)) {
|
|
9
|
+
props;
|
|
10
|
+
constructor(scope, id, props) {
|
|
11
|
+
const { handler } = props;
|
|
12
|
+
super(scope, `${id}-queue`, {
|
|
13
|
+
name: '',
|
|
14
|
+
});
|
|
15
|
+
this.props = props;
|
|
16
|
+
this.setName();
|
|
17
|
+
if (handler.ref) {
|
|
18
|
+
this.register('queue', handler.ref);
|
|
19
|
+
}
|
|
20
|
+
this.validateEventParams(props);
|
|
21
|
+
this.addEventSource(id, props);
|
|
22
|
+
}
|
|
23
|
+
setName() {
|
|
24
|
+
const { handler } = this.props;
|
|
25
|
+
if (typeof handler.queueName === 'string') {
|
|
26
|
+
this.name = (0, queue_utils_1.sqsName)(handler.queueName, handler.isFifo ? '.fifo' : '');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const queueName = (0, resolver_1.resolveCallbackResource)(this, handler.queueName);
|
|
30
|
+
if (!queueName) {
|
|
31
|
+
this.onResolve(() => {
|
|
32
|
+
this.setName();
|
|
33
|
+
if (!this.name) {
|
|
34
|
+
throw new Error('Unresolved external queue name');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.name = queueName;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ExternalQueue = ExternalQueue;
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { SqsQueue } from '@cdktn/provider-aws/lib/sqs-queue';
|
|
2
2
|
import { type AppModule } from '@lafken/resolver';
|
|
3
|
-
import type { QueueProps } from '
|
|
4
|
-
declare const
|
|
3
|
+
import type { QueueProps } from '../queue.types';
|
|
4
|
+
declare const InternalQueue_base: {
|
|
5
|
+
new (...args: any[]): {
|
|
6
|
+
addEventSource(id: string, props: QueueProps): void;
|
|
7
|
+
validateEventParams(props: QueueProps): void;
|
|
8
|
+
readonly node: import("constructs").Node;
|
|
9
|
+
with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
|
|
10
|
+
toString(): string;
|
|
11
|
+
arn: string;
|
|
12
|
+
};
|
|
13
|
+
} & (new (...args: any[]) => {
|
|
5
14
|
register(namespaces: import("@lafken/common").RegisterNamespaces | (string & {}), id: string): void;
|
|
6
15
|
onResolve(callback: () => void): void;
|
|
7
16
|
readonly node: import("constructs").Node;
|
|
8
17
|
with(...mixins: import("constructs").IMixin[]): import("constructs").IConstruct;
|
|
9
18
|
toString(): string;
|
|
10
19
|
}) & typeof SqsQueue;
|
|
11
|
-
export declare class
|
|
20
|
+
export declare class InternalQueue extends InternalQueue_base {
|
|
12
21
|
private props;
|
|
13
22
|
constructor(scope: AppModule, id: string, props: QueueProps);
|
|
14
23
|
private addDeadLetterQueue;
|
|
15
|
-
private addEventSource;
|
|
16
|
-
private validateEventParams;
|
|
17
|
-
private getParams;
|
|
18
|
-
private validateParamType;
|
|
19
24
|
}
|
|
20
25
|
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InternalQueue = void 0;
|
|
4
|
+
const sqs_queue_1 = require("@cdktn/provider-aws/lib/sqs-queue");
|
|
5
|
+
const sqs_queue_redrive_policy_1 = require("@cdktn/provider-aws/lib/sqs-queue-redrive-policy");
|
|
6
|
+
const resolver_1 = require("@lafken/resolver");
|
|
7
|
+
const base_1 = require("../base/base");
|
|
8
|
+
const queue_utils_1 = require("../queue.utils");
|
|
9
|
+
class InternalQueue extends (0, base_1.QueueBase)(resolver_1.lafkenResource.make(sqs_queue_1.SqsQueue)) {
|
|
10
|
+
props;
|
|
11
|
+
constructor(scope, id, props) {
|
|
12
|
+
const { handler } = props;
|
|
13
|
+
super(scope, `${id}-queue`, {
|
|
14
|
+
name: (0, queue_utils_1.sqsName)(handler.queueName, handler.isFifo ? '.fifo' : ''),
|
|
15
|
+
fifoQueue: handler.isFifo,
|
|
16
|
+
contentBasedDeduplication: handler.contentBasedDeduplication,
|
|
17
|
+
visibilityTimeoutSeconds: handler.visibilityTimeout,
|
|
18
|
+
messageRetentionSeconds: handler.retentionPeriod,
|
|
19
|
+
maxMessageSize: handler.maxMessageSizeBytes,
|
|
20
|
+
delaySeconds: handler.deliveryDelay,
|
|
21
|
+
});
|
|
22
|
+
this.props = props;
|
|
23
|
+
if (handler.ref) {
|
|
24
|
+
this.register('queue', handler.ref);
|
|
25
|
+
}
|
|
26
|
+
this.addDeadLetterQueue(id);
|
|
27
|
+
this.validateEventParams(props);
|
|
28
|
+
this.addEventSource(id, props);
|
|
29
|
+
new resolver_1.ResourceOutput(this, handler.outputs);
|
|
30
|
+
}
|
|
31
|
+
addDeadLetterQueue(id) {
|
|
32
|
+
const { handler } = this.props;
|
|
33
|
+
if (!handler.dlq)
|
|
34
|
+
return;
|
|
35
|
+
const dlqName = (0, queue_utils_1.sqsName)(handler.queueName, `-dlq${handler.isFifo ? '.fifo' : ''}`);
|
|
36
|
+
const dlq = new sqs_queue_1.SqsQueue(this, `${id}-dlq`, {
|
|
37
|
+
name: dlqName,
|
|
38
|
+
fifoQueue: handler.isFifo,
|
|
39
|
+
messageRetentionSeconds: handler.dlq.retentionPeriod,
|
|
40
|
+
});
|
|
41
|
+
new sqs_queue_redrive_policy_1.SqsQueueRedrivePolicy(this, `${id}-redrive-policy`, {
|
|
42
|
+
queueUrl: this.url,
|
|
43
|
+
redrivePolicy: JSON.stringify({
|
|
44
|
+
deadLetterTargetArn: dlq.arn,
|
|
45
|
+
maxReceiveCount: handler.dlq.maxReceiveCount,
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.InternalQueue = InternalQueue;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { ClassResource, ResourceMetadata } from '@lafken/common';
|
|
2
2
|
import type { QueueLambdaMetadata } from '../../main';
|
|
3
|
-
export interface
|
|
3
|
+
export interface InternalQueueProps {
|
|
4
4
|
handler: QueueLambdaMetadata;
|
|
5
5
|
resourceMetadata: ResourceMetadata;
|
|
6
6
|
classResource: ClassResource;
|
|
7
7
|
}
|
|
8
|
+
export interface ExternalQueueProps {
|
|
9
|
+
handler: QueueLambdaMetadata;
|
|
10
|
+
resourceMetadata: ResourceMetadata;
|
|
11
|
+
classResource: ClassResource;
|
|
12
|
+
}
|
|
13
|
+
export type QueueProps = InternalQueueProps | ExternalQueueProps;
|
package/lib/resolver/resolver.js
CHANGED
|
@@ -4,7 +4,8 @@ exports.QueueResolver = void 0;
|
|
|
4
4
|
const common_1 = require("@lafken/common");
|
|
5
5
|
const resolver_1 = require("@lafken/resolver");
|
|
6
6
|
const main_1 = require("../main");
|
|
7
|
-
const
|
|
7
|
+
const external_1 = require("./queue/external/external");
|
|
8
|
+
const internal_1 = require("./queue/internal/internal");
|
|
8
9
|
class QueueResolver {
|
|
9
10
|
type = main_1.RESOURCE_TYPE;
|
|
10
11
|
create(module, resource) {
|
|
@@ -19,7 +20,15 @@ class QueueResolver {
|
|
|
19
20
|
methods: handlers.map((handler) => handler.name),
|
|
20
21
|
});
|
|
21
22
|
for (const handler of handlers) {
|
|
22
|
-
|
|
23
|
+
if (handler.isExternal) {
|
|
24
|
+
new external_1.ExternalQueue(module, `${metadata.name}-${handler.name}`, {
|
|
25
|
+
resourceMetadata: metadata,
|
|
26
|
+
classResource: resource,
|
|
27
|
+
handler,
|
|
28
|
+
});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
new internal_1.InternalQueue(module, `${metadata.name}-${handler.name}`, {
|
|
23
32
|
resourceMetadata: metadata,
|
|
24
33
|
classResource: resource,
|
|
25
34
|
handler,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lafken/queue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Define SQS queues and consumers using TypeScript decorators - automatic infrastructure generation with Lafken",
|
|
6
6
|
"keywords": [
|
|
@@ -52,30 +52,29 @@
|
|
|
52
52
|
"lib"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@aws-sdk/client-sqs": "^3.
|
|
56
|
-
"aws-lambda": "^1.0.7",
|
|
55
|
+
"@aws-sdk/client-sqs": "^3.1045.0",
|
|
57
56
|
"reflect-metadata": "^0.2.2",
|
|
58
|
-
"@lafken/resolver": "0.
|
|
57
|
+
"@lafken/resolver": "0.12.0"
|
|
59
58
|
},
|
|
60
59
|
"devDependencies": {
|
|
61
|
-
"@cdktn/provider-aws": "^
|
|
62
|
-
"@swc/core": "^1.15.
|
|
60
|
+
"@cdktn/provider-aws": "^24.0.0",
|
|
61
|
+
"@swc/core": "^1.15.33",
|
|
63
62
|
"@swc/helpers": "^0.5.21",
|
|
64
63
|
"@types/aws-lambda": "^8.10.161",
|
|
65
64
|
"@vitest/runner": "^4.1.5",
|
|
66
|
-
"cdktn": "^0.
|
|
65
|
+
"cdktn": "^0.23.0",
|
|
67
66
|
"cdktn-vitest": "^1.0.0",
|
|
68
67
|
"constructs": "^10.6.0",
|
|
69
68
|
"typescript": "6.0.3",
|
|
70
69
|
"unplugin-swc": "^1.5.9",
|
|
71
70
|
"vitest": "^4.1.5",
|
|
72
|
-
"@lafken/common": "0.
|
|
71
|
+
"@lafken/common": "0.12.0"
|
|
73
72
|
},
|
|
74
73
|
"peerDependencies": {
|
|
75
74
|
"@cdktn/provider-aws": ">=23.0.0",
|
|
76
75
|
"cdktn": ">=0.22.0",
|
|
77
76
|
"constructs": "^10.4.5",
|
|
78
|
-
"@lafken/common": "0.
|
|
77
|
+
"@lafken/common": "0.12.0"
|
|
79
78
|
},
|
|
80
79
|
"engines": {
|
|
81
80
|
"node": ">=20.19"
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Queue = void 0;
|
|
4
|
-
const lambda_event_source_mapping_1 = require("@cdktn/provider-aws/lib/lambda-event-source-mapping");
|
|
5
|
-
const sqs_queue_1 = require("@cdktn/provider-aws/lib/sqs-queue");
|
|
6
|
-
const sqs_queue_redrive_policy_1 = require("@cdktn/provider-aws/lib/sqs-queue-redrive-policy");
|
|
7
|
-
const common_1 = require("@lafken/common");
|
|
8
|
-
const resolver_1 = require("@lafken/resolver");
|
|
9
|
-
const queue_utils_1 = require("./queue.utils");
|
|
10
|
-
const attributeAllowedTypes = new Set(['String', 'Number']);
|
|
11
|
-
const bodyParsedTypes = new Set(['String', 'Object', 'Array']);
|
|
12
|
-
const bodyUnparsedTypes = new Set(['String']);
|
|
13
|
-
class Queue extends resolver_1.lafkenResource.make(sqs_queue_1.SqsQueue) {
|
|
14
|
-
props;
|
|
15
|
-
constructor(scope, id, props) {
|
|
16
|
-
const { handler } = props;
|
|
17
|
-
super(scope, `${id}-queue`, {
|
|
18
|
-
name: (0, queue_utils_1.sqsName)(handler.queueName, handler.isFifo ? '.fifo' : ''),
|
|
19
|
-
fifoQueue: handler.isFifo,
|
|
20
|
-
contentBasedDeduplication: handler.contentBasedDeduplication,
|
|
21
|
-
visibilityTimeoutSeconds: handler.visibilityTimeout,
|
|
22
|
-
messageRetentionSeconds: handler.retentionPeriod,
|
|
23
|
-
maxMessageSize: handler.maxMessageSizeBytes,
|
|
24
|
-
delaySeconds: handler.deliveryDelay,
|
|
25
|
-
});
|
|
26
|
-
this.props = props;
|
|
27
|
-
if (handler.ref) {
|
|
28
|
-
this.register('queue', handler.ref);
|
|
29
|
-
}
|
|
30
|
-
this.addDeadLetterQueue(id);
|
|
31
|
-
this.validateEventParams();
|
|
32
|
-
this.addEventSource(id);
|
|
33
|
-
new resolver_1.ResourceOutput(this, handler.outputs);
|
|
34
|
-
}
|
|
35
|
-
addDeadLetterQueue(id) {
|
|
36
|
-
const { handler } = this.props;
|
|
37
|
-
if (!handler.dlq)
|
|
38
|
-
return;
|
|
39
|
-
const dlqName = (0, queue_utils_1.sqsName)(handler.queueName, `-dlq${handler.isFifo ? '.fifo' : ''}`);
|
|
40
|
-
const dlq = new sqs_queue_1.SqsQueue(this, `${id}-dlq`, {
|
|
41
|
-
name: dlqName,
|
|
42
|
-
fifoQueue: handler.isFifo,
|
|
43
|
-
messageRetentionSeconds: handler.dlq.retentionPeriod,
|
|
44
|
-
});
|
|
45
|
-
new sqs_queue_redrive_policy_1.SqsQueueRedrivePolicy(this, `${id}-redrive-policy`, {
|
|
46
|
-
queueUrl: this.url,
|
|
47
|
-
redrivePolicy: JSON.stringify({
|
|
48
|
-
deadLetterTargetArn: dlq.arn,
|
|
49
|
-
maxReceiveCount: handler.dlq.maxReceiveCount,
|
|
50
|
-
}),
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
addEventSource(id) {
|
|
54
|
-
const { handler, resourceMetadata } = this.props;
|
|
55
|
-
const lambdaHandler = new resolver_1.LambdaHandler(this, `${id}-handler`, {
|
|
56
|
-
...handler,
|
|
57
|
-
originalName: resourceMetadata.originalName,
|
|
58
|
-
filename: resourceMetadata.filename,
|
|
59
|
-
foldername: resourceMetadata.foldername,
|
|
60
|
-
suffix: 'queue',
|
|
61
|
-
});
|
|
62
|
-
new lambda_event_source_mapping_1.LambdaEventSourceMapping(this, 'event-mapping', {
|
|
63
|
-
batchSize: handler.batchSize,
|
|
64
|
-
eventSourceArn: this.arn,
|
|
65
|
-
functionName: lambdaHandler.arn,
|
|
66
|
-
maximumBatchingWindowInSeconds: handler.maxBatchingWindow,
|
|
67
|
-
functionResponseTypes: handler.isFifo ? ['ReportBatchItemFailures'] : undefined,
|
|
68
|
-
scalingConfig: handler.maxConcurrency
|
|
69
|
-
? {
|
|
70
|
-
maximumConcurrency: handler.maxConcurrency,
|
|
71
|
-
}
|
|
72
|
-
: undefined,
|
|
73
|
-
dependsOn: [lambdaHandler, this],
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
validateEventParams() {
|
|
77
|
-
const param = this.getParams();
|
|
78
|
-
if (!param) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
let bodyCount = 0;
|
|
82
|
-
for (const property of param.properties) {
|
|
83
|
-
this.validateParamType(property);
|
|
84
|
-
if (property.source === 'body') {
|
|
85
|
-
bodyCount++;
|
|
86
|
-
}
|
|
87
|
-
if (bodyCount >= 2) {
|
|
88
|
-
throw new Error('Queue event only support one body param');
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
getParams() {
|
|
93
|
-
const { classResource, handler } = this.props;
|
|
94
|
-
const params = (0, common_1.getMetadataPrototypeByKey)(classResource, common_1.LambdaReflectKeys.event_param) || {};
|
|
95
|
-
return params[handler.name];
|
|
96
|
-
}
|
|
97
|
-
validateParamType(param) {
|
|
98
|
-
if (param.source === 'attribute' && !attributeAllowedTypes.has(param.type)) {
|
|
99
|
-
throw new Error(`Attribute params only support ${[...attributeAllowedTypes].join(', ')} values`);
|
|
100
|
-
}
|
|
101
|
-
if (param?.source === 'body' && !param.parse && !bodyUnparsedTypes.has(param.type)) {
|
|
102
|
-
throw new Error(`Body params only support ${[...bodyUnparsedTypes].join(', ')} values`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
exports.Queue = Queue;
|