Skip to content

Commit 20fee58

Browse files
authored
chore(rust): enable wrapped client test vectors (#1648)
* chore(rust): enable wrapped client test vectors
1 parent 4f18689 commit 20fee58

File tree

7 files changed

+204
-4
lines changed

7 files changed

+204
-4
lines changed

.github/workflows/library_rust_tests.yml

+11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ jobs:
3434
env:
3535
RUST_MIN_STACK: 838860800
3636
steps:
37+
- name: Setup Docker
38+
if: matrix.os == 'macos-13' && matrix.library == 'TestVectors'
39+
uses: douglascamata/setup-docker-macos-action@v1-alpha
40+
41+
- name: Setup DynamoDB Local
42+
if: matrix.library == 'TestVectors'
43+
uses: rrainn/[email protected]
44+
with:
45+
port: 8000
46+
cors: "*"
47+
3748
- name: Support longpaths on Git checkout
3849
run: |
3950
git config --global core.longpaths true

TestVectors/Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ PROJECT_INDEX := \
6363
submodules/MaterialProviders/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore/src/Index.dfy \
6464
submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/src/Index.dfy \
6565
DynamoDbEncryption/dafny/StructuredEncryption/src/Index.dfy \
66+
DynamoDbEncryption/dafny/DynamoDbItemEncryptor/src/Index.dfy \
67+
DynamoDbEncryption/dafny/DynamoDbEncryptionTransforms/src/Index.dfy \
6668
DynamoDbEncryption/dafny/DynamoDbEncryption/src/Index.dfy \
6769

6870
STD_LIBRARY=submodules/MaterialProviders/StandardLibrary
@@ -77,8 +79,10 @@ SERVICE_DEPS_DDBEncryption := \
7779
submodules/MaterialProviders/ComAmazonawsDynamodb \
7880
submodules/MaterialProviders/AwsCryptographicMaterialProviders/dafny/AwsCryptographicMaterialProviders \
7981
submodules/MaterialProviders/AwsCryptographicMaterialProviders/dafny/AwsCryptographyKeyStore \
80-
DynamoDbEncryption/dafny/StructuredEncryption \
82+
DynamoDbEncryption/dafny/DynamoDbEncryptionTransforms \
8183
DynamoDbEncryption/dafny/DynamoDbEncryption \
84+
DynamoDbEncryption/dafny/DynamoDbItemEncryptor \
85+
DynamoDbEncryption/dafny/StructuredEncryption \
8286
submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/dafny/TestVectorsAwsCryptographicMaterialProviders \
8387

8488
transpile_implementation_rust: _remove_wrapped_client_rust

TestVectors/dafny/DDBEncryption/Model/AwsCryptographyDynamoDbEncryptionTypesWrapped.dfy

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
include "../../../../submodules/MaterialProviders/StandardLibrary/src/Index.dfy"
55
// BEGIN MANUAL EDIT
66
include "../../../../DynamoDbEncryption/dafny/DynamoDbEncryption/src/Index.dfy"
7+
include "../../../../DynamoDbEncryption/dafny/DynamoDbEncryptionTransforms/src/Index.dfy"
78
include "../../../../submodules/MaterialProviders/TestVectorsAwsCryptographicMaterialProviders/dafny/KeyVectors/src/Index.dfy"
89
// END MANUAL EDIT
910
abstract module WrappedAbstractAwsCryptographyDynamoDbEncryptionService {

TestVectors/runtimes/rust/SkipLocal.txt

-1
This file was deleted.

TestVectors/runtimes/rust/src/create_client.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::implementation_from_dafny::software::amazon::cryptography::services::
77
use crate::implementation_from_dafny::software::amazon::cryptography::dbencryptionsdk::dynamodb::internaldafny::types::Error;
88
use crate::implementation_from_dafny::_Wrappers_Compile;
99
use std::sync::LazyLock;
10-
// use crate::intercept::DbEsdkInterceptor;
10+
use crate::intercept::DbEsdkInterceptor;
1111

1212
static DAFNY_TOKIO_RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
1313
tokio::runtime::Builder::new_multi_thread()
@@ -24,6 +24,8 @@ impl _CreateInterceptedDDBClient_Compile::_default {
2424
pub fn CreateInterceptedDDBClient(config : &Rc<crate::implementation_from_dafny::software::amazon::cryptography::dbencryptionsdk::dynamodb::internaldafny::types::DynamoDbTablesEncryptionConfig>)
2525
-> Rc<_Wrappers_Compile::Result<Object<dyn IDynamoDBClient>, Rc<Error>>>
2626
{
27+
28+
let table_configs = crate::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_transforms::conversions::dynamo_db_tables_encryption_config::_dynamo_db_tables_encryption_config::plain_from_dafny(config);
2729
let shared_config = DAFNY_TOKIO_RUNTIME.block_on(aws_config::load_defaults(
2830
aws_config::BehaviorVersion::v2024_03_28()));
2931

@@ -33,7 +35,7 @@ impl _CreateInterceptedDDBClient_Compile::_default {
3335
.build();
3436

3537
let dynamo_config = aws_sdk_dynamodb::config::Builder::from(&shared_config)
36-
// .interceptor(DbEsdkInterceptor::new(table_configs))
38+
.interceptor(DbEsdkInterceptor::new(table_configs).unwrap())
3739
.build();
3840
let inner = aws_sdk_dynamodb::Client::from_conf(dynamo_config);
3941

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![deny(warnings, unconditional_panic)]
5+
#![deny(nonstandard_style)]
6+
#![deny(clippy::all)]
7+
#![allow(unused)]
8+
#![allow(clippy::result_large_err)]
9+
10+
use aws_sdk_dynamodb::{
11+
config::{
12+
interceptors::{BeforeSerializationInterceptorContextMut, FinalizerInterceptorContextMut},
13+
ConfigBag, Intercept, RuntimeComponents,
14+
},
15+
error::BoxError,
16+
};
17+
use aws_smithy_runtime_api::client::interceptors::context::Input;
18+
use aws_smithy_types::config_bag::{Storable, StoreReplace};
19+
20+
macro_rules! modify_request {
21+
($cfg:ident,$request:ident,$self:ident,$transform:ident) => {{
22+
// store the original request
23+
$cfg.interceptor_state()
24+
.store_put(OriginalRequest(Input::erase($request.clone())));
25+
26+
// transform the request
27+
let result = tokio::task::block_in_place(|| {
28+
tokio::runtime::Handle::current().block_on(async {
29+
$self
30+
.client
31+
.$transform()
32+
.sdk_input($request.clone())
33+
.send()
34+
.await
35+
})
36+
});
37+
match result {
38+
Ok(x) => *$request = x.transformed_input.unwrap(),
39+
Err(x) => {
40+
let s = format!("{:?}", x);
41+
return Err(s.into());
42+
}
43+
};
44+
}};
45+
}
46+
47+
macro_rules! modify_response {
48+
($cfg:ident,$type:ty,$response:ident,$self:ident,$transform:ident) => {{
49+
// retrieve the original request
50+
let original = $cfg
51+
.load::<OriginalRequest>()
52+
.expect("we put this in ourselves");
53+
let original = original
54+
.0
55+
.downcast_ref::<$type>()
56+
.expect("we know this type corresponds to the output type");
57+
58+
// transform the response
59+
let result = tokio::task::block_in_place(|| {
60+
tokio::runtime::Handle::current().block_on(async {
61+
$self
62+
.client
63+
.$transform()
64+
.original_input(original.clone())
65+
.sdk_output($response.clone())
66+
.send()
67+
.await
68+
})
69+
});
70+
match result {
71+
Ok(x) => *$response = x.transformed_output.unwrap(),
72+
Err(x) => {
73+
let s = format!("{:?}", x);
74+
return Err(s.into());
75+
}
76+
};
77+
}};
78+
}
79+
80+
type TClient = crate::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_transforms::client::Client;
81+
82+
#[derive(Debug)]
83+
pub struct DbEsdkInterceptor {
84+
client: TClient,
85+
}
86+
87+
impl DbEsdkInterceptor {
88+
pub fn new(
89+
config: crate::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_transforms::types::DynamoDbTablesEncryptionConfig,
90+
) -> Result<Self, crate::deps::aws_cryptography_dbEncryptionSdk_dynamoDb_transforms::types::error::Error> {
91+
let client = TClient::from_conf(config)?;
92+
Ok(DbEsdkInterceptor { client })
93+
}
94+
}
95+
96+
#[derive(Debug)]
97+
struct OriginalRequest(Input);
98+
99+
impl Storable for OriginalRequest {
100+
type Storer = StoreReplace<Self>;
101+
}
102+
103+
impl Intercept for DbEsdkInterceptor {
104+
fn name(&self) -> &'static str {
105+
"DbEsdkInterceptor"
106+
}
107+
108+
fn modify_before_serialization(
109+
&self,
110+
// https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/interceptors/context/struct.BeforeSerializationInterceptorContextMut.html
111+
context: &mut BeforeSerializationInterceptorContextMut,
112+
_rc: &RuntimeComponents,
113+
cfg: &mut ConfigBag,
114+
) -> Result<(), BoxError> {
115+
if let Some(batch_execute_statement_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::batch_execute_statement::BatchExecuteStatementInput>() {
116+
modify_request!(cfg, batch_execute_statement_request, self, batch_execute_statement_input_transform);
117+
} else if let Some(batch_get_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::batch_get_item::BatchGetItemInput>() {
118+
modify_request!(cfg, batch_get_item_request, self, batch_get_item_input_transform);
119+
} else if let Some(batch_write_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::batch_write_item::BatchWriteItemInput>() {
120+
modify_request!(cfg, batch_write_item_request, self, batch_write_item_input_transform);
121+
} else if let Some(delete_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::delete_item::DeleteItemInput>() {
122+
modify_request!(cfg, delete_item_request, self, delete_item_input_transform);
123+
} else if let Some(execute_statement_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::execute_statement::ExecuteStatementInput>() {
124+
modify_request!(cfg, execute_statement_request, self, execute_statement_input_transform);
125+
} else if let Some(execute_transaction_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::execute_transaction::ExecuteTransactionInput>() {
126+
modify_request!(cfg, execute_transaction_request, self, execute_transaction_input_transform);
127+
} else if let Some(get_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::get_item::GetItemInput>() {
128+
modify_request!(cfg, get_item_request, self, get_item_input_transform);
129+
} else if let Some(put_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::put_item::PutItemInput>() {
130+
modify_request!(cfg, put_item_request, self, put_item_input_transform);
131+
} else if let Some(query_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::query::QueryInput>() {
132+
modify_request!(cfg, query_request, self, query_input_transform);
133+
} else if let Some(scan_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::scan::ScanInput>() {
134+
modify_request!(cfg, scan_request, self, scan_input_transform);
135+
} else if let Some(transact_get_items_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::transact_get_items::TransactGetItemsInput>() {
136+
modify_request!(cfg, transact_get_items_request, self, transact_get_items_input_transform);
137+
} else if let Some(transact_write_items_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::transact_write_items::TransactWriteItemsInput>() {
138+
modify_request!(cfg, transact_write_items_request, self, transact_write_items_input_transform);
139+
} else if let Some(update_item_request) = context.input_mut().downcast_mut::<aws_sdk_dynamodb::operation::update_item::UpdateItemInput>() {
140+
modify_request!(cfg, update_item_request, self, update_item_input_transform);
141+
}
142+
Ok(())
143+
}
144+
145+
fn modify_before_attempt_completion(
146+
&self,
147+
context: &mut FinalizerInterceptorContextMut,
148+
_rc: &RuntimeComponents,
149+
cfg: &mut ConfigBag,
150+
) -> Result<(), BoxError> {
151+
if let Some(Ok(output)) = context.output_or_error_mut() {
152+
if let Some(batch_execute_statement_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::batch_execute_statement::BatchExecuteStatementOutput>() {
153+
modify_response!(cfg, aws_sdk_dynamodb::operation::batch_execute_statement::BatchExecuteStatementInput, batch_execute_statement_response, self, batch_execute_statement_output_transform);
154+
} else if let Some(batch_get_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::batch_get_item::BatchGetItemOutput>() {
155+
modify_response!(cfg, aws_sdk_dynamodb::operation::batch_get_item::BatchGetItemInput, batch_get_item_response, self, batch_get_item_output_transform);
156+
} else if let Some(batch_write_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::batch_write_item::BatchWriteItemOutput>() {
157+
modify_response!(cfg, aws_sdk_dynamodb::operation::batch_write_item::BatchWriteItemInput, batch_write_item_response, self, batch_write_item_output_transform);
158+
} else if let Some(delete_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::delete_item::DeleteItemOutput>() {
159+
modify_response!(cfg, aws_sdk_dynamodb::operation::delete_item::DeleteItemInput, delete_item_response, self, delete_item_output_transform);
160+
} else if let Some(execute_statement_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::execute_statement::ExecuteStatementOutput>() {
161+
modify_response!(cfg, aws_sdk_dynamodb::operation::execute_statement::ExecuteStatementInput, execute_statement_response, self, execute_statement_output_transform);
162+
} else if let Some(execute_transaction_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::execute_transaction::ExecuteTransactionOutput>() {
163+
modify_response!(cfg, aws_sdk_dynamodb::operation::execute_transaction::ExecuteTransactionInput, execute_transaction_response, self, execute_transaction_output_transform);
164+
} else if let Some(get_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::get_item::GetItemOutput>() {
165+
modify_response!(cfg, aws_sdk_dynamodb::operation::get_item::GetItemInput, get_item_response, self, get_item_output_transform);
166+
} else if let Some(put_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::put_item::PutItemOutput>() {
167+
modify_response!(cfg, aws_sdk_dynamodb::operation::put_item::PutItemInput, put_item_response, self, put_item_output_transform);
168+
} else if let Some(query_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::query::QueryOutput>() {
169+
modify_response!(cfg, aws_sdk_dynamodb::operation::query::QueryInput, query_response, self, query_output_transform);
170+
} else if let Some(scan_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::scan::ScanOutput>() {
171+
modify_response!(cfg, aws_sdk_dynamodb::operation::scan::ScanInput, scan_response, self, scan_output_transform);
172+
} else if let Some(transact_get_items_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::transact_get_items::TransactGetItemsOutput>() {
173+
modify_response!(cfg, aws_sdk_dynamodb::operation::transact_get_items::TransactGetItemsInput, transact_get_items_response, self, transact_get_items_output_transform);
174+
} else if let Some(transact_write_items_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::transact_write_items::TransactWriteItemsOutput>() {
175+
modify_response!(cfg, aws_sdk_dynamodb::operation::transact_write_items::TransactWriteItemsInput, transact_write_items_response, self, transact_write_items_output_transform);
176+
} else if let Some(update_item_response) = output.downcast_mut::<aws_sdk_dynamodb::operation::update_item::UpdateItemOutput>() {
177+
modify_response!(cfg, aws_sdk_dynamodb::operation::update_item::UpdateItemInput, update_item_response, self, update_item_output_transform);
178+
}
179+
}
180+
Ok(())
181+
}
182+
}

TestVectors/runtimes/rust/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub mod error;
1313
pub mod operation;
1414
pub mod types;
1515
pub mod validation;
16+
pub mod intercept;
1617

1718
#[cfg(feature = "wrapped-client")]
1819
pub mod wrapped;

0 commit comments

Comments
 (0)