use std::error::Error;
use std::fmt;
#[allow(warnings)]
use futures::future;
use futures::Future;
use rusoto_core::credential::ProvideAwsCredentials;
use rusoto_core::region;
use rusoto_core::request::{BufferedHttpResponse, DispatchSignedRequest};
use rusoto_core::{Client, RusotoError, RusotoFuture};
use rusoto_core::param::{Params, ServiceParams};
use rusoto_core::proto;
use rusoto_core::signature::SignedRequest;
use serde_json;
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct DescribeJobExecutionRequest {
#[serde(rename = "executionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution_number: Option<i64>,
#[serde(rename = "includeJobDocument")]
#[serde(skip_serializing_if = "Option::is_none")]
pub include_job_document: Option<bool>,
#[serde(rename = "jobId")]
pub job_id: String,
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct DescribeJobExecutionResponse {
#[serde(rename = "execution")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution: Option<JobExecution>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct GetPendingJobExecutionsRequest {
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct GetPendingJobExecutionsResponse {
#[serde(rename = "inProgressJobs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub in_progress_jobs: Option<Vec<JobExecutionSummary>>,
#[serde(rename = "queuedJobs")]
#[serde(skip_serializing_if = "Option::is_none")]
pub queued_jobs: Option<Vec<JobExecutionSummary>>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct JobExecution {
#[serde(rename = "approximateSecondsBeforeTimedOut")]
#[serde(skip_serializing_if = "Option::is_none")]
pub approximate_seconds_before_timed_out: Option<i64>,
#[serde(rename = "executionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution_number: Option<i64>,
#[serde(rename = "jobDocument")]
#[serde(skip_serializing_if = "Option::is_none")]
pub job_document: Option<String>,
#[serde(rename = "jobId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub job_id: Option<String>,
#[serde(rename = "lastUpdatedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub last_updated_at: Option<i64>,
#[serde(rename = "queuedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub queued_at: Option<i64>,
#[serde(rename = "startedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub started_at: Option<i64>,
#[serde(rename = "status")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(rename = "statusDetails")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status_details: Option<::std::collections::HashMap<String, String>>,
#[serde(rename = "thingName")]
#[serde(skip_serializing_if = "Option::is_none")]
pub thing_name: Option<String>,
#[serde(rename = "versionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub version_number: Option<i64>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct JobExecutionState {
#[serde(rename = "status")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(rename = "statusDetails")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status_details: Option<::std::collections::HashMap<String, String>>,
#[serde(rename = "versionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub version_number: Option<i64>,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct JobExecutionSummary {
#[serde(rename = "executionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution_number: Option<i64>,
#[serde(rename = "jobId")]
#[serde(skip_serializing_if = "Option::is_none")]
pub job_id: Option<String>,
#[serde(rename = "lastUpdatedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub last_updated_at: Option<i64>,
#[serde(rename = "queuedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub queued_at: Option<i64>,
#[serde(rename = "startedAt")]
#[serde(skip_serializing_if = "Option::is_none")]
pub started_at: Option<i64>,
#[serde(rename = "versionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub version_number: Option<i64>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct StartNextPendingJobExecutionRequest {
#[serde(rename = "statusDetails")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status_details: Option<::std::collections::HashMap<String, String>>,
#[serde(rename = "stepTimeoutInMinutes")]
#[serde(skip_serializing_if = "Option::is_none")]
pub step_timeout_in_minutes: Option<i64>,
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct StartNextPendingJobExecutionResponse {
#[serde(rename = "execution")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution: Option<JobExecution>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct UpdateJobExecutionRequest {
#[serde(rename = "executionNumber")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution_number: Option<i64>,
#[serde(rename = "expectedVersion")]
#[serde(skip_serializing_if = "Option::is_none")]
pub expected_version: Option<i64>,
#[serde(rename = "includeJobDocument")]
#[serde(skip_serializing_if = "Option::is_none")]
pub include_job_document: Option<bool>,
#[serde(rename = "includeJobExecutionState")]
#[serde(skip_serializing_if = "Option::is_none")]
pub include_job_execution_state: Option<bool>,
#[serde(rename = "jobId")]
pub job_id: String,
#[serde(rename = "status")]
pub status: String,
#[serde(rename = "statusDetails")]
#[serde(skip_serializing_if = "Option::is_none")]
pub status_details: Option<::std::collections::HashMap<String, String>>,
#[serde(rename = "stepTimeoutInMinutes")]
#[serde(skip_serializing_if = "Option::is_none")]
pub step_timeout_in_minutes: Option<i64>,
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct UpdateJobExecutionResponse {
#[serde(rename = "executionState")]
#[serde(skip_serializing_if = "Option::is_none")]
pub execution_state: Option<JobExecutionState>,
#[serde(rename = "jobDocument")]
#[serde(skip_serializing_if = "Option::is_none")]
pub job_document: Option<String>,
}
#[derive(Debug, PartialEq)]
pub enum DescribeJobExecutionError {
CertificateValidation(String),
InvalidRequest(String),
ResourceNotFound(String),
ServiceUnavailable(String),
TerminalState(String),
Throttling(String),
}
impl DescribeJobExecutionError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<DescribeJobExecutionError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"CertificateValidationException" => {
return RusotoError::Service(DescribeJobExecutionError::CertificateValidation(
err.msg,
))
}
"InvalidRequestException" => {
return RusotoError::Service(DescribeJobExecutionError::InvalidRequest(err.msg))
}
"ResourceNotFoundException" => {
return RusotoError::Service(DescribeJobExecutionError::ResourceNotFound(
err.msg,
))
}
"ServiceUnavailableException" => {
return RusotoError::Service(DescribeJobExecutionError::ServiceUnavailable(
err.msg,
))
}
"TerminalStateException" => {
return RusotoError::Service(DescribeJobExecutionError::TerminalState(err.msg))
}
"ThrottlingException" => {
return RusotoError::Service(DescribeJobExecutionError::Throttling(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for DescribeJobExecutionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for DescribeJobExecutionError {
fn description(&self) -> &str {
match *self {
DescribeJobExecutionError::CertificateValidation(ref cause) => cause,
DescribeJobExecutionError::InvalidRequest(ref cause) => cause,
DescribeJobExecutionError::ResourceNotFound(ref cause) => cause,
DescribeJobExecutionError::ServiceUnavailable(ref cause) => cause,
DescribeJobExecutionError::TerminalState(ref cause) => cause,
DescribeJobExecutionError::Throttling(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum GetPendingJobExecutionsError {
CertificateValidation(String),
InvalidRequest(String),
ResourceNotFound(String),
ServiceUnavailable(String),
Throttling(String),
}
impl GetPendingJobExecutionsError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<GetPendingJobExecutionsError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"CertificateValidationException" => {
return RusotoError::Service(
GetPendingJobExecutionsError::CertificateValidation(err.msg),
)
}
"InvalidRequestException" => {
return RusotoError::Service(GetPendingJobExecutionsError::InvalidRequest(
err.msg,
))
}
"ResourceNotFoundException" => {
return RusotoError::Service(GetPendingJobExecutionsError::ResourceNotFound(
err.msg,
))
}
"ServiceUnavailableException" => {
return RusotoError::Service(GetPendingJobExecutionsError::ServiceUnavailable(
err.msg,
))
}
"ThrottlingException" => {
return RusotoError::Service(GetPendingJobExecutionsError::Throttling(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for GetPendingJobExecutionsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for GetPendingJobExecutionsError {
fn description(&self) -> &str {
match *self {
GetPendingJobExecutionsError::CertificateValidation(ref cause) => cause,
GetPendingJobExecutionsError::InvalidRequest(ref cause) => cause,
GetPendingJobExecutionsError::ResourceNotFound(ref cause) => cause,
GetPendingJobExecutionsError::ServiceUnavailable(ref cause) => cause,
GetPendingJobExecutionsError::Throttling(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum StartNextPendingJobExecutionError {
CertificateValidation(String),
InvalidRequest(String),
ResourceNotFound(String),
ServiceUnavailable(String),
Throttling(String),
}
impl StartNextPendingJobExecutionError {
pub fn from_response(
res: BufferedHttpResponse,
) -> RusotoError<StartNextPendingJobExecutionError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"CertificateValidationException" => {
return RusotoError::Service(
StartNextPendingJobExecutionError::CertificateValidation(err.msg),
)
}
"InvalidRequestException" => {
return RusotoError::Service(StartNextPendingJobExecutionError::InvalidRequest(
err.msg,
))
}
"ResourceNotFoundException" => {
return RusotoError::Service(
StartNextPendingJobExecutionError::ResourceNotFound(err.msg),
)
}
"ServiceUnavailableException" => {
return RusotoError::Service(
StartNextPendingJobExecutionError::ServiceUnavailable(err.msg),
)
}
"ThrottlingException" => {
return RusotoError::Service(StartNextPendingJobExecutionError::Throttling(
err.msg,
))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for StartNextPendingJobExecutionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for StartNextPendingJobExecutionError {
fn description(&self) -> &str {
match *self {
StartNextPendingJobExecutionError::CertificateValidation(ref cause) => cause,
StartNextPendingJobExecutionError::InvalidRequest(ref cause) => cause,
StartNextPendingJobExecutionError::ResourceNotFound(ref cause) => cause,
StartNextPendingJobExecutionError::ServiceUnavailable(ref cause) => cause,
StartNextPendingJobExecutionError::Throttling(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum UpdateJobExecutionError {
CertificateValidation(String),
InvalidRequest(String),
InvalidStateTransition(String),
ResourceNotFound(String),
ServiceUnavailable(String),
Throttling(String),
}
impl UpdateJobExecutionError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<UpdateJobExecutionError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"CertificateValidationException" => {
return RusotoError::Service(UpdateJobExecutionError::CertificateValidation(
err.msg,
))
}
"InvalidRequestException" => {
return RusotoError::Service(UpdateJobExecutionError::InvalidRequest(err.msg))
}
"InvalidStateTransitionException" => {
return RusotoError::Service(UpdateJobExecutionError::InvalidStateTransition(
err.msg,
))
}
"ResourceNotFoundException" => {
return RusotoError::Service(UpdateJobExecutionError::ResourceNotFound(err.msg))
}
"ServiceUnavailableException" => {
return RusotoError::Service(UpdateJobExecutionError::ServiceUnavailable(
err.msg,
))
}
"ThrottlingException" => {
return RusotoError::Service(UpdateJobExecutionError::Throttling(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for UpdateJobExecutionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for UpdateJobExecutionError {
fn description(&self) -> &str {
match *self {
UpdateJobExecutionError::CertificateValidation(ref cause) => cause,
UpdateJobExecutionError::InvalidRequest(ref cause) => cause,
UpdateJobExecutionError::InvalidStateTransition(ref cause) => cause,
UpdateJobExecutionError::ResourceNotFound(ref cause) => cause,
UpdateJobExecutionError::ServiceUnavailable(ref cause) => cause,
UpdateJobExecutionError::Throttling(ref cause) => cause,
}
}
}
pub trait IotJobsData {
fn describe_job_execution(
&self,
input: DescribeJobExecutionRequest,
) -> RusotoFuture<DescribeJobExecutionResponse, DescribeJobExecutionError>;
fn get_pending_job_executions(
&self,
input: GetPendingJobExecutionsRequest,
) -> RusotoFuture<GetPendingJobExecutionsResponse, GetPendingJobExecutionsError>;
fn start_next_pending_job_execution(
&self,
input: StartNextPendingJobExecutionRequest,
) -> RusotoFuture<StartNextPendingJobExecutionResponse, StartNextPendingJobExecutionError>;
fn update_job_execution(
&self,
input: UpdateJobExecutionRequest,
) -> RusotoFuture<UpdateJobExecutionResponse, UpdateJobExecutionError>;
}
#[derive(Clone)]
pub struct IotJobsDataClient {
client: Client,
region: region::Region,
}
impl IotJobsDataClient {
pub fn new(region: region::Region) -> IotJobsDataClient {
IotJobsDataClient {
client: Client::shared(),
region,
}
}
pub fn new_with<P, D>(
request_dispatcher: D,
credentials_provider: P,
region: region::Region,
) -> IotJobsDataClient
where
P: ProvideAwsCredentials + Send + Sync + 'static,
P::Future: Send,
D: DispatchSignedRequest + Send + Sync + 'static,
D::Future: Send,
{
IotJobsDataClient {
client: Client::new_with(credentials_provider, request_dispatcher),
region,
}
}
}
impl IotJobsData for IotJobsDataClient {
fn describe_job_execution(
&self,
input: DescribeJobExecutionRequest,
) -> RusotoFuture<DescribeJobExecutionResponse, DescribeJobExecutionError> {
let request_uri = format!(
"/things/{thing_name}/jobs/{job_id}",
job_id = input.job_id,
thing_name = input.thing_name
);
let mut request = SignedRequest::new("GET", "iot-jobs-data", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.jobs.iot".to_string());
let mut params = Params::new();
if let Some(ref x) = input.execution_number {
params.put("executionNumber", x);
}
if let Some(ref x) = input.include_job_document {
params.put("includeJobDocument", x);
}
request.set_params(params);
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let result = proto::json::ResponsePayload::new(&response)
.deserialize::<DescribeJobExecutionResponse, _>()?;
Ok(result)
}))
} else {
Box::new(
response.buffer().from_err().and_then(|response| {
Err(DescribeJobExecutionError::from_response(response))
}),
)
}
})
}
fn get_pending_job_executions(
&self,
input: GetPendingJobExecutionsRequest,
) -> RusotoFuture<GetPendingJobExecutionsResponse, GetPendingJobExecutionsError> {
let request_uri = format!("/things/{thing_name}/jobs", thing_name = input.thing_name);
let mut request = SignedRequest::new("GET", "iot-jobs-data", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.jobs.iot".to_string());
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let result = proto::json::ResponsePayload::new(&response)
.deserialize::<GetPendingJobExecutionsResponse, _>()?;
Ok(result)
}))
} else {
Box::new(response.buffer().from_err().and_then(|response| {
Err(GetPendingJobExecutionsError::from_response(response))
}))
}
})
}
fn start_next_pending_job_execution(
&self,
input: StartNextPendingJobExecutionRequest,
) -> RusotoFuture<StartNextPendingJobExecutionResponse, StartNextPendingJobExecutionError> {
let request_uri = format!(
"/things/{thing_name}/jobs/$next",
thing_name = input.thing_name
);
let mut request = SignedRequest::new("PUT", "iot-jobs-data", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.jobs.iot".to_string());
let encoded = Some(serde_json::to_vec(&input).unwrap());
request.set_payload(encoded);
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let result = proto::json::ResponsePayload::new(&response)
.deserialize::<StartNextPendingJobExecutionResponse, _>()?;
Ok(result)
}))
} else {
Box::new(response.buffer().from_err().and_then(|response| {
Err(StartNextPendingJobExecutionError::from_response(response))
}))
}
})
}
fn update_job_execution(
&self,
input: UpdateJobExecutionRequest,
) -> RusotoFuture<UpdateJobExecutionResponse, UpdateJobExecutionError> {
let request_uri = format!(
"/things/{thing_name}/jobs/{job_id}",
job_id = input.job_id,
thing_name = input.thing_name
);
let mut request = SignedRequest::new("POST", "iot-jobs-data", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.jobs.iot".to_string());
let encoded = Some(serde_json::to_vec(&input).unwrap());
request.set_payload(encoded);
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let result = proto::json::ResponsePayload::new(&response)
.deserialize::<UpdateJobExecutionResponse, _>()?;
Ok(result)
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(UpdateJobExecutionError::from_response(response))),
)
}
})
}
}