use std::error::Error;
use std::fmt;
use async_trait::async_trait;
use rusoto_core::credential::ProvideAwsCredentials;
use rusoto_core::region;
use rusoto_core::request::{BufferedHttpResponse, DispatchSignedRequest};
use rusoto_core::{Client, RusotoError};
use rusoto_core::proto;
use rusoto_core::request::HttpResponse;
use rusoto_core::signature::SignedRequest;
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
impl QldbSessionClient {
fn new_signed_request(&self, http_method: &str, request_uri: &str) -> SignedRequest {
let mut request = SignedRequest::new(http_method, "qldb", &self.region, request_uri);
request.set_endpoint_prefix("session.qldb".to_string());
request.set_content_type("application/x-amz-json-1.0".to_owned());
request
}
async fn sign_and_dispatch<E>(
&self,
request: SignedRequest,
from_response: fn(BufferedHttpResponse) -> RusotoError<E>,
) -> Result<HttpResponse, RusotoError<E>> {
let mut response = self.client.sign_and_dispatch(request).await?;
if !response.status.is_success() {
let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
return Err(from_response(response));
}
Ok(response)
}
}
use serde_json;
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct AbortTransactionRequest {}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct AbortTransactionResult {
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct CommitTransactionRequest {
#[serde(rename = "CommitDigest")]
#[serde(
deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
default
)]
pub commit_digest: bytes::Bytes,
#[serde(rename = "TransactionId")]
pub transaction_id: String,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct CommitTransactionResult {
#[serde(rename = "CommitDigest")]
#[serde(
deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
default
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub commit_digest: Option<bytes::Bytes>,
#[serde(rename = "ConsumedIOs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub consumed_i_os: Option<IOUsage>,
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
#[serde(rename = "TransactionId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction_id: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct EndSessionRequest {}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct EndSessionResult {
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct ExecuteStatementRequest {
#[serde(rename = "Parameters")]
#[serde(skip_serializing_if = "Option::is_none")]
pub parameters: Option<Vec<ValueHolder>>,
#[serde(rename = "Statement")]
pub statement: String,
#[serde(rename = "TransactionId")]
pub transaction_id: String,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct ExecuteStatementResult {
#[serde(rename = "ConsumedIOs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub consumed_i_os: Option<IOUsage>,
#[serde(rename = "FirstPage")]
#[serde(skip_serializing_if = "Option::is_none")]
pub first_page: Option<Page>,
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct FetchPageRequest {
#[serde(rename = "NextPageToken")]
pub next_page_token: String,
#[serde(rename = "TransactionId")]
pub transaction_id: String,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct FetchPageResult {
#[serde(rename = "ConsumedIOs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub consumed_i_os: Option<IOUsage>,
#[serde(rename = "Page")]
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<Page>,
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct IOUsage {
#[serde(rename = "ReadIOs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub read_i_os: Option<i64>,
#[serde(rename = "WriteIOs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub write_i_os: Option<i64>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct Page {
#[serde(rename = "NextPageToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_page_token: Option<String>,
#[serde(rename = "Values")]
#[serde(skip_serializing_if = "Option::is_none")]
pub values: Option<Vec<ValueHolder>>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct SendCommandRequest {
#[serde(rename = "AbortTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub abort_transaction: Option<AbortTransactionRequest>,
#[serde(rename = "CommitTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub commit_transaction: Option<CommitTransactionRequest>,
#[serde(rename = "EndSession")]
#[serde(skip_serializing_if = "Option::is_none")]
pub end_session: Option<EndSessionRequest>,
#[serde(rename = "ExecuteStatement")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execute_statement: Option<ExecuteStatementRequest>,
#[serde(rename = "FetchPage")]
#[serde(skip_serializing_if = "Option::is_none")]
pub fetch_page: Option<FetchPageRequest>,
#[serde(rename = "SessionToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub session_token: Option<String>,
#[serde(rename = "StartSession")]
#[serde(skip_serializing_if = "Option::is_none")]
pub start_session: Option<StartSessionRequest>,
#[serde(rename = "StartTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub start_transaction: Option<StartTransactionRequest>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct SendCommandResult {
#[serde(rename = "AbortTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub abort_transaction: Option<AbortTransactionResult>,
#[serde(rename = "CommitTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub commit_transaction: Option<CommitTransactionResult>,
#[serde(rename = "EndSession")]
#[serde(skip_serializing_if = "Option::is_none")]
pub end_session: Option<EndSessionResult>,
#[serde(rename = "ExecuteStatement")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execute_statement: Option<ExecuteStatementResult>,
#[serde(rename = "FetchPage")]
#[serde(skip_serializing_if = "Option::is_none")]
pub fetch_page: Option<FetchPageResult>,
#[serde(rename = "StartSession")]
#[serde(skip_serializing_if = "Option::is_none")]
pub start_session: Option<StartSessionResult>,
#[serde(rename = "StartTransaction")]
#[serde(skip_serializing_if = "Option::is_none")]
pub start_transaction: Option<StartTransactionResult>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct StartSessionRequest {
#[serde(rename = "LedgerName")]
pub ledger_name: String,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct StartSessionResult {
#[serde(rename = "SessionToken")]
#[serde(skip_serializing_if = "Option::is_none")]
pub session_token: Option<String>,
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize)]
#[cfg_attr(feature = "deserialize_structs", derive(Deserialize))]
pub struct StartTransactionRequest {}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct StartTransactionResult {
#[serde(rename = "TimingInformation")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timing_information: Option<TimingInformation>,
#[serde(rename = "TransactionId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction_id: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[cfg_attr(any(test, feature = "serialize_structs"), derive(Serialize))]
pub struct TimingInformation {
#[serde(rename = "ProcessingTimeMilliseconds")]
#[serde(skip_serializing_if = "Option::is_none")]
pub processing_time_milliseconds: Option<i64>,
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct ValueHolder {
#[serde(rename = "IonBinary")]
#[serde(
deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
default
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub ion_binary: Option<bytes::Bytes>,
#[serde(rename = "IonText")]
#[serde(skip_serializing_if = "Option::is_none")]
pub ion_text: Option<String>,
}
#[derive(Debug, PartialEq)]
pub enum SendCommandError {
BadRequest(String),
InvalidSession(String),
LimitExceeded(String),
OccConflict(String),
RateExceeded(String),
}
impl SendCommandError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<SendCommandError> {
if let Some(err) = proto::json::Error::parse(&res) {
match err.typ.as_str() {
"BadRequestException" => {
return RusotoError::Service(SendCommandError::BadRequest(err.msg))
}
"InvalidSessionException" => {
return RusotoError::Service(SendCommandError::InvalidSession(err.msg))
}
"LimitExceededException" => {
return RusotoError::Service(SendCommandError::LimitExceeded(err.msg))
}
"OccConflictException" => {
return RusotoError::Service(SendCommandError::OccConflict(err.msg))
}
"RateExceededException" => {
return RusotoError::Service(SendCommandError::RateExceeded(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
RusotoError::Unknown(res)
}
}
impl fmt::Display for SendCommandError {
#[allow(unused_variables)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SendCommandError::BadRequest(ref cause) => write!(f, "{}", cause),
SendCommandError::InvalidSession(ref cause) => write!(f, "{}", cause),
SendCommandError::LimitExceeded(ref cause) => write!(f, "{}", cause),
SendCommandError::OccConflict(ref cause) => write!(f, "{}", cause),
SendCommandError::RateExceeded(ref cause) => write!(f, "{}", cause),
}
}
}
impl Error for SendCommandError {}
#[async_trait]
pub trait QldbSession {
async fn send_command(
&self,
input: SendCommandRequest,
) -> Result<SendCommandResult, RusotoError<SendCommandError>>;
}
#[derive(Clone)]
pub struct QldbSessionClient {
client: Client,
region: region::Region,
}
impl QldbSessionClient {
pub fn new(region: region::Region) -> QldbSessionClient {
QldbSessionClient {
client: Client::shared(),
region,
}
}
pub fn new_with<P, D>(
request_dispatcher: D,
credentials_provider: P,
region: region::Region,
) -> QldbSessionClient
where
P: ProvideAwsCredentials + Send + Sync + 'static,
D: DispatchSignedRequest + Send + Sync + 'static,
{
QldbSessionClient {
client: Client::new_with(credentials_provider, request_dispatcher),
region,
}
}
pub fn new_with_client(client: Client, region: region::Region) -> QldbSessionClient {
QldbSessionClient { client, region }
}
}
#[async_trait]
impl QldbSession for QldbSessionClient {
async fn send_command(
&self,
input: SendCommandRequest,
) -> Result<SendCommandResult, RusotoError<SendCommandError>> {
let mut request = self.new_signed_request("POST", "/");
request.add_header("x-amz-target", "QLDBSession.SendCommand");
let encoded = serde_json::to_string(&input).unwrap();
request.set_payload(Some(encoded));
let response = self
.sign_and_dispatch(request, SendCommandError::from_response)
.await?;
let mut response = response;
let response = response.buffer().await.map_err(RusotoError::HttpDispatch)?;
proto::json::ResponsePayload::new(&response).deserialize::<SendCommandResult, _>()
}
}