1+ using Amazon . CDK ;
2+ using Amazon . CDK . AWS . DynamoDB ;
3+ using Amazon . CDK . AWS . SQS ;
4+ using Amazon . CDK . AWS . Kinesis ;
5+ using Amazon . CDK . AWS . Lambda ;
6+ using Amazon . CDK . AWS . Lambda . EventSources ;
7+ using Constructs ;
8+ using Attribute = Amazon . CDK . AWS . DynamoDB . Attribute ;
9+ using Stream = Amazon . CDK . AWS . Kinesis . Stream ;
10+
11+ namespace InfraShared ;
12+
13+ public class BatchProcessingStackProps : PowertoolsDefaultStackProps
14+ {
15+ // Any specific properties for batch processing
16+ }
17+
18+ public class BatchProcessingStack : Stack
19+ {
20+ public Table DynamoDbTable { get ; set ; }
21+ public Queue StandardQueue { get ; set ; }
22+ public Queue FifoQueue { get ; set ; }
23+ public Stream KinesisStream { get ; set ; }
24+
25+ public BatchProcessingStack ( Construct scope , string id , BatchProcessingStackProps props ) : base ( scope , id , props )
26+ {
27+ // DynamoDB table with streams enabled
28+ DynamoDbTable = new Table ( this , "BatchProcessingTable" , new TableProps
29+ {
30+ PartitionKey = new Attribute
31+ {
32+ Name = "id" ,
33+ Type = AttributeType . STRING
34+ } ,
35+ TableName = "BatchProcessingTable" ,
36+ BillingMode = BillingMode . PAY_PER_REQUEST ,
37+ RemovalPolicy = RemovalPolicy . DESTROY ,
38+ Stream = StreamViewType . NEW_AND_OLD_IMAGES
39+ } ) ;
40+
41+ // SQS Queues
42+ StandardQueue = new Queue ( this , "BatchProcessingStandardQueue" , new QueueProps
43+ {
44+ QueueName = "BatchProcessingStandardQueue" ,
45+ RemovalPolicy = RemovalPolicy . DESTROY
46+ } ) ;
47+
48+ FifoQueue = new Queue ( this , "BatchProcessingFifoQueue" , new QueueProps
49+ {
50+ QueueName = "BatchProcessingFifoQueue.fifo" ,
51+ Fifo = true ,
52+ RemovalPolicy = RemovalPolicy . DESTROY
53+ } ) ;
54+
55+ // Kinesis Data Stream
56+ KinesisStream = new Stream ( this , "BatchProcessingKinesisStream" , new StreamProps
57+ {
58+ StreamName = "BatchProcessingKinesisStream" ,
59+ ShardCount = 1 ,
60+ RemovalPolicy = RemovalPolicy . DESTROY
61+ } ) ;
62+
63+ var utility = "batchprocessing" ;
64+
65+ if ( props . IsAot )
66+ {
67+ CreateAotFunctions ( this , utility , props ) ;
68+ }
69+ else
70+ {
71+ CreateRegularFunctions ( this , utility , props ) ;
72+ }
73+ }
74+
75+ private void CreateAotFunctions ( Construct scope , string utility , BatchProcessingStackProps props )
76+ {
77+ var sources = new [ ] { "DynamoDB" , "SQS" , "Kinesis" } ;
78+
79+ foreach ( var source in sources )
80+ {
81+ var baseAotPath = $ "../functions/{ utility } /AOT-Function/src/AOT-Function{ source } ";
82+ var distAotPath = $ "../functions/{ utility } /AOT-Function/dist/AOT-Function{ source } ";
83+ var path = new Path ( baseAotPath , distAotPath ) ;
84+ props . Handler = $ "AOT-Function{ source } ";
85+
86+ var architecture = props . ArchitectureString == "arm64" ? Architecture . ARM_64 : Architecture . X86_64 ;
87+ var arch = architecture == Architecture . X86_64 ? "X64" : "ARM" ;
88+
89+ var lambdaFunction = CreateFunctionConstruct (
90+ scope ,
91+ $ "{ utility } _{ arch } _aot_net8__{ source } ",
92+ Runtime . DOTNET_8 ,
93+ architecture ,
94+ $ "E2ETestLambda_{ arch } _AOT_NET8_{ utility } _{ source } ",
95+ path ,
96+ props
97+ ) ;
98+
99+ ConfigureEventSource ( lambdaFunction , source ) ;
100+ }
101+ }
102+
103+ private void CreateRegularFunctions ( Construct scope , string utility , BatchProcessingStackProps props )
104+ {
105+ var sources = new [ ] { "DynamoDB" , "SQS" , "Kinesis" } ;
106+
107+ foreach ( var source in sources )
108+ {
109+ var basePath = $ "../functions/{ utility } /Function/src/Function{ source } ";
110+ var distPath = $ "../functions/{ utility } /Function/dist/Function{ source } ";
111+ var path = new Path ( basePath , distPath ) ;
112+ props . Handler = $ "Function{ source } ::Function{ source } .Function::FunctionHandler";
113+
114+ // Create Lambda functions for different runtimes and architectures
115+ var runtimes = new [ ] {
116+ ( runtime : Runtime . DOTNET_8 , arch : Architecture . X86_64 , archStr : "X64" , runtimeStr : "NET8" ) ,
117+ ( runtime : Runtime . DOTNET_8 , arch : Architecture . ARM_64 , archStr : "ARM" , runtimeStr : "NET8" ) ,
118+ ( runtime : Runtime . DOTNET_6 , arch : Architecture . X86_64 , archStr : "X64" , runtimeStr : "NET6" ) ,
119+ ( runtime : Runtime . DOTNET_6 , arch : Architecture . ARM_64 , archStr : "ARM" , runtimeStr : "NET6" )
120+ } ;
121+
122+ foreach ( var ( runtime , arch , archStr , runtimeStr ) in runtimes )
123+ {
124+ var lambdaFunction = CreateFunctionConstruct (
125+ scope ,
126+ $ "{ utility } _{ archStr } _{ runtimeStr } _{ source } ",
127+ runtime ,
128+ arch ,
129+ $ "E2ETestLambda_{ archStr } _{ runtimeStr } _{ utility } _{ source } ",
130+ path ,
131+ props
132+ ) ;
133+
134+ ConfigureEventSource ( lambdaFunction , source ) ;
135+ }
136+ }
137+ }
138+
139+ private FunctionConstruct CreateFunctionConstruct ( Construct scope , string id , Runtime runtime , Architecture architecture ,
140+ string name , Path path , PowertoolsDefaultStackProps props )
141+ {
142+ var lambdaFunction = new FunctionConstruct ( scope , id , new FunctionConstructProps
143+ {
144+ Runtime = runtime ,
145+ Architecture = architecture ,
146+ Name = name ,
147+ Handler = props . Handler ! ,
148+ SourcePath = path . SourcePath ,
149+ DistPath = path . DistPath ,
150+ Environment = new Dictionary < string , string >
151+ {
152+ { "BATCH_PROCESSING_TABLE_NAME" , DynamoDbTable . TableName } ,
153+ { "BATCH_PROCESSING_STANDARD_QUEUE_URL" , StandardQueue . QueueUrl } ,
154+ { "BATCH_PROCESSING_FIFO_QUEUE_URL" , FifoQueue . QueueUrl } ,
155+ { "BATCH_PROCESSING_KINESIS_STREAM_NAME" , KinesisStream . StreamName }
156+ } ,
157+ IsAot = props . IsAot
158+ } ) ;
159+
160+ return lambdaFunction ;
161+ }
162+
163+ private void ConfigureEventSource ( FunctionConstruct lambdaFunction , string source )
164+ {
165+ switch ( source )
166+ {
167+ case "DynamoDB" :
168+ lambdaFunction . Function . AddEventSource ( new DynamoEventSource ( DynamoDbTable , new DynamoEventSourceProps
169+ {
170+ StartingPosition = StartingPosition . LATEST ,
171+ BatchSize = 10 ,
172+ RetryAttempts = 3
173+ } ) ) ;
174+ break ;
175+
176+ case "SQS" :
177+ lambdaFunction . Function . AddEventSource ( new SqsEventSource ( StandardQueue , new SqsEventSourceProps
178+ {
179+ BatchSize = 10 ,
180+ MaxBatchingWindow = Duration . Seconds ( 5 )
181+ } ) ) ;
182+
183+ // Add permissions for FIFO queue too
184+ FifoQueue . GrantConsumeMessages ( lambdaFunction . Function ) ;
185+ break ;
186+
187+ case "Kinesis" :
188+ lambdaFunction . Function . AddEventSource ( new KinesisEventSource ( KinesisStream , new KinesisEventSourceProps
189+ {
190+ StartingPosition = StartingPosition . LATEST ,
191+ BatchSize = 10 ,
192+ RetryAttempts = 3 ,
193+ MaxBatchingWindow = Duration . Seconds ( 5 )
194+ } ) ) ;
195+ break ;
196+ }
197+ }
198+ }
0 commit comments