fakecloud-appconfig 0.40.1

AWS AppConfig (appconfig + appconfigdata) implementation for FakeCloud
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
//! Model-derived input validation for AWS AppConfig.
//!
//! AWS rejects requests that violate the Smithy model's top-level constraints
//! (`@required`, `@length`, `@range`, `@enum`) with `BadRequestException`
//! before the operation runs. This module encodes those constraints per
//! operation so out-of-range / omitted / bad-enum inputs are rejected exactly
//! as the real service does. The rule table is generated from
//! `aws-models/appconfig.json`.

use http::StatusCode;
use serde_json::Value;

use fakecloud_core::service::{AwsRequest, AwsServiceError};

/// Where a constrained input member is bound on the wire.
#[derive(Clone, Copy)]
pub enum Src {
    Body,
    Query,
    Label,
}

/// A single input-constraint rule from the Smithy model.
pub enum Rule {
    Required(&'static str, Src),
    LenMin(&'static str, Src, usize),
    LenMax(&'static str, Src, usize),
    RangeMin(&'static str, Src, f64),
    RangeMax(&'static str, Src, f64),
    Enum(&'static str, Src, &'static [&'static str]),
}

fn bad(msg: impl Into<String>) -> AwsServiceError {
    AwsServiceError::aws_error(StatusCode::BAD_REQUEST, "BadRequestException", msg)
}

/// Length of a value for `@length` checks: strings by char count, lists by
/// element count, maps by entry count.
fn value_len(v: &Value) -> Option<usize> {
    match v {
        Value::String(s) => Some(s.chars().count()),
        Value::Array(a) => Some(a.len()),
        Value::Object(o) => Some(o.len()),
        _ => None,
    }
}

fn as_f64(v: &Value) -> Option<f64> {
    v.as_f64()
        .or_else(|| v.as_str().and_then(|s| s.parse().ok()))
}

/// Validate an operation's input against the model constraints. `labels` are
/// the decoded path labels in URI order (see `label_fields`).
pub fn validate(action: &str, labels: &[String], req: &AwsRequest) -> Result<(), AwsServiceError> {
    let rules = input_rules(action);
    if rules.is_empty() {
        return Ok(());
    }
    let body: Value = serde_json::from_slice(&req.body).unwrap_or(Value::Null);
    let lf = label_fields(action);
    let raw = |field: &str, src: Src| -> Option<Value> {
        match src {
            Src::Body => body.get(field).cloned().filter(|v| !v.is_null()),
            Src::Query => req
                .query_params
                .get(field)
                .map(|s| Value::String(s.clone())),
            Src::Label => lf
                .iter()
                .position(|f| *f == field)
                .and_then(|i| labels.get(i))
                .map(|s| Value::String(s.clone())),
        }
    };
    for rule in rules {
        match rule {
            Rule::Required(f, src) => {
                let missing = match raw(f, src) {
                    None => true,
                    // An omitted path label reaches us as the literal
                    // `{Field}` placeholder or an empty segment.
                    Some(Value::String(s)) => {
                        s.is_empty() || (s.starts_with('{') && s.ends_with('}'))
                    }
                    Some(_) => false,
                };
                if missing {
                    return Err(bad(format!("{f} is required.")));
                }
            }
            Rule::LenMin(f, src, n) => {
                if let Some(len) = raw(f, src).as_ref().and_then(value_len) {
                    if len < n {
                        return Err(bad(format!("{f} is shorter than the minimum length.")));
                    }
                }
            }
            Rule::LenMax(f, src, n) => {
                if let Some(len) = raw(f, src).as_ref().and_then(value_len) {
                    if len > n {
                        return Err(bad(format!("{f} exceeds the maximum length.")));
                    }
                }
            }
            Rule::RangeMin(f, src, n) => {
                if let Some(x) = raw(f, src).as_ref().and_then(as_f64) {
                    if x < n {
                        return Err(bad(format!("{f} is below the minimum value.")));
                    }
                }
            }
            Rule::RangeMax(f, src, n) => {
                if let Some(x) = raw(f, src).as_ref().and_then(as_f64) {
                    if x > n {
                        return Err(bad(format!("{f} exceeds the maximum value.")));
                    }
                }
            }
            Rule::Enum(f, src, vals) => {
                if let Some(Value::String(s)) = raw(f, src) {
                    if !vals.contains(&s.as_str()) {
                        return Err(bad(format!("{f} is not a valid value.")));
                    }
                }
            }
        }
    }
    Ok(())
}

/// Path-label field names in URI order for each operation, so `Src::Label`
/// rules can resolve their value from the positional `labels` slice.
fn label_fields(action: &str) -> &'static [&'static str] {
    match action {
        "CreateConfigurationProfile" => &["ApplicationId"],
        "CreateEnvironment" => &["ApplicationId"],
        "CreateExperimentDefinition" => &["ApplicationIdentifier"],
        "CreateHostedConfigurationVersion" => &["ApplicationId", "ConfigurationProfileId"],
        "DeleteApplication" => &["ApplicationId"],
        "DeleteConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
        "DeleteDeploymentStrategy" => &["DeploymentStrategyId"],
        "DeleteEnvironment" => &["ApplicationId", "EnvironmentId"],
        "DeleteExperimentDefinition" => {
            &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"]
        }
        "DeleteExtension" => &["ExtensionIdentifier"],
        "DeleteExtensionAssociation" => &["ExtensionAssociationId"],
        "DeleteHostedConfigurationVersion" => {
            &["ApplicationId", "ConfigurationProfileId", "VersionNumber"]
        }
        "GetApplication" => &["ApplicationId"],
        "GetConfiguration" => &["Application", "Environment", "Configuration"],
        "GetConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
        "GetDeployment" => &["ApplicationId", "EnvironmentId", "DeploymentNumber"],
        "GetDeploymentStrategy" => &["DeploymentStrategyId"],
        "GetEnvironment" => &["ApplicationId", "EnvironmentId"],
        "GetExperimentDefinition" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
        "GetExperimentRun" => &[
            "ApplicationIdentifier",
            "ExperimentDefinitionIdentifier",
            "Run",
        ],
        "GetExtension" => &["ExtensionIdentifier"],
        "GetExtensionAssociation" => &["ExtensionAssociationId"],
        "GetHostedConfigurationVersion" => {
            &["ApplicationId", "ConfigurationProfileId", "VersionNumber"]
        }
        "ListConfigurationProfiles" => &["ApplicationId"],
        "ListDeployments" => &["ApplicationId", "EnvironmentId"],
        "ListEnvironments" => &["ApplicationId"],
        "ListExperimentRunEvents" => &[
            "ApplicationIdentifier",
            "ExperimentDefinitionIdentifier",
            "Run",
        ],
        "ListExperimentRuns" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
        "ListHostedConfigurationVersions" => &["ApplicationId", "ConfigurationProfileId"],
        "ListTagsForResource" => &["ResourceArn"],
        "StartDeployment" => &["ApplicationId", "EnvironmentId"],
        "StartExperimentRun" => &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"],
        "StopDeployment" => &["ApplicationId", "EnvironmentId", "DeploymentNumber"],
        "StopExperimentRun" => &[
            "ApplicationIdentifier",
            "ExperimentDefinitionIdentifier",
            "Run",
        ],
        "TagResource" => &["ResourceArn"],
        "UntagResource" => &["ResourceArn"],
        "UpdateApplication" => &["ApplicationId"],
        "UpdateConfigurationProfile" => &["ApplicationId", "ConfigurationProfileId"],
        "UpdateDeploymentStrategy" => &["DeploymentStrategyId"],
        "UpdateEnvironment" => &["ApplicationId", "EnvironmentId"],
        "UpdateExperimentDefinition" => {
            &["ApplicationIdentifier", "ExperimentDefinitionIdentifier"]
        }
        "UpdateExperimentRun" => &[
            "ApplicationIdentifier",
            "ExperimentDefinitionIdentifier",
            "Run",
        ],
        "UpdateExtension" => &["ExtensionIdentifier"],
        "UpdateExtensionAssociation" => &["ExtensionAssociationId"],
        "ValidateConfiguration" => &["ApplicationId", "ConfigurationProfileId"],
        _ => &[],
    }
}

/// Model-derived constraint rules per operation.
#[allow(clippy::too_many_lines)]
fn input_rules(action: &str) -> Vec<Rule> {
    match action {
        "CreateApplication" => vec![
            Rule::Required("Name", Src::Body),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 64),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateConfigurationProfile" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("Name", Src::Body),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 128),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::Required("LocationUri", Src::Body),
            Rule::LenMin("LocationUri", Src::Body, 1),
            Rule::LenMax("LocationUri", Src::Body, 2048),
            Rule::LenMin("RetrievalRoleArn", Src::Body, 20),
            Rule::LenMax("RetrievalRoleArn", Src::Body, 2048),
            Rule::LenMin("Validators", Src::Body, 0),
            Rule::LenMax("Validators", Src::Body, 2),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
            Rule::LenMin("KmsKeyIdentifier", Src::Body, 1),
            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
        ],
        "CreateDeploymentStrategy" => vec![
            Rule::Required("Name", Src::Body),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 64),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::Required("DeploymentDurationInMinutes", Src::Body),
            Rule::RangeMin("DeploymentDurationInMinutes", Src::Body, 0.0),
            Rule::RangeMax("DeploymentDurationInMinutes", Src::Body, 1440.0),
            Rule::RangeMin("FinalBakeTimeInMinutes", Src::Body, 0.0),
            Rule::RangeMax("FinalBakeTimeInMinutes", Src::Body, 1440.0),
            Rule::Required("GrowthFactor", Src::Body),
            Rule::RangeMin("GrowthFactor", Src::Body, 1.0),
            Rule::RangeMax("GrowthFactor", Src::Body, 100.0),
            Rule::Enum("GrowthType", Src::Body, &["LINEAR", "EXPONENTIAL"]),
            Rule::Enum("ReplicateTo", Src::Body, &["NONE", "SSM_DOCUMENT"]),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateEnvironment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("Name", Src::Body),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 64),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("Monitors", Src::Body, 0),
            Rule::LenMax("Monitors", Src::Body, 5),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateExperimentDefinition" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("Name", Src::Body),
            Rule::Required("ConfigurationProfileIdentifier", Src::Body),
            Rule::LenMin("ConfigurationProfileIdentifier", Src::Body, 1),
            Rule::LenMax("ConfigurationProfileIdentifier", Src::Body, 2048),
            Rule::Required("EnvironmentIdentifier", Src::Body),
            Rule::LenMin("EnvironmentIdentifier", Src::Body, 1),
            Rule::LenMax("EnvironmentIdentifier", Src::Body, 2048),
            Rule::Required("FlagKey", Src::Body),
            Rule::Required("Treatments", Src::Body),
            Rule::LenMin("Treatments", Src::Body, 1),
            Rule::LenMax("Treatments", Src::Body, 5),
            Rule::Required("Control", Src::Body),
            Rule::Required("AudienceRule", Src::Body),
            Rule::LenMin("AudienceRule", Src::Body, 1),
            Rule::LenMax("AudienceRule", Src::Body, 16384),
            Rule::LenMin("Hypothesis", Src::Body, 0),
            Rule::LenMax("Hypothesis", Src::Body, 1024),
            Rule::LenMin("AudienceDescription", Src::Body, 0),
            Rule::LenMax("AudienceDescription", Src::Body, 1024),
            Rule::LenMin("LaunchCriteria", Src::Body, 0),
            Rule::LenMax("LaunchCriteria", Src::Body, 1024),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateExtension" => vec![
            Rule::Required("Name", Src::Body),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::Required("Actions", Src::Body),
            Rule::LenMin("Actions", Src::Body, 1),
            Rule::LenMax("Actions", Src::Body, 5),
            Rule::LenMin("Parameters", Src::Body, 1),
            Rule::LenMax("Parameters", Src::Body, 10),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateExtensionAssociation" => vec![
            Rule::Required("ExtensionIdentifier", Src::Body),
            Rule::LenMin("ExtensionIdentifier", Src::Body, 1),
            Rule::LenMax("ExtensionIdentifier", Src::Body, 2048),
            Rule::Required("ResourceIdentifier", Src::Body),
            Rule::LenMin("ResourceIdentifier", Src::Body, 1),
            Rule::LenMax("ResourceIdentifier", Src::Body, 2048),
            Rule::LenMin("Parameters", Src::Body, 0),
            Rule::LenMax("Parameters", Src::Body, 10),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "CreateHostedConfigurationVersion" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
        ],
        "DeleteApplication" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
        ],
        "DeleteConfigurationProfile" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
        ],
        "DeleteDeploymentStrategy" => vec![Rule::Required("DeploymentStrategyId", Src::Label)],
        "DeleteEnvironment" => vec![
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
        ],
        "DeleteExperimentDefinition" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::Enum("delete_type", Src::Query, &["ARCHIVE", "DESTROY"]),
        ],
        "DeleteExtension" => vec![
            Rule::Required("ExtensionIdentifier", Src::Label),
            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
        ],
        "DeleteExtensionAssociation" => vec![Rule::Required("ExtensionAssociationId", Src::Label)],
        "DeleteHostedConfigurationVersion" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
            Rule::Required("VersionNumber", Src::Label),
        ],
        "GetApplication" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
        ],
        "GetConfiguration" => vec![
            Rule::Required("Application", Src::Label),
            Rule::LenMin("Application", Src::Label, 1),
            Rule::LenMax("Application", Src::Label, 64),
            Rule::Required("Environment", Src::Label),
            Rule::LenMin("Environment", Src::Label, 1),
            Rule::LenMax("Environment", Src::Label, 64),
            Rule::Required("Configuration", Src::Label),
            Rule::LenMin("Configuration", Src::Label, 1),
            Rule::LenMax("Configuration", Src::Label, 64),
            Rule::Required("client_id", Src::Query),
            Rule::LenMin("client_id", Src::Query, 1),
            Rule::LenMax("client_id", Src::Query, 64),
            Rule::LenMin("client_configuration_version", Src::Query, 1),
            Rule::LenMax("client_configuration_version", Src::Query, 1024),
        ],
        "GetConfigurationProfile" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
        ],
        "GetDeployment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::Required("DeploymentNumber", Src::Label),
        ],
        "GetDeploymentStrategy" => vec![Rule::Required("DeploymentStrategyId", Src::Label)],
        "GetEnvironment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
        ],
        "GetExperimentDefinition" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
        ],
        "GetExperimentRun" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::Required("Run", Src::Label),
            Rule::RangeMin("Run", Src::Label, 1.0),
        ],
        "GetExtension" => vec![
            Rule::Required("ExtensionIdentifier", Src::Label),
            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
        ],
        "GetExtensionAssociation" => vec![Rule::Required("ExtensionAssociationId", Src::Label)],
        "GetHostedConfigurationVersion" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
            Rule::Required("VersionNumber", Src::Label),
        ],
        "ListApplications" => vec![
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListConfigurationProfiles" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListDeploymentStrategies" => vec![
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListDeployments" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListEnvironments" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListExperimentDefinitions" => vec![
            Rule::LenMin("application_identifier", Src::Query, 1),
            Rule::LenMax("application_identifier", Src::Query, 2048),
            Rule::LenMin("configuration_profile_identifier", Src::Query, 1),
            Rule::LenMax("configuration_profile_identifier", Src::Query, 2048),
            Rule::LenMin("environment_identifier", Src::Query, 1),
            Rule::LenMax("environment_identifier", Src::Query, 2048),
            Rule::Enum("status", Src::Query, &["ACTIVE", "IDLE", "ARCHIVED"]),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListExperimentRunEvents" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::Required("Run", Src::Label),
            Rule::RangeMin("Run", Src::Label, 1.0),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListExperimentRuns" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
            Rule::Enum("status", Src::Query, &["RUNNING", "DONE"]),
        ],
        "ListExtensionAssociations" => vec![
            Rule::LenMin("resource_identifier", Src::Query, 20),
            Rule::LenMax("resource_identifier", Src::Query, 2048),
            Rule::LenMin("extension_identifier", Src::Query, 1),
            Rule::LenMax("extension_identifier", Src::Query, 2048),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
        ],
        "ListExtensions" => vec![
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
            Rule::LenMin("name", Src::Query, 1),
            Rule::LenMax("name", Src::Query, 64),
        ],
        "ListHostedConfigurationVersions" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
            Rule::RangeMin("max_results", Src::Query, 1.0),
            Rule::RangeMax("max_results", Src::Query, 50.0),
            Rule::LenMin("next_token", Src::Query, 1),
            Rule::LenMax("next_token", Src::Query, 2048),
            Rule::LenMin("version_label", Src::Query, 1),
            Rule::LenMax("version_label", Src::Query, 64),
        ],
        "ListTagsForResource" => vec![
            Rule::Required("ResourceArn", Src::Label),
            Rule::LenMin("ResourceArn", Src::Label, 20),
            Rule::LenMax("ResourceArn", Src::Label, 2048),
        ],
        "StartDeployment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::Required("DeploymentStrategyId", Src::Body),
            Rule::Required("ConfigurationProfileId", Src::Body),
            Rule::LenMin("ConfigurationProfileId", Src::Body, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Body, 128),
            Rule::Required("ConfigurationVersion", Src::Body),
            Rule::LenMin("ConfigurationVersion", Src::Body, 1),
            Rule::LenMax("ConfigurationVersion", Src::Body, 1024),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
            Rule::LenMin("KmsKeyIdentifier", Src::Body, 1),
            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
            Rule::LenMin("DynamicExtensionParameters", Src::Body, 1),
            Rule::LenMax("DynamicExtensionParameters", Src::Body, 10),
        ],
        "StartExperimentRun" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::RangeMin("ExposurePercentage", Src::Body, 0.0),
            Rule::RangeMax("ExposurePercentage", Src::Body, 100.0),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "StopDeployment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::Required("DeploymentNumber", Src::Label),
        ],
        "StopExperimentRun" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::Required("Run", Src::Label),
            Rule::RangeMin("Run", Src::Label, 1.0),
        ],
        "TagResource" => vec![
            Rule::Required("ResourceArn", Src::Label),
            Rule::LenMin("ResourceArn", Src::Label, 20),
            Rule::LenMax("ResourceArn", Src::Label, 2048),
            Rule::Required("Tags", Src::Body),
            Rule::LenMin("Tags", Src::Body, 0),
            Rule::LenMax("Tags", Src::Body, 50),
        ],
        "UntagResource" => vec![
            Rule::Required("ResourceArn", Src::Label),
            Rule::LenMin("ResourceArn", Src::Label, 20),
            Rule::LenMax("ResourceArn", Src::Label, 2048),
            Rule::Required("tagKeys", Src::Query),
            Rule::LenMin("tagKeys", Src::Query, 0),
            Rule::LenMax("tagKeys", Src::Query, 50),
        ],
        "UpdateApplication" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 64),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
        ],
        "UpdateConfigurationProfile" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 128),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("RetrievalRoleArn", Src::Body, 20),
            Rule::LenMax("RetrievalRoleArn", Src::Body, 2048),
            Rule::LenMin("Validators", Src::Body, 0),
            Rule::LenMax("Validators", Src::Body, 2),
            Rule::LenMin("KmsKeyIdentifier", Src::Body, 0),
            Rule::LenMax("KmsKeyIdentifier", Src::Body, 2048),
        ],
        "UpdateDeploymentStrategy" => vec![
            Rule::Required("DeploymentStrategyId", Src::Label),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::RangeMin("DeploymentDurationInMinutes", Src::Body, 0.0),
            Rule::RangeMax("DeploymentDurationInMinutes", Src::Body, 1440.0),
            Rule::RangeMin("FinalBakeTimeInMinutes", Src::Body, 0.0),
            Rule::RangeMax("FinalBakeTimeInMinutes", Src::Body, 1440.0),
            Rule::RangeMin("GrowthFactor", Src::Body, 1.0),
            Rule::RangeMax("GrowthFactor", Src::Body, 100.0),
            Rule::Enum("GrowthType", Src::Body, &["LINEAR", "EXPONENTIAL"]),
        ],
        "UpdateEnvironment" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("EnvironmentId", Src::Label),
            Rule::LenMin("EnvironmentId", Src::Label, 1),
            Rule::LenMax("EnvironmentId", Src::Label, 64),
            Rule::LenMin("Name", Src::Body, 1),
            Rule::LenMax("Name", Src::Body, 64),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("Monitors", Src::Body, 0),
            Rule::LenMax("Monitors", Src::Body, 5),
        ],
        "UpdateExperimentDefinition" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::LenMin("Treatments", Src::Body, 1),
            Rule::LenMax("Treatments", Src::Body, 5),
            Rule::LenMin("Hypothesis", Src::Body, 0),
            Rule::LenMax("Hypothesis", Src::Body, 1024),
            Rule::LenMin("AudienceRule", Src::Body, 1),
            Rule::LenMax("AudienceRule", Src::Body, 16384),
            Rule::LenMin("AudienceDescription", Src::Body, 0),
            Rule::LenMax("AudienceDescription", Src::Body, 1024),
            Rule::LenMin("LaunchCriteria", Src::Body, 0),
            Rule::LenMax("LaunchCriteria", Src::Body, 1024),
        ],
        "UpdateExperimentRun" => vec![
            Rule::Required("ApplicationIdentifier", Src::Label),
            Rule::LenMin("ApplicationIdentifier", Src::Label, 1),
            Rule::LenMax("ApplicationIdentifier", Src::Label, 2048),
            Rule::Required("ExperimentDefinitionIdentifier", Src::Label),
            Rule::LenMin("ExperimentDefinitionIdentifier", Src::Label, 1),
            Rule::LenMax("ExperimentDefinitionIdentifier", Src::Label, 2048),
            Rule::Required("Run", Src::Label),
            Rule::RangeMin("Run", Src::Label, 1.0),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::RangeMin("ExposurePercentage", Src::Body, 0.0),
            Rule::RangeMax("ExposurePercentage", Src::Body, 100.0),
        ],
        "UpdateExtension" => vec![
            Rule::Required("ExtensionIdentifier", Src::Label),
            Rule::LenMin("ExtensionIdentifier", Src::Label, 1),
            Rule::LenMax("ExtensionIdentifier", Src::Label, 2048),
            Rule::LenMin("Description", Src::Body, 0),
            Rule::LenMax("Description", Src::Body, 1024),
            Rule::LenMin("Actions", Src::Body, 1),
            Rule::LenMax("Actions", Src::Body, 5),
            Rule::LenMin("Parameters", Src::Body, 1),
            Rule::LenMax("Parameters", Src::Body, 10),
        ],
        "UpdateExtensionAssociation" => vec![
            Rule::Required("ExtensionAssociationId", Src::Label),
            Rule::LenMin("Parameters", Src::Body, 0),
            Rule::LenMax("Parameters", Src::Body, 10),
        ],
        "ValidateConfiguration" => vec![
            Rule::Required("ApplicationId", Src::Label),
            Rule::LenMin("ApplicationId", Src::Label, 1),
            Rule::LenMax("ApplicationId", Src::Label, 64),
            Rule::Required("ConfigurationProfileId", Src::Label),
            Rule::LenMin("ConfigurationProfileId", Src::Label, 1),
            Rule::LenMax("ConfigurationProfileId", Src::Label, 128),
            Rule::Required("configuration_version", Src::Query),
            Rule::LenMin("configuration_version", Src::Query, 1),
            Rule::LenMax("configuration_version", Src::Query, 1024),
        ],
        _ => vec![],
    }
}