@@ -3493,6 +3493,167 @@ async fn range_explicit_encryption_defaults() -> Result<()> {
3493
3493
Ok ( ( ) )
3494
3494
}
3495
3495
3496
+ // Prose Test 24. KMS Retry Tests
3497
+ #[ tokio:: test]
3498
+ // using openssl causes errors after configuring a network failpoint
3499
+ #[ cfg( not( feature = "openssl-tls" ) ) ]
3500
+ async fn kms_retry ( ) {
3501
+ use reqwest:: { Certificate , Client as HttpClient } ;
3502
+
3503
+ let endpoint = "127.0.0.1:9003" ;
3504
+
3505
+ let mut certificate_file_path = PathBuf :: from ( std:: env:: var ( "CSFLE_TLS_CERT_DIR" ) . unwrap ( ) ) ;
3506
+ certificate_file_path. push ( "ca.pem" ) ;
3507
+ let certificate_file = std:: fs:: read ( & certificate_file_path) . unwrap ( ) ;
3508
+
3509
+ let set_failpoint = |kind : & str , count : u8 | {
3510
+ // create a fresh client for each request to avoid hangs
3511
+ let http_client = HttpClient :: builder ( )
3512
+ . add_root_certificate ( Certificate :: from_pem ( & certificate_file) . unwrap ( ) )
3513
+ . build ( )
3514
+ . unwrap ( ) ;
3515
+ let url = format ! ( "https://localhost:9003/set_failpoint/{}" , kind) ;
3516
+ let body = format ! ( "{{\" count\" :{}}}" , count) ;
3517
+ http_client. post ( url) . body ( body) . send ( )
3518
+ } ;
3519
+
3520
+ let aws_kms = AWS_KMS . clone ( ) ;
3521
+ let mut azure_kms = AZURE_KMS . clone ( ) ;
3522
+ azure_kms. 1 . insert ( "identityPlatformEndpoint" , endpoint) ;
3523
+ let mut gcp_kms = GCP_KMS . clone ( ) ;
3524
+ gcp_kms. 1 . insert ( "endpoint" , endpoint) ;
3525
+ let mut kms_providers = vec ! [ aws_kms, azure_kms, gcp_kms] ;
3526
+
3527
+ let tls_options = get_client_options ( ) . await . tls_options ( ) ;
3528
+ for kms_provider in kms_providers. iter_mut ( ) {
3529
+ kms_provider. 2 = tls_options. clone ( ) ;
3530
+ }
3531
+
3532
+ let key_vault_client = Client :: for_test ( ) . await . into_client ( ) ;
3533
+ let client_encryption = ClientEncryption :: new (
3534
+ key_vault_client,
3535
+ Namespace :: new ( "keyvault" , "datakeys" ) ,
3536
+ kms_providers,
3537
+ )
3538
+ . unwrap ( ) ;
3539
+
3540
+ let aws_master_key = AwsMasterKey :: builder ( )
3541
+ . region ( "foo" )
3542
+ . key ( "bar" )
3543
+ . endpoint ( endpoint. to_string ( ) )
3544
+ . build ( ) ;
3545
+ let azure_master_key = AzureMasterKey :: builder ( )
3546
+ . key_vault_endpoint ( endpoint)
3547
+ . key_name ( "foo" )
3548
+ . build ( ) ;
3549
+ let gcp_master_key = GcpMasterKey :: builder ( )
3550
+ . project_id ( "foo" )
3551
+ . location ( "bar" )
3552
+ . key_ring ( "baz" )
3553
+ . key_name ( "qux" )
3554
+ . endpoint ( endpoint. to_string ( ) )
3555
+ . build ( ) ;
3556
+
3557
+ // Case 1: createDataKey and encrypt with TCP retry
3558
+
3559
+ // AWS
3560
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3561
+ let key_id = client_encryption
3562
+ . create_data_key ( aws_master_key. clone ( ) )
3563
+ . await
3564
+ . unwrap ( ) ;
3565
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3566
+ client_encryption
3567
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3568
+ . await
3569
+ . unwrap ( ) ;
3570
+
3571
+ // Azure
3572
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3573
+ let key_id = client_encryption
3574
+ . create_data_key ( azure_master_key. clone ( ) )
3575
+ . await
3576
+ . unwrap ( ) ;
3577
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3578
+ client_encryption
3579
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3580
+ . await
3581
+ . unwrap ( ) ;
3582
+
3583
+ // GCP
3584
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3585
+ let key_id = client_encryption
3586
+ . create_data_key ( gcp_master_key. clone ( ) )
3587
+ . await
3588
+ . unwrap ( ) ;
3589
+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3590
+ client_encryption
3591
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3592
+ . await
3593
+ . unwrap ( ) ;
3594
+
3595
+ // Case 2: createDataKey and encrypt with HTTP retry
3596
+
3597
+ // AWS
3598
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3599
+ let key_id = client_encryption
3600
+ . create_data_key ( aws_master_key. clone ( ) )
3601
+ . await
3602
+ . unwrap ( ) ;
3603
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3604
+ client_encryption
3605
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3606
+ . await
3607
+ . unwrap ( ) ;
3608
+
3609
+ // Azure
3610
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3611
+ let key_id = client_encryption
3612
+ . create_data_key ( azure_master_key. clone ( ) )
3613
+ . await
3614
+ . unwrap ( ) ;
3615
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3616
+ client_encryption
3617
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3618
+ . await
3619
+ . unwrap ( ) ;
3620
+
3621
+ // GCP
3622
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3623
+ let key_id = client_encryption
3624
+ . create_data_key ( gcp_master_key. clone ( ) )
3625
+ . await
3626
+ . unwrap ( ) ;
3627
+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3628
+ client_encryption
3629
+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3630
+ . await
3631
+ . unwrap ( ) ;
3632
+
3633
+ // Case 3: createDataKey fails after too many retries
3634
+
3635
+ // AWS
3636
+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3637
+ client_encryption
3638
+ . create_data_key ( aws_master_key)
3639
+ . await
3640
+ . unwrap_err ( ) ;
3641
+
3642
+ // Azure
3643
+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3644
+ client_encryption
3645
+ . create_data_key ( azure_master_key)
3646
+ . await
3647
+ . unwrap_err ( ) ;
3648
+
3649
+ // GCP
3650
+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3651
+ client_encryption
3652
+ . create_data_key ( gcp_master_key)
3653
+ . await
3654
+ . unwrap_err ( ) ;
3655
+ }
3656
+
3496
3657
// FLE 2.0 Documentation Example
3497
3658
#[ tokio:: test]
3498
3659
async fn fle2_example ( ) -> Result < ( ) > {
0 commit comments