1use chrono::{DateTime, Utc};
2use parking_lot::RwLock;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct LambdaFunction {
9 pub function_name: String,
10 pub function_arn: String,
11 pub runtime: String,
12 pub role: String,
13 pub handler: String,
14 pub description: String,
15 pub timeout: i64,
16 pub memory_size: i64,
17 pub code_sha256: String,
18 pub code_size: i64,
19 pub version: String,
20 pub last_modified: DateTime<Utc>,
21 pub tags: HashMap<String, String>,
22 pub environment: HashMap<String, String>,
23 pub architectures: Vec<String>,
24 pub package_type: String,
25 pub code_zip: Option<Vec<u8>>,
26 #[serde(default)]
30 pub image_uri: Option<String>,
31 pub policy: Option<String>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct EventSourceMapping {
44 pub uuid: String,
45 pub function_arn: String,
46 pub event_source_arn: String,
47 pub batch_size: i64,
48 pub enabled: bool,
49 pub state: String,
50 pub last_modified: DateTime<Utc>,
51 #[serde(default)]
56 pub filter_patterns: Vec<String>,
57 #[serde(default)]
60 pub maximum_batching_window_in_seconds: Option<i64>,
61 #[serde(default)]
64 pub starting_position: Option<String>,
65 #[serde(default)]
68 pub starting_position_timestamp: Option<f64>,
69 #[serde(default)]
71 pub parallelization_factor: Option<i64>,
72 #[serde(default)]
75 pub function_response_types: Vec<String>,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct LambdaInvocation {
81 pub function_arn: String,
82 pub payload: String,
83 pub timestamp: DateTime<Utc>,
84 pub source: String,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct LambdaState {
89 pub account_id: String,
90 pub region: String,
91 #[serde(default)]
92 pub functions: HashMap<String, LambdaFunction>,
93 #[serde(default)]
94 pub event_source_mappings: HashMap<String, EventSourceMapping>,
95 #[serde(default, skip)]
97 pub invocations: Vec<LambdaInvocation>,
98 #[serde(default)]
100 pub aliases: HashMap<String, FunctionAlias>,
101 #[serde(default)]
103 pub function_versions: HashMap<String, Vec<String>>,
104 #[serde(default)]
106 pub layers: HashMap<String, Layer>,
107 #[serde(default)]
109 pub function_url_configs: HashMap<String, FunctionUrlConfig>,
110 #[serde(default)]
112 pub function_concurrency: HashMap<String, i64>,
113 #[serde(default)]
115 pub provisioned_concurrency: HashMap<String, ProvisionedConcurrencyConfig>,
116 #[serde(default)]
118 pub code_signing_configs: HashMap<String, CodeSigningConfig>,
119 #[serde(default)]
121 pub function_code_signing: HashMap<String, String>,
122 #[serde(default)]
124 pub event_invoke_configs: HashMap<String, EventInvokeConfig>,
125 #[serde(default)]
127 pub runtime_management: HashMap<String, RuntimeManagementConfig>,
128 #[serde(default)]
130 pub scaling_configs: HashMap<String, FunctionScalingConfig>,
131 #[serde(default)]
133 pub recursion_configs: HashMap<String, String>,
134 #[serde(default)]
136 pub tags: HashMap<String, Vec<(String, String)>>,
137 #[serde(default)]
139 pub capacity_providers: HashMap<String, CapacityProvider>,
140 #[serde(default)]
142 pub durable_executions: HashMap<String, DurableExecution>,
143 #[serde(default)]
145 pub account_settings: Option<AccountSettings>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct FunctionAlias {
150 pub alias_arn: String,
151 pub name: String,
152 pub function_version: String,
153 pub description: String,
154 pub revision_id: String,
155 pub routing_config: Option<serde_json::Value>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct Layer {
160 pub layer_name: String,
161 pub layer_arn: String,
162 pub versions: Vec<LayerVersion>,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct LayerVersion {
167 pub version: i64,
168 pub layer_version_arn: String,
169 pub description: String,
170 pub created_date: DateTime<Utc>,
171 pub compatible_runtimes: Vec<String>,
172 pub license_info: String,
173 pub policy: Option<String>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct FunctionUrlConfig {
178 pub function_arn: String,
179 pub function_url: String,
180 pub auth_type: String,
181 pub cors: Option<serde_json::Value>,
182 pub creation_time: DateTime<Utc>,
183 pub last_modified_time: DateTime<Utc>,
184 pub invoke_mode: String,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct ProvisionedConcurrencyConfig {
189 pub requested: i64,
190 pub allocated: i64,
191 pub status: String,
192 pub last_modified: DateTime<Utc>,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct CodeSigningConfig {
197 pub csc_id: String,
198 pub csc_arn: String,
199 pub description: String,
200 pub allowed_publishers: Vec<String>,
201 pub untrusted_artifact_action: String,
202 pub last_modified: DateTime<Utc>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct EventInvokeConfig {
207 pub function_arn: String,
208 pub maximum_event_age: i64,
209 pub maximum_retry_attempts: i64,
210 pub destination_config: serde_json::Value,
211 pub last_modified: DateTime<Utc>,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct RuntimeManagementConfig {
216 pub update_runtime_on: String,
217 pub runtime_version_arn: String,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct FunctionScalingConfig {
222 pub maximum_concurrency: i64,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct CapacityProvider {
227 pub name: String,
228 pub arn: String,
229 pub status: String,
230 pub created: DateTime<Utc>,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct DurableExecution {
235 pub id: String,
236 pub function_arn: String,
237 pub status: String,
238 pub started: DateTime<Utc>,
239 pub stopped: Option<DateTime<Utc>>,
240 pub history: Vec<serde_json::Value>,
241 pub state: serde_json::Value,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize, Default)]
245pub struct AccountSettings {
246 pub concurrent_executions: i64,
247 pub code_size_zipped: i64,
248 pub code_size_unzipped: i64,
249 pub total_code_size: i64,
250}
251
252impl LambdaState {
253 pub fn new(account_id: &str, region: &str) -> Self {
254 Self {
255 account_id: account_id.to_string(),
256 region: region.to_string(),
257 functions: HashMap::new(),
258 event_source_mappings: HashMap::new(),
259 invocations: Vec::new(),
260 aliases: HashMap::new(),
261 function_versions: HashMap::new(),
262 layers: HashMap::new(),
263 function_url_configs: HashMap::new(),
264 function_concurrency: HashMap::new(),
265 provisioned_concurrency: HashMap::new(),
266 code_signing_configs: HashMap::new(),
267 function_code_signing: HashMap::new(),
268 event_invoke_configs: HashMap::new(),
269 runtime_management: HashMap::new(),
270 scaling_configs: HashMap::new(),
271 recursion_configs: HashMap::new(),
272 tags: HashMap::new(),
273 capacity_providers: HashMap::new(),
274 durable_executions: HashMap::new(),
275 account_settings: None,
276 }
277 }
278
279 pub fn reset(&mut self) {
280 self.functions.clear();
281 self.event_source_mappings.clear();
282 self.invocations.clear();
283 self.aliases.clear();
284 self.function_versions.clear();
285 self.layers.clear();
286 self.function_url_configs.clear();
287 self.function_concurrency.clear();
288 self.provisioned_concurrency.clear();
289 self.code_signing_configs.clear();
290 self.function_code_signing.clear();
291 self.event_invoke_configs.clear();
292 self.runtime_management.clear();
293 self.scaling_configs.clear();
294 self.recursion_configs.clear();
295 self.tags.clear();
296 self.capacity_providers.clear();
297 self.durable_executions.clear();
298 self.account_settings = None;
299 }
300}
301
302pub type SharedLambdaState =
303 Arc<RwLock<fakecloud_core::multi_account::MultiAccountState<LambdaState>>>;
304
305impl fakecloud_core::multi_account::AccountState for LambdaState {
306 fn new_for_account(account_id: &str, region: &str, _endpoint: &str) -> Self {
307 Self::new(account_id, region)
308 }
309}
310
311pub const LAMBDA_SNAPSHOT_SCHEMA_VERSION: u32 = 2;
312
313#[derive(Debug, Serialize, Deserialize)]
314pub struct LambdaSnapshot {
315 pub schema_version: u32,
316 #[serde(default)]
317 pub accounts: Option<fakecloud_core::multi_account::MultiAccountState<LambdaState>>,
318 #[serde(default)]
319 pub state: Option<LambdaState>,
320}
321
322#[cfg(test)]
323mod tests {
324 use super::*;
325
326 #[test]
327 fn new_has_empty_collections() {
328 let state = LambdaState::new("123456789012", "us-east-1");
329 assert_eq!(state.account_id, "123456789012");
330 assert_eq!(state.region, "us-east-1");
331 assert!(state.functions.is_empty());
332 assert!(state.event_source_mappings.is_empty());
333 assert!(state.invocations.is_empty());
334 }
335
336 #[test]
337 fn reset_clears_collections() {
338 let mut state = LambdaState::new("123456789012", "us-east-1");
339 state.invocations.push(LambdaInvocation {
340 function_arn: "arn".to_string(),
341 payload: "p".to_string(),
342 timestamp: Utc::now(),
343 source: "s".to_string(),
344 });
345 state.reset();
346 assert!(state.invocations.is_empty());
347 }
348}