From 08d719bea40db973281b1f5e87f9fb06cc1a70f6 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 10:47:30 +0200 Subject: [PATCH 01/52] feat: implement resolve incident command --- cli/src/main.rs | 23 +++++++++++++++++++---- client/src/lib.rs | 9 +++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 051a1dc..deb49b1 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,7 +3,7 @@ use std::{fmt::Debug, path::PathBuf}; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; -use zeebe_client::api::{DeployResourceRequest, Resource, TopologyRequest}; +use zeebe_client::{api::{DeployResourceRequest, ResolveIncidentRequest, Resource, TopologyRequest}, Protocol}; #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] @@ -47,6 +47,7 @@ struct Connection { enum Commands { Status, Deploy(DeployArgs), + ResolveIncident(IncidentArgs), } #[derive(Args)] @@ -55,11 +56,17 @@ struct DeployArgs { resources: Vec, } +#[derive(Args)] +struct IncidentArgs { + incident_key: i64, +} + impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { - match conn.address { - Some(addr) => zeebe_client::Connection::Address(addr), - None => zeebe_client::Connection::HostPort(conn.host, conn.port), + match (conn.address, conn.insecure) { + (Some(addr),_) => zeebe_client::Connection::Address(addr), + (None, true) => zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port), + (None, false) => zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port), } } } @@ -77,6 +84,14 @@ async fn main() -> Result<()> { .await? .into_inner(), ), + Commands::ResolveIncident(args) => Box::new( + client + .resolve_incident(ResolveIncidentRequest { + incident_key: args.incident_key, + }) + .await? + .into_inner(), + ), }; println!("{:#?}", response); diff --git a/client/src/lib.rs b/client/src/lib.rs index 4a2aef2..fc5e6ba 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -15,9 +15,14 @@ pub mod api { pub use super::generated_api::*; } +#[derive(Debug)] +pub enum Protocol { + HTTPS, + HTTP +} pub enum Connection { Address(String), - HostPort(String, u16), + HostPort(Protocol,String, u16), } #[derive(Error, Debug)] @@ -31,7 +36,7 @@ pub enum ConnectionError { pub async fn connect(conn: Connection) -> Result, ConnectionError> { let uri = match conn { Connection::Address(addr) => Uri::from_str(&addr), - Connection::HostPort(host, port) => Uri::from_str(&format!("http://{}:{}", host, port)), + Connection::HostPort(proto, host, port) => Uri::from_str(&format!("{:?}://{}:{}", proto, host, port)), }?; let channel = Channel::builder(uri); Ok(GatewayClient::new(channel.connect().await?)) From 0d0296f6aa8025c2a7402e36e8cd46f9c8e1760e Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 11:15:00 +0200 Subject: [PATCH 02/52] run formatter --- client/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index fc5e6ba..9b25a94 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -18,11 +18,11 @@ pub mod api { #[derive(Debug)] pub enum Protocol { HTTPS, - HTTP + HTTP, } pub enum Connection { Address(String), - HostPort(Protocol,String, u16), + HostPort(Protocol, String, u16), } #[derive(Error, Debug)] @@ -36,7 +36,9 @@ pub enum ConnectionError { pub async fn connect(conn: Connection) -> Result, ConnectionError> { let uri = match conn { Connection::Address(addr) => Uri::from_str(&addr), - Connection::HostPort(proto, host, port) => Uri::from_str(&format!("{:?}://{}:{}", proto, host, port)), + Connection::HostPort(proto, host, port) => { + Uri::from_str(&format!("{:?}://{}:{}", proto, host, port)) + } }?; let channel = Channel::builder(uri); Ok(GatewayClient::new(channel.connect().await?)) From 5581013e2cf247082cb937fb9e8409322689fd19 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 11:15:55 +0200 Subject: [PATCH 03/52] implement CancelProcessInstance --- cli/src/main.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index deb49b1..d8c1f99 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,7 +3,13 @@ use std::{fmt::Debug, path::PathBuf}; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; -use zeebe_client::{api::{DeployResourceRequest, ResolveIncidentRequest, Resource, TopologyRequest}, Protocol}; +use zeebe_client::{ + api::{ + CancelProcessInstanceRequest, DeployResourceRequest, ResolveIncidentRequest, Resource, + TopologyRequest, + }, + Protocol, +}; #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] @@ -48,6 +54,7 @@ enum Commands { Status, Deploy(DeployArgs), ResolveIncident(IncidentArgs), + CancelProcessInstance(CancelProcessInstanceArgs), } #[derive(Args)] @@ -61,12 +68,21 @@ struct IncidentArgs { incident_key: i64, } +#[derive(Args)] +struct CancelProcessInstanceArgs { + process_instance_key: i64, +} + impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { - (Some(addr),_) => zeebe_client::Connection::Address(addr), - (None, true) => zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port), - (None, false) => zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port), + (Some(addr), _) => zeebe_client::Connection::Address(addr), + (None, true) => { + zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port) + } + (None, false) => { + zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port) + } } } } @@ -92,6 +108,14 @@ async fn main() -> Result<()> { .await? .into_inner(), ), + Commands::CancelProcessInstance(args) => Box::new( + client + .cancel_process_instance(CancelProcessInstanceRequest { + process_instance_key: args.process_instance_key, + }) + .await? + .into_inner(), + ), }; println!("{:#?}", response); From ee2422805feb1ee2cc6b36398308b8f225568e6f Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 11:50:09 +0200 Subject: [PATCH 04/52] Implement FailJob command --- cli/src/main.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index d8c1f99..03c292f 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -5,8 +5,8 @@ use color_eyre::eyre::Result; use zeebe_client::{ api::{ - CancelProcessInstanceRequest, DeployResourceRequest, ResolveIncidentRequest, Resource, - TopologyRequest, + CancelProcessInstanceRequest, DeployResourceRequest, FailJobRequest, + ResolveIncidentRequest, Resource, TopologyRequest, }, Protocol, }; @@ -55,6 +55,7 @@ enum Commands { Deploy(DeployArgs), ResolveIncident(IncidentArgs), CancelProcessInstance(CancelProcessInstanceArgs), + FailJob(FailJobArgs), } #[derive(Args)] @@ -73,6 +74,24 @@ struct CancelProcessInstanceArgs { process_instance_key: i64, } +#[derive(Args)] +struct FailJobArgs { + // the unique job identifier, as obtained when activating the job + #[clap(required = true, short, long)] + job_key: i64, + // the amount of retries the job should have left + #[clap(required = true, short, long)] + retries: i32, + // an optional message describing why the job failed + // this is particularly useful if a job runs out of retries and an incident is raised, + // as it this message can help explain why an incident was raised + #[clap(short, long)] + error_message: Option, + // the back off timeout for the next retry + #[clap(short = 'b', long)] + retry_back_off: Option, +} + impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { @@ -116,6 +135,17 @@ async fn main() -> Result<()> { .await? .into_inner(), ), + Commands::FailJob(args) => Box::new( + client + .fail_job(FailJobRequest { + job_key: args.job_key, + retries: args.retries, + error_message: args.error_message.unwrap_or(String::new()), + retry_back_off: args.retry_back_off.unwrap_or(0), + }) + .await? + .into_inner(), + ), }; println!("{:#?}", response); From eae3ea885bb2455b7949206cfdb350ab8805b43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 11:57:15 +0200 Subject: [PATCH 05/52] feat: implement create process instance command --- cli/src/create.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++ cli/src/main.rs | 20 ++++++++++--- 2 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 cli/src/create.rs diff --git a/cli/src/create.rs b/cli/src/create.rs new file mode 100644 index 0000000..e8c4ad8 --- /dev/null +++ b/cli/src/create.rs @@ -0,0 +1,73 @@ +use crate::Debug; +use clap::{Args, Subcommand}; +use color_eyre::eyre::Result; +use tonic::transport::Channel; +use zeebe_client::api::{ + gateway_client::GatewayClient, CreateProcessInstanceRequest, + CreateProcessInstanceWithResultRequest, +}; + +#[derive(Args, Clone, Debug)] +pub(crate) struct CreateArgs { + #[clap(subcommand)] + resource_type: CreateResourceType, +} + +#[derive(Subcommand, Clone, Debug)] +enum CreateResourceType { + Instance(CreateInstanceArgs), +} + +#[derive(Args, Clone, Debug)] +struct CreateInstanceArgs { + process: String, + + #[clap(long, required = false)] + with_results: bool, + #[clap(long, required = false, default_value = "")] + variables: String, + #[clap(long, required = false, default_value_t = -1)] + version: i32, +} + +pub(crate) async fn handle_create_command( + client: &mut GatewayClient, + args: &CreateArgs, +) -> Result> { + match &args.resource_type { + CreateResourceType::Instance(args) => handle_create_instance_command(client, args).await, + } +} + +impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { + fn from(args: &CreateInstanceArgs) -> CreateProcessInstanceRequest { + CreateProcessInstanceRequest { + process_definition_key: args.process.parse().unwrap(), + bpmn_process_id: String::new(), + version: args.version, + variables: args.variables.clone(), + start_instructions: vec![], + } + } +} + +async fn handle_create_instance_command( + client: &mut GatewayClient, + args: &CreateInstanceArgs, +) -> Result> { + let request: CreateProcessInstanceRequest = args.into(); + match args.with_results { + true => Ok(Box::new( + client + .create_process_instance_with_result(CreateProcessInstanceWithResultRequest { + request: Some(request), + ..Default::default() + }) + .await? + .into_inner(), + )), + false => Ok(Box::new( + client.create_process_instance(request).await?.into_inner(), + )), + } +} diff --git a/cli/src/main.rs b/cli/src/main.rs index deb49b1..a2dc34a 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,9 +1,15 @@ +mod create; + use std::{fmt::Debug, path::PathBuf}; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; -use zeebe_client::{api::{DeployResourceRequest, ResolveIncidentRequest, Resource, TopologyRequest}, Protocol}; +use create::CreateArgs; +use zeebe_client::{ + api::{DeployResourceRequest, ResolveIncidentRequest, Resource, TopologyRequest}, + Protocol, +}; #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] @@ -48,6 +54,7 @@ enum Commands { Status, Deploy(DeployArgs), ResolveIncident(IncidentArgs), + Create(CreateArgs), } #[derive(Args)] @@ -64,9 +71,13 @@ struct IncidentArgs { impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { - (Some(addr),_) => zeebe_client::Connection::Address(addr), - (None, true) => zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port), - (None, false) => zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port), + (Some(addr), _) => zeebe_client::Connection::Address(addr), + (None, true) => { + zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port) + } + (None, false) => { + zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port) + } } } } @@ -92,6 +103,7 @@ async fn main() -> Result<()> { .await? .into_inner(), ), + Commands::Create(args) => create::handle_create_command(&mut client, &args).await?, }; println!("{:#?}", response); From f3ec1a590aa803307dc2fb5a0d86d22178dec08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 12:15:00 +0200 Subject: [PATCH 06/52] feat: stub publish message command --- cli/src/main.rs | 3 +++ cli/src/publish.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 cli/src/publish.rs diff --git a/cli/src/main.rs b/cli/src/main.rs index 1fe2568..ed67b56 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,4 +1,5 @@ mod create; +mod publish; use std::{fmt::Debug, path::PathBuf}; @@ -59,6 +60,7 @@ enum Commands { CancelProcessInstance(CancelProcessInstanceArgs), FailJob(FailJobArgs), Create(create::CreateArgs), + Publish(publish::PublishArgs), } #[derive(Args)] @@ -150,6 +152,7 @@ async fn main() -> Result<()> { .into_inner(), ), Commands::Create(args) => create::handle_create_command(&mut client, &args).await?, + Commands::Publish(args) => publish::handle_publish_command(&mut client, &args).await?, }; println!("{:#?}", response); diff --git a/cli/src/publish.rs b/cli/src/publish.rs new file mode 100644 index 0000000..3ea5bd3 --- /dev/null +++ b/cli/src/publish.rs @@ -0,0 +1,27 @@ +use color_eyre::eyre::Result; +use std::fmt::Debug; + +use clap::{Args, Subcommand}; +use tonic::transport::Channel; +use zeebe_client::api::gateway_client::GatewayClient; + +#[derive(Args, Clone, Debug)] +pub(crate) struct PublishArgs { + #[clap(subcommand)] + resource_type: PublishResourceType, +} + +#[derive(Subcommand, Clone, Debug)] +enum PublishResourceType { + Message(PublishMessageArgs), +} + +#[derive(Args, Clone, Debug)] +struct PublishMessageArgs {} + +pub(crate) async fn handle_publish_command( + client: &mut GatewayClient, + args: &PublishArgs, +) -> Result> { + todo!() +} From 952e80dd6a63253e657b487ab964b0f5a918c304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 12:45:39 +0200 Subject: [PATCH 07/52] feat: implement publish message command --- cli/src/publish.rs | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/cli/src/publish.rs b/cli/src/publish.rs index 3ea5bd3..f9361d7 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use clap::{Args, Subcommand}; use tonic::transport::Channel; -use zeebe_client::api::gateway_client::GatewayClient; +use zeebe_client::api::{gateway_client::GatewayClient, PublishMessageRequest}; #[derive(Args, Clone, Debug)] pub(crate) struct PublishArgs { @@ -17,11 +17,45 @@ enum PublishResourceType { } #[derive(Args, Clone, Debug)] -struct PublishMessageArgs {} +struct PublishMessageArgs { + name: String, + #[clap(long)] + correlation_key: String, + #[clap(long)] + message_id: String, + #[clap(long, required = false, default_value = "")] + variables: String, + #[clap(long, required = false, default_value_t = -1)] + ttl: i64, // todo: should be duration +} + +impl From<&PublishMessageArgs> for PublishMessageRequest { + fn from(args: &PublishMessageArgs) -> Self { + PublishMessageRequest { + name: args.name.to_owned(), + correlation_key: args.correlation_key.to_owned(), + time_to_live: args.ttl, + message_id: args.message_id.to_owned(), + variables: args.variables.to_owned(), + } + } +} pub(crate) async fn handle_publish_command( client: &mut GatewayClient, args: &PublishArgs, ) -> Result> { - todo!() + match &args.resource_type { + PublishResourceType::Message(args) => handle_publish_message_command(client, args).await, + } +} + +async fn handle_publish_message_command( + client: &mut GatewayClient, + args: &PublishMessageArgs, +) -> Result> { + let request: PublishMessageRequest = args.into(); + Ok(Box::new( + client.publish_message(request).await?.into_inner(), + )) } From 2ad87aff521aa05fa4abbebc84b1dffb4bfd40bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 13:02:08 +0200 Subject: [PATCH 08/52] feat: implement update-retries command --- cli/src/main.rs | 5 +++++ cli/src/retries.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 cli/src/retries.rs diff --git a/cli/src/main.rs b/cli/src/main.rs index ed67b56..4a8d30a 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,5 +1,6 @@ mod create; mod publish; +mod retries; use std::{fmt::Debug, path::PathBuf}; @@ -61,6 +62,7 @@ enum Commands { FailJob(FailJobArgs), Create(create::CreateArgs), Publish(publish::PublishArgs), + UpdateRetries(retries::UpdateRetriesArgs), } #[derive(Args)] @@ -153,6 +155,9 @@ async fn main() -> Result<()> { ), Commands::Create(args) => create::handle_create_command(&mut client, &args).await?, Commands::Publish(args) => publish::handle_publish_command(&mut client, &args).await?, + Commands::UpdateRetries(args) => { + retries::handle_set_retries_command(&mut client, &args).await? + } }; println!("{:#?}", response); diff --git a/cli/src/retries.rs b/cli/src/retries.rs new file mode 100644 index 0000000..9542cbb --- /dev/null +++ b/cli/src/retries.rs @@ -0,0 +1,36 @@ +use crate::Debug; + +use clap::Args; +use color_eyre::Result; +use tonic::transport::Channel; +use zeebe_client::api::{gateway_client::GatewayClient, UpdateJobRetriesRequest}; + +#[derive(Args)] +pub(crate) struct UpdateRetriesArgs { + #[clap(long)] + job_key: u64, + #[clap(long)] + retries: u32, +} + +impl TryFrom<&UpdateRetriesArgs> for UpdateJobRetriesRequest { + type Error = std::num::TryFromIntError; + fn try_from( + args: &UpdateRetriesArgs, + ) -> Result { + Ok(UpdateJobRetriesRequest { + job_key: args.job_key.try_into()?, + retries: args.retries.try_into()?, + }) + } +} + +pub(crate) async fn handle_set_retries_command( + client: &mut GatewayClient, + args: &UpdateRetriesArgs, +) -> Result> { + let request: UpdateJobRetriesRequest = args.try_into()?; + Ok(Box::new( + client.update_job_retries(request).await?.into_inner(), + )) +} From 86641e0bfbacd28e6914550a99ac3cbbd90efee0 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 13:00:31 +0200 Subject: [PATCH 09/52] SetVariables implemented --- cli/src/main.rs | 49 ++++++++++++++++++++++++++-------------- cli/src/set_variables.rs | 35 ++++++++++++++++++++++++++++ test.json | 4 ++++ 3 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 cli/src/set_variables.rs create mode 100644 test.json diff --git a/cli/src/main.rs b/cli/src/main.rs index 4a8d30a..c546dfe 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,20 +1,23 @@ mod create; mod publish; mod retries; +mod set_variables; use std::{fmt::Debug, path::PathBuf}; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; +use set_variables::SetVariablesArgs; use zeebe_client::{ api::{ CancelProcessInstanceRequest, DeployResourceRequest, FailJobRequest, - ResolveIncidentRequest, Resource, TopologyRequest, + ResolveIncidentRequest, Resource, TopologyRequest, SetVariablesRequest, }, Protocol, }; + #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] struct Cli { @@ -63,6 +66,7 @@ enum Commands { Create(create::CreateArgs), Publish(publish::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), + SetVariables(SetVariablesArgs), } #[derive(Args)] @@ -122,7 +126,7 @@ async fn main() -> Result<()> { Commands::Status => Box::new(client.topology(TopologyRequest {}).await?.into_inner()), Commands::Deploy(args) => Box::new( client - .deploy_resource(build_deploy_request(args)?) + .deploy_resource(TryInto::::try_into(args)?) .await? .into_inner(), ), @@ -147,7 +151,7 @@ async fn main() -> Result<()> { .fail_job(FailJobRequest { job_key: args.job_key, retries: args.retries, - error_message: args.error_message.unwrap_or(String::new()), + error_message: args.error_message.unwrap_or_default(), retry_back_off: args.retry_back_off.unwrap_or(0), }) .await? @@ -158,6 +162,13 @@ async fn main() -> Result<()> { Commands::UpdateRetries(args) => { retries::handle_set_retries_command(&mut client, &args).await? } + + Commands::SetVariables(arg) => Box::new( + client + .set_variables(TryInto::::try_into(arg)?) + .await? + .into_inner(), + ), }; println!("{:#?}", response); @@ -165,19 +176,23 @@ async fn main() -> Result<()> { Ok(()) } -fn build_deploy_request(args: DeployArgs) -> Result { - let mut resources = Vec::with_capacity(args.resources.len()); - for path in &args.resources { - let resource = Resource { - name: path - .file_name() - .expect("resource path should point to a file") - .to_str() - .expect("file name should be UTF-8") - .to_string(), - content: std::fs::read(path)?, - }; - resources.push(resource); +impl TryInto for DeployArgs { + type Error = color_eyre::Report; + + fn try_into(self) -> Result { + let mut resources = Vec::with_capacity(self.resources.len()); + for path in &self.resources { + let resource = Resource { + name: path + .file_name() + .expect("resource path should point to a file") + .to_str() + .expect("file name should be UTF-8") + .to_string(), + content: std::fs::read(path)?, + }; + resources.push(resource); + } + Ok(DeployResourceRequest { resources }) } - Ok(DeployResourceRequest { resources }) } diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs new file mode 100644 index 0000000..63e8b93 --- /dev/null +++ b/cli/src/set_variables.rs @@ -0,0 +1,35 @@ +use std::path::PathBuf; + +use clap::Args; +use zeebe_client::api::SetVariablesRequest; + +#[derive(Args)] + +pub struct SetVariablesArgs { + element_instance_key: i64, + #[clap(long)] + local: bool, + #[clap(long, value_parser, group = "value")] + path: Option, + #[clap(long, group = "value")] + json: Option, +} + +impl TryInto for SetVariablesArgs { + type Error = color_eyre::Report; + + fn try_into(self) -> Result { + let variables = if let Some(path) = self.path { + std::fs::read_to_string(path)? + } else if let Some(json) = self.json { + json + } else { + unreachable!() + }; + Ok(SetVariablesRequest { + element_instance_key: self.element_instance_key, + variables, + local: self.local, + }) + } +} diff --git a/test.json b/test.json new file mode 100644 index 0000000..470f330 --- /dev/null +++ b/test.json @@ -0,0 +1,4 @@ +{ + "test": true, + "value": 12345 +} \ No newline at end of file From c728a61692a1df4f11f1b9ee1a90c2b0dac030a4 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 13:26:24 +0200 Subject: [PATCH 10/52] refactor: simplify optional attributes for fail job --- cli/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index c546dfe..ccf31c4 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -96,11 +96,11 @@ struct FailJobArgs { // an optional message describing why the job failed // this is particularly useful if a job runs out of retries and an incident is raised, // as it this message can help explain why an incident was raised - #[clap(short, long)] - error_message: Option, + #[clap(required = false, short, long, default_value = "")] + error_message: String, // the back off timeout for the next retry - #[clap(short = 'b', long)] - retry_back_off: Option, + #[clap(required = false, short = 'b', long, default_value = "0")] + retry_back_off: i64, } impl From for zeebe_client::Connection { @@ -151,8 +151,8 @@ async fn main() -> Result<()> { .fail_job(FailJobRequest { job_key: args.job_key, retries: args.retries, - error_message: args.error_message.unwrap_or_default(), - retry_back_off: args.retry_back_off.unwrap_or(0), + error_message: args.error_message, + retry_back_off: args.retry_back_off, }) .await? .into_inner(), From e66ab11c333f61bd8be0197aab701a5838c587a3 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 13:38:16 +0200 Subject: [PATCH 11/52] Switched to try_from --- cli/src/main.rs | 17 ++++++++--------- cli/src/set_variables.rs | 14 +++++++------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index ccf31c4..75b5f58 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -12,12 +12,11 @@ use set_variables::SetVariablesArgs; use zeebe_client::{ api::{ CancelProcessInstanceRequest, DeployResourceRequest, FailJobRequest, - ResolveIncidentRequest, Resource, TopologyRequest, SetVariablesRequest, + ResolveIncidentRequest, Resource, SetVariablesRequest, TopologyRequest, }, Protocol, }; - #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] struct Cli { @@ -126,7 +125,7 @@ async fn main() -> Result<()> { Commands::Status => Box::new(client.topology(TopologyRequest {}).await?.into_inner()), Commands::Deploy(args) => Box::new( client - .deploy_resource(TryInto::::try_into(args)?) + .deploy_resource(DeployResourceRequest::try_from(&args)?) .await? .into_inner(), ), @@ -165,7 +164,7 @@ async fn main() -> Result<()> { Commands::SetVariables(arg) => Box::new( client - .set_variables(TryInto::::try_into(arg)?) + .set_variables(SetVariablesRequest::try_from(arg)?) .await? .into_inner(), ), @@ -176,12 +175,12 @@ async fn main() -> Result<()> { Ok(()) } -impl TryInto for DeployArgs { +impl TryFrom<&DeployArgs> for DeployResourceRequest { type Error = color_eyre::Report; - fn try_into(self) -> Result { - let mut resources = Vec::with_capacity(self.resources.len()); - for path in &self.resources { + fn try_from(args: &DeployArgs) -> Result { + let mut resources = Vec::with_capacity(args.resources.len()); + for path in &args.resources { let resource = Resource { name: path .file_name() @@ -193,6 +192,6 @@ impl TryInto for DeployArgs { }; resources.push(resource); } - Ok(DeployResourceRequest { resources }) + Ok(Self { resources }) } } diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs index 63e8b93..13d0cb2 100644 --- a/cli/src/set_variables.rs +++ b/cli/src/set_variables.rs @@ -15,21 +15,21 @@ pub struct SetVariablesArgs { json: Option, } -impl TryInto for SetVariablesArgs { +impl TryFrom for SetVariablesRequest { type Error = color_eyre::Report; - fn try_into(self) -> Result { - let variables = if let Some(path) = self.path { + fn try_from(args: SetVariablesArgs) -> Result { + let variables = if let Some(path) = &args.path { std::fs::read_to_string(path)? - } else if let Some(json) = self.json { + } else if let Some(json) = args.json { json } else { unreachable!() }; - Ok(SetVariablesRequest { - element_instance_key: self.element_instance_key, + Ok(Self { + element_instance_key: args.element_instance_key, variables, - local: self.local, + local: args.local, }) } } From c9a3c2a5c9f19d1d35935f7d38f394869a5350b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 13:37:22 +0200 Subject: [PATCH 12/52] feat: implement activate jobs command --- cli/src/activate.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++ cli/src/main.rs | 3 +++ 2 files changed, 66 insertions(+) create mode 100644 cli/src/activate.rs diff --git a/cli/src/activate.rs b/cli/src/activate.rs new file mode 100644 index 0000000..ee0df7c --- /dev/null +++ b/cli/src/activate.rs @@ -0,0 +1,63 @@ +use crate::Debug; +use clap::{Args, Subcommand}; +use color_eyre::Result; +use tonic::transport::Channel; +use zeebe_client::api::{gateway_client::GatewayClient, ActivateJobsRequest}; + +#[derive(Args)] +pub(crate) struct ActivateArgs { + #[clap(subcommand)] + resource_type: ActivateResourceType, +} + +#[derive(Subcommand)] +enum ActivateResourceType { + Jobs(ActivateJobsArgs), +} + +#[derive(Args)] +struct ActivateJobsArgs { + job_type: String, + #[clap(long, default_value_t = 1)] + max_jobs_to_activate: u32, + #[clap(long, default_value_t = 5 * 60 * 1000)] + job_timeout: u64, // todo: should be duration + worker: String, + #[clap(long, required = false)] + variables: Vec, +} + +impl From<&ActivateJobsArgs> for ActivateJobsRequest { + fn from(args: &ActivateJobsArgs) -> Self { + ActivateJobsRequest { + r#type: args.job_type.to_owned(), + worker: args.worker.to_owned(), + timeout: args.job_timeout as i64, + max_jobs_to_activate: args.max_jobs_to_activate as i32, + fetch_variable: args.variables.to_owned(), + request_timeout: Default::default(), + } + } +} + +pub(crate) async fn handle_activate_command( + client: &mut GatewayClient, + args: &ActivateArgs, +) -> Result> { + match &args.resource_type { + ActivateResourceType::Jobs(args) => handle_activate_jobs_command(client, args).await, + } +} + +async fn handle_activate_jobs_command( + client: &mut GatewayClient, + args: &ActivateJobsArgs, +) -> Result> { + let request: ActivateJobsRequest = args.into(); + let mut stream = client.activate_jobs(request).await?.into_inner(); + let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); + while let Some(response) = stream.message().await? { + result.push(response); + } + Ok(Box::new(result)) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 75b5f58..481e630 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,3 +1,4 @@ +mod activate; mod create; mod publish; mod retries; @@ -66,6 +67,7 @@ enum Commands { Publish(publish::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), SetVariables(SetVariablesArgs), + Activate(activate::ActivateArgs), } #[derive(Args)] @@ -168,6 +170,7 @@ async fn main() -> Result<()> { .await? .into_inner(), ), + Commands::Activate(args) => activate::handle_activate_command(&mut client, &args).await?, }; println!("{:#?}", response); From 8f507ef92a3cc33a869fbba808d069efb5922f92 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 13:59:29 +0200 Subject: [PATCH 13/52] feat: ThrowError command in CLI --- cli/src/main.rs | 3 +++ cli/src/throw_error.rs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 cli/src/throw_error.rs diff --git a/cli/src/main.rs b/cli/src/main.rs index 481e630..0ced6f2 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,6 +3,7 @@ mod create; mod publish; mod retries; mod set_variables; +mod throw_error; use std::{fmt::Debug, path::PathBuf}; @@ -68,6 +69,7 @@ enum Commands { UpdateRetries(retries::UpdateRetriesArgs), SetVariables(SetVariablesArgs), Activate(activate::ActivateArgs), + ThrowError(throw_error::ThrowErrorArgs), } #[derive(Args)] @@ -171,6 +173,7 @@ async fn main() -> Result<()> { .into_inner(), ), Commands::Activate(args) => activate::handle_activate_command(&mut client, &args).await?, + Commands::ThrowError(args) => throw_error::handle_command(&mut client, &args).await?, }; println!("{:#?}", response); diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs new file mode 100644 index 0000000..6c6611c --- /dev/null +++ b/cli/src/throw_error.rs @@ -0,0 +1,37 @@ +use color_eyre::eyre::Result; +use std::fmt::Debug; + +use clap::Args; +use tonic::transport::Channel; +use zeebe_client::api::{gateway_client::GatewayClient, ThrowErrorRequest}; + +#[derive(Args)] +pub struct ThrowErrorArgs { + // the unique job identifier, as obtained when activating the job + #[clap(short, long)] + job_key: i64, + // the error code that will be matched with an error catch event + #[clap(short = 'c', long)] + error_code: String, + // an optional error message that provides additional context + #[clap(short = 'm', long, default_value = "")] + error_message: String, +} + +impl From<&ThrowErrorArgs> for ThrowErrorRequest { + fn from(args: &ThrowErrorArgs) -> Self { + ThrowErrorRequest { + job_key: args.job_key, + error_code: args.error_code.to_owned(), + error_message: args.error_message.to_owned(), + } + } +} + +pub async fn handle_command( + client: &mut GatewayClient, + args: &ThrowErrorArgs, +) -> Result> { + let request: ThrowErrorRequest = args.into(); + Ok(Box::new(client.throw_error(request).await?.into_inner())) +} From ab8dc482c17986ec2e07042a2d98dfca5ec82891 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 14:11:42 +0200 Subject: [PATCH 14/52] refactor: move cancel process instance logic into own file --- cli/src/cancel_process_instance.rs | 29 +++++++++++++++++++++++++++++ cli/src/main.rs | 21 ++++++--------------- 2 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 cli/src/cancel_process_instance.rs diff --git a/cli/src/cancel_process_instance.rs b/cli/src/cancel_process_instance.rs new file mode 100644 index 0000000..bb57ead --- /dev/null +++ b/cli/src/cancel_process_instance.rs @@ -0,0 +1,29 @@ +use color_eyre::eyre::Result; +use std::fmt::Debug; + +use clap::Args; +use tonic::transport::Channel; +use zeebe_client::api::{gateway_client::GatewayClient, CancelProcessInstanceRequest}; + +#[derive(Args)] +pub struct CancelProcessInstanceArgs { + process_instance_key: i64, +} + +impl From<&CancelProcessInstanceArgs> for CancelProcessInstanceRequest { + fn from(args: &CancelProcessInstanceArgs) -> Self { + CancelProcessInstanceRequest { + process_instance_key: args.process_instance_key, + } + } +} + +pub async fn handle_command( + client: &mut GatewayClient, + args: &CancelProcessInstanceArgs, +) -> Result> { + let request: CancelProcessInstanceRequest = args.into(); + Ok(Box::new( + client.cancel_process_instance(request).await?.into_inner(), + )) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 0ced6f2..5cb4122 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,4 +1,5 @@ mod activate; +mod cancel_process_instance; mod create; mod publish; mod retries; @@ -13,7 +14,7 @@ use color_eyre::eyre::Result; use set_variables::SetVariablesArgs; use zeebe_client::{ api::{ - CancelProcessInstanceRequest, DeployResourceRequest, FailJobRequest, + DeployResourceRequest, FailJobRequest, ResolveIncidentRequest, Resource, SetVariablesRequest, TopologyRequest, }, Protocol, @@ -62,7 +63,7 @@ enum Commands { Status, Deploy(DeployArgs), ResolveIncident(IncidentArgs), - CancelProcessInstance(CancelProcessInstanceArgs), + CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(FailJobArgs), Create(create::CreateArgs), Publish(publish::PublishArgs), @@ -83,11 +84,6 @@ struct IncidentArgs { incident_key: i64, } -#[derive(Args)] -struct CancelProcessInstanceArgs { - process_instance_key: i64, -} - #[derive(Args)] struct FailJobArgs { // the unique job identifier, as obtained when activating the job @@ -141,14 +137,9 @@ async fn main() -> Result<()> { .await? .into_inner(), ), - Commands::CancelProcessInstance(args) => Box::new( - client - .cancel_process_instance(CancelProcessInstanceRequest { - process_instance_key: args.process_instance_key, - }) - .await? - .into_inner(), - ), + Commands::CancelProcessInstance(args) => { + cancel_process_instance::handle_command(&mut client, &args).await? + } Commands::FailJob(args) => Box::new( client .fail_job(FailJobRequest { From 974f887c03698108bb22e22fc14cc8800551e14d Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 14:20:56 +0200 Subject: [PATCH 15/52] ci: use clippy for linting --- .vscode/settings.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..edd1e96 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "rust-analyzer.checkOnSave.command": "clippy" +} \ No newline at end of file From cac0f0bd9d11cf71c6b33dbd94f953a8fb35d430 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 14:21:14 +0200 Subject: [PATCH 16/52] refactor: move fail_job into own file --- cli/src/fail_job.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ cli/src/main.rs | 37 +++++-------------------------------- 2 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 cli/src/fail_job.rs diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs new file mode 100644 index 0000000..59fec11 --- /dev/null +++ b/cli/src/fail_job.rs @@ -0,0 +1,43 @@ +use color_eyre::eyre::Result; +use std::fmt::Debug; + +use clap::Args; +use tonic::transport::Channel; +use zeebe_client::api::{gateway_client::GatewayClient, FailJobRequest}; + +#[derive(Args)] +pub struct FailJobArgs { + // the unique job identifier, as obtained when activating the job + #[clap(required = true, short, long)] + job_key: i64, + // the amount of retries the job should have left + #[clap(required = true, short, long)] + retries: i32, + // an optional message describing why the job failed + // this is particularly useful if a job runs out of retries and an incident is raised, + // as it this message can help explain why an incident was raised + #[clap(required = false, short, long, default_value = "")] + error_message: String, + // the back off timeout for the next retry + #[clap(required = false, short = 'b', long, default_value = "0")] + retry_back_off: i64, +} + +impl From<&FailJobArgs> for FailJobRequest { + fn from(args: &FailJobArgs) -> Self { + FailJobRequest { + job_key: args.job_key, + retries: args.retries, + error_message: args.error_message.to_owned(), + retry_back_off: args.retry_back_off, + } + } +} + +pub async fn handle_command( + client: &mut GatewayClient, + args: &FailJobArgs, +) -> Result> { + let request: FailJobRequest = args.into(); + Ok(Box::new(client.fail_job(request).await?.into_inner())) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 5cb4122..68308ba 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,6 +1,7 @@ mod activate; mod cancel_process_instance; mod create; +mod fail_job; mod publish; mod retries; mod set_variables; @@ -14,8 +15,8 @@ use color_eyre::eyre::Result; use set_variables::SetVariablesArgs; use zeebe_client::{ api::{ - DeployResourceRequest, FailJobRequest, - ResolveIncidentRequest, Resource, SetVariablesRequest, TopologyRequest, + DeployResourceRequest, ResolveIncidentRequest, Resource, SetVariablesRequest, + TopologyRequest, }, Protocol, }; @@ -64,7 +65,7 @@ enum Commands { Deploy(DeployArgs), ResolveIncident(IncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), - FailJob(FailJobArgs), + FailJob(fail_job::FailJobArgs), Create(create::CreateArgs), Publish(publish::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), @@ -84,24 +85,6 @@ struct IncidentArgs { incident_key: i64, } -#[derive(Args)] -struct FailJobArgs { - // the unique job identifier, as obtained when activating the job - #[clap(required = true, short, long)] - job_key: i64, - // the amount of retries the job should have left - #[clap(required = true, short, long)] - retries: i32, - // an optional message describing why the job failed - // this is particularly useful if a job runs out of retries and an incident is raised, - // as it this message can help explain why an incident was raised - #[clap(required = false, short, long, default_value = "")] - error_message: String, - // the back off timeout for the next retry - #[clap(required = false, short = 'b', long, default_value = "0")] - retry_back_off: i64, -} - impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { @@ -140,17 +123,7 @@ async fn main() -> Result<()> { Commands::CancelProcessInstance(args) => { cancel_process_instance::handle_command(&mut client, &args).await? } - Commands::FailJob(args) => Box::new( - client - .fail_job(FailJobRequest { - job_key: args.job_key, - retries: args.retries, - error_message: args.error_message, - retry_back_off: args.retry_back_off, - }) - .await? - .into_inner(), - ), + Commands::FailJob(args) => fail_job::handle_command(&mut client, &args).await?, Commands::Create(args) => create::handle_create_command(&mut client, &args).await?, Commands::Publish(args) => publish::handle_publish_command(&mut client, &args).await?, Commands::UpdateRetries(args) => { From 07df12927cc63d0cfff9f704ecc5b77f786be9a5 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 14:31:03 +0200 Subject: [PATCH 17/52] Remove one unneeded parse --- cli/src/create.rs | 6 +++--- cli/src/set_variables.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/src/create.rs b/cli/src/create.rs index e8c4ad8..e407e20 100644 --- a/cli/src/create.rs +++ b/cli/src/create.rs @@ -20,7 +20,7 @@ enum CreateResourceType { #[derive(Args, Clone, Debug)] struct CreateInstanceArgs { - process: String, + process: i64, #[clap(long, required = false)] with_results: bool, @@ -40,9 +40,9 @@ pub(crate) async fn handle_create_command( } impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { - fn from(args: &CreateInstanceArgs) -> CreateProcessInstanceRequest { + fn from(args: &CreateInstanceArgs) -> Self { CreateProcessInstanceRequest { - process_definition_key: args.process.parse().unwrap(), + process_definition_key: args.process, bpmn_process_id: String::new(), version: args.version, variables: args.variables.clone(), diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs index 13d0cb2..b66b277 100644 --- a/cli/src/set_variables.rs +++ b/cli/src/set_variables.rs @@ -5,7 +5,7 @@ use zeebe_client::api::SetVariablesRequest; #[derive(Args)] -pub struct SetVariablesArgs { +pub(crate) struct SetVariablesArgs { element_instance_key: i64, #[clap(long)] local: bool, From a0cc4b5a502cf0c486f5523cc8f9179036766b62 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 14:33:02 +0200 Subject: [PATCH 18/52] Remove testfile --- test.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 test.json diff --git a/test.json b/test.json deleted file mode 100644 index 470f330..0000000 --- a/test.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "test": true, - "value": 12345 -} \ No newline at end of file From ce96eff908c69e158ad27788e8376b43e18ac75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 10 Aug 2022 15:16:06 +0200 Subject: [PATCH 19/52] feat: add empty auth interceptor --- cli/src/activate.rs | 7 +++---- cli/src/cancel_process_instance.rs | 6 +++--- cli/src/create.rs | 12 ++++++------ cli/src/fail_job.rs | 5 ++--- cli/src/publish.rs | 8 ++++---- cli/src/retries.rs | 6 +++--- cli/src/throw_error.rs | 6 +++--- client/src/auth.rs | 9 +++++++++ client/src/lib.rs | 15 +++++++++++---- 9 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 client/src/auth.rs diff --git a/cli/src/activate.rs b/cli/src/activate.rs index ee0df7c..f10b565 100644 --- a/cli/src/activate.rs +++ b/cli/src/activate.rs @@ -1,8 +1,7 @@ use crate::Debug; use clap::{Args, Subcommand}; use color_eyre::Result; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, ActivateJobsRequest}; +use zeebe_client::{api::ActivateJobsRequest, ZeebeClient}; #[derive(Args)] pub(crate) struct ActivateArgs { @@ -41,7 +40,7 @@ impl From<&ActivateJobsArgs> for ActivateJobsRequest { } pub(crate) async fn handle_activate_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &ActivateArgs, ) -> Result> { match &args.resource_type { @@ -50,7 +49,7 @@ pub(crate) async fn handle_activate_command( } async fn handle_activate_jobs_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &ActivateJobsArgs, ) -> Result> { let request: ActivateJobsRequest = args.into(); diff --git a/cli/src/cancel_process_instance.rs b/cli/src/cancel_process_instance.rs index bb57ead..7d3e7b0 100644 --- a/cli/src/cancel_process_instance.rs +++ b/cli/src/cancel_process_instance.rs @@ -2,8 +2,8 @@ use color_eyre::eyre::Result; use std::fmt::Debug; use clap::Args; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, CancelProcessInstanceRequest}; + +use zeebe_client::{api::CancelProcessInstanceRequest, ZeebeClient}; #[derive(Args)] pub struct CancelProcessInstanceArgs { @@ -19,7 +19,7 @@ impl From<&CancelProcessInstanceArgs> for CancelProcessInstanceRequest { } pub async fn handle_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &CancelProcessInstanceArgs, ) -> Result> { let request: CancelProcessInstanceRequest = args.into(); diff --git a/cli/src/create.rs b/cli/src/create.rs index e407e20..e86945e 100644 --- a/cli/src/create.rs +++ b/cli/src/create.rs @@ -1,10 +1,10 @@ use crate::Debug; use clap::{Args, Subcommand}; use color_eyre::eyre::Result; -use tonic::transport::Channel; -use zeebe_client::api::{ - gateway_client::GatewayClient, CreateProcessInstanceRequest, - CreateProcessInstanceWithResultRequest, + +use zeebe_client::{ + api::{CreateProcessInstanceRequest, CreateProcessInstanceWithResultRequest}, + ZeebeClient, }; #[derive(Args, Clone, Debug)] @@ -31,7 +31,7 @@ struct CreateInstanceArgs { } pub(crate) async fn handle_create_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &CreateArgs, ) -> Result> { match &args.resource_type { @@ -52,7 +52,7 @@ impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { } async fn handle_create_instance_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &CreateInstanceArgs, ) -> Result> { let request: CreateProcessInstanceRequest = args.into(); diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs index 59fec11..65148d7 100644 --- a/cli/src/fail_job.rs +++ b/cli/src/fail_job.rs @@ -2,8 +2,7 @@ use color_eyre::eyre::Result; use std::fmt::Debug; use clap::Args; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, FailJobRequest}; +use zeebe_client::{api::FailJobRequest, ZeebeClient}; #[derive(Args)] pub struct FailJobArgs { @@ -35,7 +34,7 @@ impl From<&FailJobArgs> for FailJobRequest { } pub async fn handle_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &FailJobArgs, ) -> Result> { let request: FailJobRequest = args.into(); diff --git a/cli/src/publish.rs b/cli/src/publish.rs index f9361d7..92bfe71 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish.rs @@ -2,8 +2,8 @@ use color_eyre::eyre::Result; use std::fmt::Debug; use clap::{Args, Subcommand}; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, PublishMessageRequest}; + +use zeebe_client::{api::PublishMessageRequest, ZeebeClient}; #[derive(Args, Clone, Debug)] pub(crate) struct PublishArgs { @@ -42,7 +42,7 @@ impl From<&PublishMessageArgs> for PublishMessageRequest { } pub(crate) async fn handle_publish_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &PublishArgs, ) -> Result> { match &args.resource_type { @@ -51,7 +51,7 @@ pub(crate) async fn handle_publish_command( } async fn handle_publish_message_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &PublishMessageArgs, ) -> Result> { let request: PublishMessageRequest = args.into(); diff --git a/cli/src/retries.rs b/cli/src/retries.rs index 9542cbb..9b89a36 100644 --- a/cli/src/retries.rs +++ b/cli/src/retries.rs @@ -2,8 +2,8 @@ use crate::Debug; use clap::Args; use color_eyre::Result; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, UpdateJobRetriesRequest}; + +use zeebe_client::{api::UpdateJobRetriesRequest, ZeebeClient}; #[derive(Args)] pub(crate) struct UpdateRetriesArgs { @@ -26,7 +26,7 @@ impl TryFrom<&UpdateRetriesArgs> for UpdateJobRetriesRequest { } pub(crate) async fn handle_set_retries_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &UpdateRetriesArgs, ) -> Result> { let request: UpdateJobRetriesRequest = args.try_into()?; diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs index 6c6611c..a359931 100644 --- a/cli/src/throw_error.rs +++ b/cli/src/throw_error.rs @@ -2,8 +2,8 @@ use color_eyre::eyre::Result; use std::fmt::Debug; use clap::Args; -use tonic::transport::Channel; -use zeebe_client::api::{gateway_client::GatewayClient, ThrowErrorRequest}; + +use zeebe_client::{api::ThrowErrorRequest, ZeebeClient}; #[derive(Args)] pub struct ThrowErrorArgs { @@ -29,7 +29,7 @@ impl From<&ThrowErrorArgs> for ThrowErrorRequest { } pub async fn handle_command( - client: &mut GatewayClient, + client: &mut ZeebeClient, args: &ThrowErrorArgs, ) -> Result> { let request: ThrowErrorRequest = args.into(); diff --git a/client/src/auth.rs b/client/src/auth.rs new file mode 100644 index 0000000..d308a0e --- /dev/null +++ b/client/src/auth.rs @@ -0,0 +1,9 @@ +use tonic::service::Interceptor; + +pub struct AuthInterceptor {} + +impl Interceptor for AuthInterceptor { + fn call(&mut self, request: tonic::Request<()>) -> Result, tonic::Status> { + Ok(request) + } +} diff --git a/client/src/lib.rs b/client/src/lib.rs index 9b25a94..8c5abec 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,9 +1,10 @@ +mod auth; use std::str::FromStr; -use api::gateway_client::GatewayClient; +use auth::AuthInterceptor; use thiserror::Error; use tonic::{ - codegen::http::uri::InvalidUri, + codegen::{http::uri::InvalidUri, InterceptedService}, transport::{self, Channel, Uri}, }; @@ -33,7 +34,10 @@ pub enum ConnectionError { Uri(#[from] InvalidUri), } -pub async fn connect(conn: Connection) -> Result, ConnectionError> { +pub type ZeebeClient = + api::gateway_client::GatewayClient>; + +pub async fn connect(conn: Connection) -> Result { let uri = match conn { Connection::Address(addr) => Uri::from_str(&addr), Connection::HostPort(proto, host, port) => { @@ -41,5 +45,8 @@ pub async fn connect(conn: Connection) -> Result, Connect } }?; let channel = Channel::builder(uri); - Ok(GatewayClient::new(channel.connect().await?)) + Ok(api::gateway_client::GatewayClient::with_interceptor( + channel.connect().await?, + AuthInterceptor {}, + )) } From d37112ac00b49df630796f3b013e97ed19e2157b Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Wed, 10 Aug 2022 18:25:57 +0200 Subject: [PATCH 20/52] Grand rewrite --- cli/Cargo.toml | 5 +- cli/src/activate.rs | 53 ++++++++---- cli/src/cancel_process_instance.rs | 39 ++++++--- cli/src/create.rs | 56 +++++++++---- cli/src/deploy.rs | 62 ++++++++++++++ cli/src/fail_job.rs | 39 +++++++-- cli/src/main.rs | 130 ++++++++++++++--------------- cli/src/publish.rs | 49 ++++++++--- cli/src/retries.rs | 43 +++++++--- cli/src/set_variables.rs | 31 ++++++- cli/src/status.rs | 31 +++++++ cli/src/throw_error.rs | 38 +++++++-- client/src/lib.rs | 36 +++++++- 13 files changed, 458 insertions(+), 154 deletions(-) create mode 100644 cli/src/deploy.rs create mode 100644 cli/src/status.rs diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 183f450..a5c0a04 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -8,4 +8,7 @@ zeebe-client = { path = "../client" } clap = { version = "3.2", features = ["derive", "env"] } color-eyre = "0.6" tonic = "0.8" -tokio = { version = "1", features=["full"] } \ No newline at end of file +tokio = { version = "1", features=["full"] } +tracing = {version="0.1.36", features=["async-await", "log"]} +tracing-subscriber = "0.3.15" +async-trait = "0.1.57" diff --git a/cli/src/activate.rs b/cli/src/activate.rs index f10b565..e8fde12 100644 --- a/cli/src/activate.rs +++ b/cli/src/activate.rs @@ -1,20 +1,25 @@ -use crate::Debug; +use crate::{Debug, ExecuteZeebeCommand}; +use async_trait::async_trait; use clap::{Args, Subcommand}; use color_eyre::Result; -use zeebe_client::{api::ActivateJobsRequest, ZeebeClient}; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{gateway_client::GatewayClient, ActivateJobsRequest}; -#[derive(Args)] +#[derive(Debug, Args)] pub(crate) struct ActivateArgs { #[clap(subcommand)] resource_type: ActivateResourceType, } -#[derive(Subcommand)] +#[derive(Debug, Subcommand)] enum ActivateResourceType { Jobs(ActivateJobsArgs), } -#[derive(Args)] +#[derive(Args, Debug)] struct ActivateJobsArgs { job_type: String, #[clap(long, default_value_t = 1)] @@ -39,19 +44,39 @@ impl From<&ActivateJobsArgs> for ActivateJobsRequest { } } -pub(crate) async fn handle_activate_command( - client: &mut ZeebeClient, - args: &ActivateArgs, -) -> Result> { - match &args.resource_type { - ActivateResourceType::Jobs(args) => handle_activate_jobs_command(client, args).await, +#[async_trait] +impl ExecuteZeebeCommand for ActivateArgs { + type Output = Box; + + #[tracing::instrument(skip(client))] + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + match &self.resource_type { + ActivateResourceType::Jobs(args) => handle_activate_jobs_command(client, args).await, + } } } -async fn handle_activate_jobs_command( - client: &mut ZeebeClient, +async fn handle_activate_jobs_command( + client: &mut GatewayClient, args: &ActivateJobsArgs, -) -> Result> { +) -> Result> +where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, +{ let request: ActivateJobsRequest = args.into(); let mut stream = client.activate_jobs(request).await?.into_inner(); let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); diff --git a/cli/src/cancel_process_instance.rs b/cli/src/cancel_process_instance.rs index 7d3e7b0..7e767cf 100644 --- a/cli/src/cancel_process_instance.rs +++ b/cli/src/cancel_process_instance.rs @@ -1,9 +1,16 @@ +use async_trait::async_trait; use color_eyre::eyre::Result; -use std::fmt::Debug; use clap::Args; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{ + gateway_client::GatewayClient, CancelProcessInstanceRequest, CancelProcessInstanceResponse, +}; -use zeebe_client::{api::CancelProcessInstanceRequest, ZeebeClient}; +use crate::ExecuteZeebeCommand; #[derive(Args)] pub struct CancelProcessInstanceArgs { @@ -18,12 +25,24 @@ impl From<&CancelProcessInstanceArgs> for CancelProcessInstanceRequest { } } -pub async fn handle_command( - client: &mut ZeebeClient, - args: &CancelProcessInstanceArgs, -) -> Result> { - let request: CancelProcessInstanceRequest = args.into(); - Ok(Box::new( - client.cancel_process_instance(request).await?.into_inner(), - )) + +#[async_trait] +impl ExecuteZeebeCommand for CancelProcessInstanceArgs { + type Output = CancelProcessInstanceResponse; + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .cancel_process_instance(CancelProcessInstanceRequest::from(&self)) + .await? + .into_inner()) + } } diff --git a/cli/src/create.rs b/cli/src/create.rs index e86945e..200aa93 100644 --- a/cli/src/create.rs +++ b/cli/src/create.rs @@ -1,11 +1,9 @@ -use crate::Debug; +use crate::{Debug, ExecuteZeebeCommand}; +use async_trait::async_trait; use clap::{Args, Subcommand}; use color_eyre::eyre::Result; - -use zeebe_client::{ - api::{CreateProcessInstanceRequest, CreateProcessInstanceWithResultRequest}, - ZeebeClient, -}; +use tonic::{codegen::{StdError, Body, Bytes}, client::GrpcService}; +use zeebe_client::api::{CreateProcessInstanceRequest, gateway_client::GatewayClient, CreateProcessInstanceWithResultRequest}; #[derive(Args, Clone, Debug)] pub(crate) struct CreateArgs { @@ -30,15 +28,6 @@ struct CreateInstanceArgs { version: i32, } -pub(crate) async fn handle_create_command( - client: &mut ZeebeClient, - args: &CreateArgs, -) -> Result> { - match &args.resource_type { - CreateResourceType::Instance(args) => handle_create_instance_command(client, args).await, - } -} - impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { fn from(args: &CreateInstanceArgs) -> Self { CreateProcessInstanceRequest { @@ -51,10 +40,41 @@ impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { } } -async fn handle_create_instance_command( - client: &mut ZeebeClient, +#[async_trait] +impl ExecuteZeebeCommand for CreateArgs { + type Output = Box; + + #[tracing::instrument(skip(client))] + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + match &self.resource_type { + CreateResourceType::Instance(args) => { + handle_create_instance_command(client, args).await + } + } + } +} + +async fn handle_create_instance_command( + client: &mut GatewayClient, args: &CreateInstanceArgs, -) -> Result> { +) -> Result> +where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, +{ let request: CreateProcessInstanceRequest = args.into(); match args.with_results { true => Ok(Box::new( diff --git a/cli/src/deploy.rs b/cli/src/deploy.rs new file mode 100644 index 0000000..12f4941 --- /dev/null +++ b/cli/src/deploy.rs @@ -0,0 +1,62 @@ +use std::path::PathBuf; + +use async_trait::async_trait; +use clap::Args; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{ + gateway_client::GatewayClient, DeployResourceRequest, DeployResourceResponse, Resource, +}; + +use crate::ExecuteZeebeCommand; +use color_eyre::Result; + +#[derive(Args)] +pub(crate) struct DeployArgs { + #[clap(required = true, value_parser, value_name = "FILE")] + resources: Vec, +} +#[async_trait] +impl ExecuteZeebeCommand for DeployArgs { + type Output = DeployResourceResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .deploy_resource(DeployResourceRequest::try_from(&self)?) + .await? + .into_inner()) + } +} + +impl TryFrom<&DeployArgs> for DeployResourceRequest { + type Error = color_eyre::Report; + + fn try_from(args: &DeployArgs) -> Result { + let mut resources = Vec::with_capacity(args.resources.len()); + for path in &args.resources { + let resource = Resource { + name: path + .file_name() + .expect("resource path should point to a file") + .to_str() + .expect("file name should be UTF-8") + .to_string(), + content: std::fs::read(path)?, + }; + resources.push(resource); + } + Ok(Self { resources }) + } +} diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs index 65148d7..8a20a4a 100644 --- a/cli/src/fail_job.rs +++ b/cli/src/fail_job.rs @@ -1,9 +1,16 @@ +use async_trait::async_trait; use color_eyre::eyre::Result; -use std::fmt::Debug; -use clap::Args; -use zeebe_client::{api::FailJobRequest, ZeebeClient}; +use crate::ExecuteZeebeCommand; +use clap::Args; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{ + gateway_client::GatewayClient, FailJobRequest, FailJobResponse, +}; #[derive(Args)] pub struct FailJobArgs { // the unique job identifier, as obtained when activating the job @@ -33,10 +40,24 @@ impl From<&FailJobArgs> for FailJobRequest { } } -pub async fn handle_command( - client: &mut ZeebeClient, - args: &FailJobArgs, -) -> Result> { - let request: FailJobRequest = args.into(); - Ok(Box::new(client.fail_job(request).await?.into_inner())) +#[async_trait] +impl ExecuteZeebeCommand for FailJobArgs { + type Output = FailJobResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .fail_job(FailJobRequest::from(&self)) + .await? + .into_inner()) + } } diff --git a/cli/src/main.rs b/cli/src/main.rs index 68308ba..3cb14eb 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,22 +1,27 @@ mod activate; mod cancel_process_instance; mod create; +mod deploy; mod fail_job; mod publish; mod retries; mod set_variables; +mod status; mod throw_error; -use std::{fmt::Debug, path::PathBuf}; +use std::fmt::Debug; +use async_trait::async_trait; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; -use set_variables::SetVariablesArgs; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; use zeebe_client::{ api::{ - DeployResourceRequest, ResolveIncidentRequest, Resource, SetVariablesRequest, - TopologyRequest, + gateway_client::GatewayClient, ResolveIncidentRequest, ResolveIncidentResponse, }, Protocol, }; @@ -61,30 +66,48 @@ struct Connection { #[derive(Subcommand)] enum Commands { - Status, - Deploy(DeployArgs), + Status(status::StatusArgs), + Deploy(deploy::DeployArgs), ResolveIncident(IncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), Create(create::CreateArgs), Publish(publish::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), - SetVariables(SetVariablesArgs), + SetVariables(set_variables::SetVariablesArgs), Activate(activate::ActivateArgs), ThrowError(throw_error::ThrowErrorArgs), } -#[derive(Args)] -struct DeployArgs { - #[clap(required = true, value_parser, value_name = "FILE")] - resources: Vec, -} - #[derive(Args)] struct IncidentArgs { incident_key: i64, } +#[async_trait] +impl ExecuteZeebeCommand for IncidentArgs { + type Output = ResolveIncidentResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .resolve_incident(ResolveIncidentRequest { + incident_key: self.incident_key, + }) + .await? + .into_inner()) + } +} + impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { @@ -99,69 +122,42 @@ impl From for zeebe_client::Connection { } } +#[async_trait] +trait ExecuteZeebeCommand { + type Output: Debug; + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send; +} + #[tokio::main] async fn main() -> Result<()> { + tracing_subscriber::fmt::init(); color_eyre::install()?; let cli: Cli = Cli::parse(); let mut client = zeebe_client::connect(cli.connection.into()).await?; let response: Box = match cli.command { - Commands::Status => Box::new(client.topology(TopologyRequest {}).await?.into_inner()), - Commands::Deploy(args) => Box::new( - client - .deploy_resource(DeployResourceRequest::try_from(&args)?) - .await? - .into_inner(), - ), - Commands::ResolveIncident(args) => Box::new( - client - .resolve_incident(ResolveIncidentRequest { - incident_key: args.incident_key, - }) - .await? - .into_inner(), - ), - Commands::CancelProcessInstance(args) => { - cancel_process_instance::handle_command(&mut client, &args).await? - } - Commands::FailJob(args) => fail_job::handle_command(&mut client, &args).await?, - Commands::Create(args) => create::handle_create_command(&mut client, &args).await?, - Commands::Publish(args) => publish::handle_publish_command(&mut client, &args).await?, - Commands::UpdateRetries(args) => { - retries::handle_set_retries_command(&mut client, &args).await? - } - - Commands::SetVariables(arg) => Box::new( - client - .set_variables(SetVariablesRequest::try_from(arg)?) - .await? - .into_inner(), - ), - Commands::Activate(args) => activate::handle_activate_command(&mut client, &args).await?, - Commands::ThrowError(args) => throw_error::handle_command(&mut client, &args).await?, + Commands::Status(args) => Box::new(args.execute(&mut client).await?), + Commands::Deploy(args) => Box::new(args.execute(&mut client).await?), + Commands::ResolveIncident(args) => Box::new(args.execute(&mut client).await?), + Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), + Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), + Commands::Create(args) => args.execute(&mut client).await?, // Already boxed + Commands::Publish(args) => args.execute(&mut client).await?, // Already boxed, + Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), + Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), + Commands::Activate(args) => args.execute(&mut client).await?, // Already boxed + Commands::ThrowError(args) => Box::new(args.execute(&mut client).await?), }; println!("{:#?}", response); Ok(()) } - -impl TryFrom<&DeployArgs> for DeployResourceRequest { - type Error = color_eyre::Report; - - fn try_from(args: &DeployArgs) -> Result { - let mut resources = Vec::with_capacity(args.resources.len()); - for path in &args.resources { - let resource = Resource { - name: path - .file_name() - .expect("resource path should point to a file") - .to_str() - .expect("file name should be UTF-8") - .to_string(), - content: std::fs::read(path)?, - }; - resources.push(resource); - } - Ok(Self { resources }) - } -} diff --git a/cli/src/publish.rs b/cli/src/publish.rs index 92bfe71..04b9197 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish.rs @@ -1,9 +1,16 @@ +use async_trait::async_trait; use color_eyre::eyre::Result; use std::fmt::Debug; use clap::{Args, Subcommand}; -use zeebe_client::{api::PublishMessageRequest, ZeebeClient}; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{gateway_client::GatewayClient, PublishMessageRequest}; + +use crate::ExecuteZeebeCommand; #[derive(Args, Clone, Debug)] pub(crate) struct PublishArgs { @@ -41,19 +48,41 @@ impl From<&PublishMessageArgs> for PublishMessageRequest { } } -pub(crate) async fn handle_publish_command( - client: &mut ZeebeClient, - args: &PublishArgs, -) -> Result> { - match &args.resource_type { - PublishResourceType::Message(args) => handle_publish_message_command(client, args).await, +#[async_trait] +impl ExecuteZeebeCommand for PublishArgs { + type Output = Box; + + #[tracing::instrument(skip(client))] + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + match &self.resource_type { + PublishResourceType::Message(args) => { + handle_publish_message_command(client, args).await + } + } } } -async fn handle_publish_message_command( - client: &mut ZeebeClient, +async fn handle_publish_message_command( + client: &mut GatewayClient, args: &PublishMessageArgs, -) -> Result> { +) -> Result> +where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, +{ let request: PublishMessageRequest = args.into(); Ok(Box::new( client.publish_message(request).await?.into_inner(), diff --git a/cli/src/retries.rs b/cli/src/retries.rs index 9b89a36..78fe1d0 100644 --- a/cli/src/retries.rs +++ b/cli/src/retries.rs @@ -1,11 +1,17 @@ -use crate::Debug; +use crate::{Debug, ExecuteZeebeCommand}; +use async_trait::async_trait; use clap::Args; use color_eyre::Result; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{ + gateway_client::GatewayClient, UpdateJobRetriesRequest, UpdateJobRetriesResponse, +}; -use zeebe_client::{api::UpdateJobRetriesRequest, ZeebeClient}; - -#[derive(Args)] +#[derive(Debug, Args)] pub(crate) struct UpdateRetriesArgs { #[clap(long)] job_key: u64, @@ -25,12 +31,25 @@ impl TryFrom<&UpdateRetriesArgs> for UpdateJobRetriesRequest { } } -pub(crate) async fn handle_set_retries_command( - client: &mut ZeebeClient, - args: &UpdateRetriesArgs, -) -> Result> { - let request: UpdateJobRetriesRequest = args.try_into()?; - Ok(Box::new( - client.update_job_retries(request).await?.into_inner(), - )) +#[async_trait] +impl ExecuteZeebeCommand for UpdateRetriesArgs { + type Output = UpdateJobRetriesResponse; + + #[tracing::instrument(skip(client))] + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .update_job_retries(UpdateJobRetriesRequest::try_from(&self)?) + .await? + .into_inner()) + } } diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs index b66b277..add32c5 100644 --- a/cli/src/set_variables.rs +++ b/cli/src/set_variables.rs @@ -1,7 +1,14 @@ use std::path::PathBuf; +use crate::ExecuteZeebeCommand; +use async_trait::async_trait; use clap::Args; -use zeebe_client::api::SetVariablesRequest; +use color_eyre::Result; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{gateway_client::GatewayClient, SetVariablesRequest, SetVariablesResponse}; #[derive(Args)] @@ -33,3 +40,25 @@ impl TryFrom for SetVariablesRequest { }) } } + +#[async_trait] +impl ExecuteZeebeCommand for SetVariablesArgs { + type Output = SetVariablesResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .set_variables(SetVariablesRequest::try_from(self)?) + .await? + .into_inner()) + } +} diff --git a/cli/src/status.rs b/cli/src/status.rs new file mode 100644 index 0000000..2ad1169 --- /dev/null +++ b/cli/src/status.rs @@ -0,0 +1,31 @@ +use crate::ExecuteZeebeCommand; +use async_trait::async_trait; +use clap::Args; +use color_eyre::Result; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{gateway_client::GatewayClient, TopologyRequest, TopologyResponse}; + +#[derive(Args)] +pub struct StatusArgs {} + +#[async_trait] +impl ExecuteZeebeCommand for StatusArgs { + type Output = TopologyResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client.topology(TopologyRequest {}).await?.into_inner()) + } +} diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs index a359931..096c985 100644 --- a/cli/src/throw_error.rs +++ b/cli/src/throw_error.rs @@ -1,9 +1,17 @@ +use async_trait::async_trait; use color_eyre::eyre::Result; -use std::fmt::Debug; + use clap::Args; +use tonic::{ + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; +use zeebe_client::api::{ + gateway_client::GatewayClient, ThrowErrorRequest, ThrowErrorResponse, +}; -use zeebe_client::{api::ThrowErrorRequest, ZeebeClient}; +use crate::ExecuteZeebeCommand; #[derive(Args)] pub struct ThrowErrorArgs { @@ -28,10 +36,24 @@ impl From<&ThrowErrorArgs> for ThrowErrorRequest { } } -pub async fn handle_command( - client: &mut ZeebeClient, - args: &ThrowErrorArgs, -) -> Result> { - let request: ThrowErrorRequest = args.into(); - Ok(Box::new(client.throw_error(request).await?.into_inner())) +#[async_trait] +impl ExecuteZeebeCommand for ThrowErrorArgs { + type Output = ThrowErrorResponse; + + async fn execute( + self, + client: &mut GatewayClient, + ) -> Result + where + Service: tonic::client::GrpcService, + Service::Error: Into, + Service::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + >::Future: Send, + { + Ok(client + .throw_error(ThrowErrorRequest::from(&self)) + .await? + .into_inner()) + } } diff --git a/client/src/lib.rs b/client/src/lib.rs index 8c5abec..84babe1 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,10 +1,19 @@ +#![feature(associated_type_bounds)] + mod auth; + use std::str::FromStr; use auth::AuthInterceptor; +use generated_api::gateway_client::GatewayClient; use thiserror::Error; +use tonic::client::GrpcService; +use tonic::codegen::Body; +use tonic::codegen::Bytes; use tonic::{ - codegen::{http::uri::InvalidUri, InterceptedService}, + + codegen::{http::uri::InvalidUri, StdError}, + service::Interceptor, transport::{self, Channel, Uri}, }; @@ -34,10 +43,28 @@ pub enum ConnectionError { Uri(#[from] InvalidUri), } -pub type ZeebeClient = - api::gateway_client::GatewayClient>; +struct FakeInterceptor {} -pub async fn connect(conn: Connection) -> Result { +impl Interceptor for FakeInterceptor { + fn call(&mut self, _request: tonic::Request<()>) -> Result, tonic::Status> { + todo!() + } +} +// Service::ResponseBody: Body + Send + 'static, +// >::Future: Send; + +pub async fn connect( + conn: Connection, +) -> Result< + GatewayClient< + impl GrpcService< + tonic::body::BoxBody, + ResponseBody: Body + Send> + Send + 'static, + Future: Send, + > + Send, + >, + ConnectionError, +> { let uri = match conn { Connection::Address(addr) => Uri::from_str(&addr), Connection::HostPort(proto, host, port) => { @@ -48,5 +75,6 @@ pub async fn connect(conn: Connection) -> Result { Ok(api::gateway_client::GatewayClient::with_interceptor( channel.connect().await?, AuthInterceptor {}, + )) } From 1e91194c0a63482bf2f87589ea4f55e70c27e284 Mon Sep 17 00:00:00 2001 From: pihme Date: Wed, 10 Aug 2022 20:33:50 +0200 Subject: [PATCH 21/52] ci: try nightly toolchain --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9771c7..f4f2d3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - name: Install latest rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: nightly default: true override: true From 04bfec9cfd2a6d5f9fa5a34669ec64cd49d3da06 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Thu, 11 Aug 2022 10:58:50 +0200 Subject: [PATCH 22/52] Less generics --- cli/src/activate.rs | 32 +++++---------------------- cli/src/cancel_process_instance.rs | 22 ++++--------------- cli/src/create.rs | 31 +++++++------------------- cli/src/deploy.rs | 22 +++++-------------- cli/src/fail_job.rs | 23 +++++--------------- cli/src/main.rs | 35 +++++------------------------- cli/src/publish.rs | 31 +++++--------------------- cli/src/retries.rs | 21 ++++-------------- cli/src/set_variables.rs | 20 +++++------------ cli/src/status.rs | 20 +++++------------ cli/src/throw_error.rs | 22 ++++--------------- client/src/lib.rs | 23 +++++--------------- 12 files changed, 61 insertions(+), 241 deletions(-) diff --git a/cli/src/activate.rs b/cli/src/activate.rs index e8fde12..b4314b1 100644 --- a/cli/src/activate.rs +++ b/cli/src/activate.rs @@ -2,11 +2,8 @@ use crate::{Debug, ExecuteZeebeCommand}; use async_trait::async_trait; use clap::{Args, Subcommand}; use color_eyre::Result; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{gateway_client::GatewayClient, ActivateJobsRequest}; + +use zeebe_client::{api::ActivateJobsRequest, ZeebeClient}; #[derive(Debug, Args)] pub(crate) struct ActivateArgs { @@ -49,34 +46,17 @@ impl ExecuteZeebeCommand for ActivateArgs { type Output = Box; #[tracing::instrument(skip(client))] - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { match &self.resource_type { ActivateResourceType::Jobs(args) => handle_activate_jobs_command(client, args).await, } } } -async fn handle_activate_jobs_command( - client: &mut GatewayClient, +async fn handle_activate_jobs_command( + client: &mut ZeebeClient, args: &ActivateJobsArgs, -) -> Result> -where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, -{ +) -> Result> { let request: ActivateJobsRequest = args.into(); let mut stream = client.activate_jobs(request).await?.into_inner(); let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); diff --git a/cli/src/cancel_process_instance.rs b/cli/src/cancel_process_instance.rs index 7e767cf..85279cd 100644 --- a/cli/src/cancel_process_instance.rs +++ b/cli/src/cancel_process_instance.rs @@ -2,12 +2,9 @@ use async_trait::async_trait; use color_eyre::eyre::Result; use clap::Args; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{ - gateway_client::GatewayClient, CancelProcessInstanceRequest, CancelProcessInstanceResponse, +use zeebe_client::{ + api::{CancelProcessInstanceRequest, CancelProcessInstanceResponse}, + ZeebeClient, }; use crate::ExecuteZeebeCommand; @@ -25,21 +22,10 @@ impl From<&CancelProcessInstanceArgs> for CancelProcessInstanceRequest { } } - #[async_trait] impl ExecuteZeebeCommand for CancelProcessInstanceArgs { type Output = CancelProcessInstanceResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .cancel_process_instance(CancelProcessInstanceRequest::from(&self)) .await? diff --git a/cli/src/create.rs b/cli/src/create.rs index 200aa93..db03692 100644 --- a/cli/src/create.rs +++ b/cli/src/create.rs @@ -2,8 +2,10 @@ use crate::{Debug, ExecuteZeebeCommand}; use async_trait::async_trait; use clap::{Args, Subcommand}; use color_eyre::eyre::Result; -use tonic::{codegen::{StdError, Body, Bytes}, client::GrpcService}; -use zeebe_client::api::{CreateProcessInstanceRequest, gateway_client::GatewayClient, CreateProcessInstanceWithResultRequest}; +use zeebe_client::{ + api::{CreateProcessInstanceRequest, CreateProcessInstanceWithResultRequest}, + ZeebeClient, +}; #[derive(Args, Clone, Debug)] pub(crate) struct CreateArgs { @@ -45,17 +47,7 @@ impl ExecuteZeebeCommand for CreateArgs { type Output = Box; #[tracing::instrument(skip(client))] - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { match &self.resource_type { CreateResourceType::Instance(args) => { handle_create_instance_command(client, args).await @@ -64,17 +56,10 @@ impl ExecuteZeebeCommand for CreateArgs { } } -async fn handle_create_instance_command( - client: &mut GatewayClient, +async fn handle_create_instance_command( + client: &mut ZeebeClient, args: &CreateInstanceArgs, -) -> Result> -where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, -{ +) -> Result> { let request: CreateProcessInstanceRequest = args.into(); match args.with_results { true => Ok(Box::new( diff --git a/cli/src/deploy.rs b/cli/src/deploy.rs index 12f4941..bafb972 100644 --- a/cli/src/deploy.rs +++ b/cli/src/deploy.rs @@ -2,12 +2,10 @@ use std::path::PathBuf; use async_trait::async_trait; use clap::Args; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{ - gateway_client::GatewayClient, DeployResourceRequest, DeployResourceResponse, Resource, + +use zeebe_client::{ + api::{DeployResourceRequest, DeployResourceResponse, Resource}, + ZeebeClient, }; use crate::ExecuteZeebeCommand; @@ -22,17 +20,7 @@ pub(crate) struct DeployArgs { impl ExecuteZeebeCommand for DeployArgs { type Output = DeployResourceResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .deploy_resource(DeployResourceRequest::try_from(&self)?) .await? diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs index 8a20a4a..5bf6b42 100644 --- a/cli/src/fail_job.rs +++ b/cli/src/fail_job.rs @@ -1,15 +1,12 @@ use async_trait::async_trait; use color_eyre::eyre::Result; - use crate::ExecuteZeebeCommand; use clap::Args; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{ - gateway_client::GatewayClient, FailJobRequest, FailJobResponse, + +use zeebe_client::{ + api::{FailJobRequest, FailJobResponse}, + ZeebeClient, }; #[derive(Args)] pub struct FailJobArgs { @@ -44,17 +41,7 @@ impl From<&FailJobArgs> for FailJobRequest { impl ExecuteZeebeCommand for FailJobArgs { type Output = FailJobResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .fail_job(FailJobRequest::from(&self)) .await? diff --git a/cli/src/main.rs b/cli/src/main.rs index 3cb14eb..e6c43e3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -15,15 +15,9 @@ use async_trait::async_trait; use clap::{AppSettings, Args, Parser, Subcommand}; use color_eyre::eyre::Result; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; use zeebe_client::{ - api::{ - gateway_client::GatewayClient, ResolveIncidentRequest, ResolveIncidentResponse, - }, - Protocol, + api::{ResolveIncidentRequest, ResolveIncidentResponse}, + Protocol, ZeebeClient, }; #[derive(Parser)] @@ -88,17 +82,7 @@ struct IncidentArgs { impl ExecuteZeebeCommand for IncidentArgs { type Output = ResolveIncidentResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .resolve_incident(ResolveIncidentRequest { incident_key: self.incident_key, @@ -125,16 +109,7 @@ impl From for zeebe_client::Connection { #[async_trait] trait ExecuteZeebeCommand { type Output: Debug; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send; + async fn execute(self, client: &mut ZeebeClient) -> Result; } #[tokio::main] @@ -142,7 +117,7 @@ async fn main() -> Result<()> { tracing_subscriber::fmt::init(); color_eyre::install()?; let cli: Cli = Cli::parse(); - let mut client = zeebe_client::connect(cli.connection.into()).await?; + let mut client: ZeebeClient = zeebe_client::connect(cli.connection.into()).await?; let response: Box = match cli.command { Commands::Status(args) => Box::new(args.execute(&mut client).await?), Commands::Deploy(args) => Box::new(args.execute(&mut client).await?), diff --git a/cli/src/publish.rs b/cli/src/publish.rs index 04b9197..7e1a0f5 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish.rs @@ -4,11 +4,7 @@ use std::fmt::Debug; use clap::{Args, Subcommand}; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{gateway_client::GatewayClient, PublishMessageRequest}; +use zeebe_client::{api::PublishMessageRequest, ZeebeClient}; use crate::ExecuteZeebeCommand; @@ -53,17 +49,7 @@ impl ExecuteZeebeCommand for PublishArgs { type Output = Box; #[tracing::instrument(skip(client))] - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { match &self.resource_type { PublishResourceType::Message(args) => { handle_publish_message_command(client, args).await @@ -72,17 +58,10 @@ impl ExecuteZeebeCommand for PublishArgs { } } -async fn handle_publish_message_command( - client: &mut GatewayClient, +async fn handle_publish_message_command( + client: &mut ZeebeClient, args: &PublishMessageArgs, -) -> Result> -where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, -{ +) -> Result> { let request: PublishMessageRequest = args.into(); Ok(Box::new( client.publish_message(request).await?.into_inner(), diff --git a/cli/src/retries.rs b/cli/src/retries.rs index 78fe1d0..4d6824f 100644 --- a/cli/src/retries.rs +++ b/cli/src/retries.rs @@ -3,12 +3,9 @@ use crate::{Debug, ExecuteZeebeCommand}; use async_trait::async_trait; use clap::Args; use color_eyre::Result; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{ - gateway_client::GatewayClient, UpdateJobRetriesRequest, UpdateJobRetriesResponse, +use zeebe_client::{ + api::{UpdateJobRetriesRequest, UpdateJobRetriesResponse}, + ZeebeClient, }; #[derive(Debug, Args)] @@ -36,17 +33,7 @@ impl ExecuteZeebeCommand for UpdateRetriesArgs { type Output = UpdateJobRetriesResponse; #[tracing::instrument(skip(client))] - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .update_job_retries(UpdateJobRetriesRequest::try_from(&self)?) .await? diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs index add32c5..26968e7 100644 --- a/cli/src/set_variables.rs +++ b/cli/src/set_variables.rs @@ -4,11 +4,11 @@ use crate::ExecuteZeebeCommand; use async_trait::async_trait; use clap::Args; use color_eyre::Result; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, + +use zeebe_client::{ + api::{SetVariablesRequest, SetVariablesResponse}, + ZeebeClient, }; -use zeebe_client::api::{gateway_client::GatewayClient, SetVariablesRequest, SetVariablesResponse}; #[derive(Args)] @@ -45,17 +45,7 @@ impl TryFrom for SetVariablesRequest { impl ExecuteZeebeCommand for SetVariablesArgs { type Output = SetVariablesResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .set_variables(SetVariablesRequest::try_from(self)?) .await? diff --git a/cli/src/status.rs b/cli/src/status.rs index 2ad1169..8dfc34a 100644 --- a/cli/src/status.rs +++ b/cli/src/status.rs @@ -2,11 +2,11 @@ use crate::ExecuteZeebeCommand; use async_trait::async_trait; use clap::Args; use color_eyre::Result; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, + +use zeebe_client::{ + api::{TopologyRequest, TopologyResponse}, + ZeebeClient, }; -use zeebe_client::api::{gateway_client::GatewayClient, TopologyRequest, TopologyResponse}; #[derive(Args)] pub struct StatusArgs {} @@ -15,17 +15,7 @@ pub struct StatusArgs {} impl ExecuteZeebeCommand for StatusArgs { type Output = TopologyResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client.topology(TopologyRequest {}).await?.into_inner()) } } diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs index 096c985..f8150a7 100644 --- a/cli/src/throw_error.rs +++ b/cli/src/throw_error.rs @@ -1,14 +1,10 @@ use async_trait::async_trait; use color_eyre::eyre::Result; - use clap::Args; -use tonic::{ - client::GrpcService, - codegen::{Body, Bytes, StdError}, -}; -use zeebe_client::api::{ - gateway_client::GatewayClient, ThrowErrorRequest, ThrowErrorResponse, +use zeebe_client::{ + api::{ThrowErrorRequest, ThrowErrorResponse}, + ZeebeClient, }; use crate::ExecuteZeebeCommand; @@ -40,17 +36,7 @@ impl From<&ThrowErrorArgs> for ThrowErrorRequest { impl ExecuteZeebeCommand for ThrowErrorArgs { type Output = ThrowErrorResponse; - async fn execute( - self, - client: &mut GatewayClient, - ) -> Result - where - Service: tonic::client::GrpcService, - Service::Error: Into, - Service::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - >::Future: Send, - { + async fn execute(self, client: &mut ZeebeClient) -> Result { Ok(client .throw_error(ThrowErrorRequest::from(&self)) .await? diff --git a/client/src/lib.rs b/client/src/lib.rs index 84babe1..f00bddf 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -7,12 +7,9 @@ use std::str::FromStr; use auth::AuthInterceptor; use generated_api::gateway_client::GatewayClient; use thiserror::Error; -use tonic::client::GrpcService; -use tonic::codegen::Body; -use tonic::codegen::Bytes; -use tonic::{ - codegen::{http::uri::InvalidUri, StdError}, +use tonic::{ + codegen::http::uri::InvalidUri, service::Interceptor, transport::{self, Channel, Uri}, }; @@ -53,18 +50,9 @@ impl Interceptor for FakeInterceptor { // Service::ResponseBody: Body + Send + 'static, // >::Future: Send; -pub async fn connect( - conn: Connection, -) -> Result< - GatewayClient< - impl GrpcService< - tonic::body::BoxBody, - ResponseBody: Body + Send> + Send + 'static, - Future: Send, - > + Send, - >, - ConnectionError, -> { +pub type ZeebeClient = + GatewayClient>; +pub async fn connect(conn: Connection) -> Result { let uri = match conn { Connection::Address(addr) => Uri::from_str(&addr), Connection::HostPort(proto, host, port) => { @@ -75,6 +63,5 @@ pub async fn connect( Ok(api::gateway_client::GatewayClient::with_interceptor( channel.connect().await?, AuthInterceptor {}, - )) } From 23d29311ede6f23ecc1515c7763557a843106d14 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Thu, 11 Aug 2022 11:35:56 +0200 Subject: [PATCH 23/52] No more args in main.rs --- cli/src/incident.rs | 26 ++++++++++++++++++++++++++ cli/src/main.rs | 25 +++---------------------- 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 cli/src/incident.rs diff --git a/cli/src/incident.rs b/cli/src/incident.rs new file mode 100644 index 0000000..82ad882 --- /dev/null +++ b/cli/src/incident.rs @@ -0,0 +1,26 @@ +use async_trait::async_trait; +use clap::Args; +use color_eyre::Result; + +use zeebe_client::{api::{ResolveIncidentResponse, ResolveIncidentRequest}, ZeebeClient}; + +use crate::ExecuteZeebeCommand; + +#[derive(Args)] +pub struct IncidentArgs { + incident_key: i64, +} + +#[async_trait] +impl ExecuteZeebeCommand for IncidentArgs { + type Output = ResolveIncidentResponse; + + async fn execute(self, client: &mut ZeebeClient) -> Result { + Ok(client + .resolve_incident(ResolveIncidentRequest { + incident_key: self.incident_key, + }) + .await? + .into_inner()) + } +} diff --git a/cli/src/main.rs b/cli/src/main.rs index e6c43e3..d905271 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -8,15 +8,15 @@ mod retries; mod set_variables; mod status; mod throw_error; +mod incident; use std::fmt::Debug; use async_trait::async_trait; -use clap::{AppSettings, Args, Parser, Subcommand}; +use clap::{AppSettings, Parser, Subcommand}; use color_eyre::eyre::Result; use zeebe_client::{ - api::{ResolveIncidentRequest, ResolveIncidentResponse}, Protocol, ZeebeClient, }; @@ -62,7 +62,7 @@ struct Connection { enum Commands { Status(status::StatusArgs), Deploy(deploy::DeployArgs), - ResolveIncident(IncidentArgs), + ResolveIncident(incident::IncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), Create(create::CreateArgs), @@ -73,25 +73,6 @@ enum Commands { ThrowError(throw_error::ThrowErrorArgs), } -#[derive(Args)] -struct IncidentArgs { - incident_key: i64, -} - -#[async_trait] -impl ExecuteZeebeCommand for IncidentArgs { - type Output = ResolveIncidentResponse; - - async fn execute(self, client: &mut ZeebeClient) -> Result { - Ok(client - .resolve_incident(ResolveIncidentRequest { - incident_key: self.incident_key, - }) - .await? - .into_inner()) - } -} - impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match (conn.address, conn.insecure) { From a8b985df97696ac757349c0a0ded071261376a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Thu, 11 Aug 2022 12:19:59 +0200 Subject: [PATCH 24/52] fix: remove unused nightly feature --- client/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index f00bddf..84fe574 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(associated_type_bounds)] - mod auth; use std::str::FromStr; From c77f42cb52f3f5100297c43eb04882699de2ccda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Thu, 11 Aug 2022 12:29:51 +0200 Subject: [PATCH 25/52] ci: use stable rust --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4f2d3b..e9771c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - name: Install latest rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: stable default: true override: true From ba1b659182af48c657744da01356d10ad61811a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Thu, 11 Aug 2022 16:35:49 +0200 Subject: [PATCH 26/52] feat: connect over tls --- cli/Cargo.toml | 8 ++-- cli/src/incident.rs | 5 ++- cli/src/main.rs | 90 +++++++++++++++++++++++++++++++++++++-------- client/Cargo.toml | 7 ++-- client/src/auth.rs | 44 +++++++++++++++++++++- client/src/lib.rs | 75 +++++++++++++++++++++++++------------ 6 files changed, 181 insertions(+), 48 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a5c0a04..e69959c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -7,8 +7,10 @@ edition = "2021" zeebe-client = { path = "../client" } clap = { version = "3.2", features = ["derive", "env"] } color-eyre = "0.6" -tonic = "0.8" +tonic = { version = "0.8", features = ["tls", "tls-roots", "gzip"] } tokio = { version = "1", features=["full"] } -tracing = {version="0.1.36", features=["async-await", "log"]} -tracing-subscriber = "0.3.15" +tracing = { version="0.1.36", features = ["async-await", "log"] } +tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } +tracing-error = { version = "0.2", features = ["traced-error"] } +tracing-tree = { version = "0.2" } async-trait = "0.1.57" diff --git a/cli/src/incident.rs b/cli/src/incident.rs index 82ad882..6710857 100644 --- a/cli/src/incident.rs +++ b/cli/src/incident.rs @@ -2,7 +2,10 @@ use async_trait::async_trait; use clap::Args; use color_eyre::Result; -use zeebe_client::{api::{ResolveIncidentResponse, ResolveIncidentRequest}, ZeebeClient}; +use zeebe_client::{ + api::{ResolveIncidentRequest, ResolveIncidentResponse}, + ZeebeClient, +}; use crate::ExecuteZeebeCommand; diff --git a/cli/src/main.rs b/cli/src/main.rs index d905271..d17249a 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,36 +3,51 @@ mod cancel_process_instance; mod create; mod deploy; mod fail_job; +mod incident; mod publish; mod retries; mod set_variables; mod status; mod throw_error; -mod incident; use std::fmt::Debug; use async_trait::async_trait; use clap::{AppSettings, Parser, Subcommand}; +use color_eyre::eyre::Report; use color_eyre::eyre::Result; - -use zeebe_client::{ - Protocol, ZeebeClient, -}; +use zeebe_client::ZeebeClient; #[derive(Parser)] #[clap(global_setting(AppSettings::DeriveDisplayOrder))] struct Cli { #[clap(flatten)] connection: Connection, + #[clap(flatten)] + auth: Authentication, #[clap(subcommand)] command: Commands, } +#[derive(Parser)] +struct Authentication { + #[clap(long, value_parser, group = "authentication", env = "ZEEBE_CLIENT_ID")] + client_id: Option, + #[clap(long, value_parser, env = "ZEEBE_CLIENT_SECRET")] + client_secret: Option, + #[clap( + long, + value_parser, + env = "ZEEBE_AUTHORIZATION_SERVER_URL", + default_value = "https://login.cloud.camunda.io/oauth/token/" + )] + authorization_server: String, +} + #[derive(Parser)] #[clap(group = clap::ArgGroup::new("connection"))] struct Connection { - #[clap(long)] + #[clap(long, default_value_t = false)] insecure: bool, #[clap(long, value_parser, group = "connection", env = "ZEEBE_ADDRESS")] @@ -75,14 +90,37 @@ enum Commands { impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { - match (conn.address, conn.insecure) { - (Some(addr), _) => zeebe_client::Connection::Address(addr), - (None, true) => { - zeebe_client::Connection::HostPort(Protocol::HTTP, conn.host, conn.port) - } - (None, false) => { - zeebe_client::Connection::HostPort(Protocol::HTTPS, conn.host, conn.port) - } + match conn.address { + Some(addr) => zeebe_client::Connection::Address { + insecure: conn.insecure, + addr, + }, + None => zeebe_client::Connection::HostPort { + insecure: conn.insecure, + host: conn.host, + port: conn.port, + }, + } + } +} + +impl TryFrom for zeebe_client::Authentication { + type Error = Report; + + fn try_from(auth: Authentication) -> Result { + match (auth.client_id, auth.client_secret) { + (None, None) => Ok(zeebe_client::Authentication::Unauthenticated), + (Some(client_id), Some(client_secret)) => Ok(zeebe_client::Authentication::Oauth2( + zeebe_client::auth::OAuth2Config { + client_id, + client_secret, + auth_server: auth.authorization_server, + audience: "zeebe".to_owned(), + }, + )), + _ => Err(color_eyre::eyre::eyre!( + "Partial authentication info, needs at least client id and client secret" + )), } } } @@ -93,12 +131,32 @@ trait ExecuteZeebeCommand { async fn execute(self, client: &mut ZeebeClient) -> Result; } +fn install_tracing() { + use tracing_error::ErrorLayer; + use tracing_subscriber::prelude::*; + use tracing_subscriber::EnvFilter; + use tracing_tree::HierarchicalLayer; + + let filter_layer = EnvFilter::try_from_default_env() + .or_else(|_| EnvFilter::try_new("info")) + .unwrap(); + + tracing_subscriber::registry() + .with(filter_layer) + .with(HierarchicalLayer::new(2)) + .with(ErrorLayer::default()) + .init(); +} + #[tokio::main] async fn main() -> Result<()> { - tracing_subscriber::fmt::init(); + install_tracing(); + color_eyre::install()?; + let cli: Cli = Cli::parse(); - let mut client: ZeebeClient = zeebe_client::connect(cli.connection.into()).await?; + let mut client: ZeebeClient = + zeebe_client::connect(cli.connection.into(), cli.auth.try_into()?).await?; let response: Box = match cli.command { Commands::Status(args) => Box::new(args.execute(&mut client).await?), Commands::Deploy(args) => Box::new(args.execute(&mut client).await?), diff --git a/client/Cargo.toml b/client/Cargo.toml index 1603769..07aa1f8 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,10 +4,11 @@ version = "0.1.0" edition = "2021" [dependencies] -tonic = "0.8" +tonic = { version = "0.8", features = ["tls", "tls-roots", "gzip"] } prost = "0.11" thiserror = "1.0" +tracing = { version="0.1", features = ["async-await"] } [build-dependencies] -tonic-build = "0.8" -prost-build = "0.11" \ No newline at end of file +tonic-build = { version = "0.8" } +prost-build = "0.11" diff --git a/client/src/auth.rs b/client/src/auth.rs index d308a0e..83f4228 100644 --- a/client/src/auth.rs +++ b/client/src/auth.rs @@ -1,9 +1,49 @@ use tonic::service::Interceptor; -pub struct AuthInterceptor {} +#[derive(Debug)] +pub struct OAuth2Config { + pub client_id: String, + pub client_secret: String, + pub auth_server: String, + pub audience: String, +} + +pub struct OAuth2Provider { + config: OAuth2Config, +} + +impl OAuth2Provider { + fn get_token(&mut self) -> String { + "fake token".to_owned() + } +} + +pub struct AuthInterceptor { + auth: Option, +} + +impl AuthInterceptor { + pub fn none() -> AuthInterceptor { + AuthInterceptor { auth: None } + } + pub fn oauth2(config: OAuth2Config) -> AuthInterceptor { + AuthInterceptor { + auth: Some(OAuth2Provider { config }), + } + } +} impl Interceptor for AuthInterceptor { - fn call(&mut self, request: tonic::Request<()>) -> Result, tonic::Status> { + fn call( + &mut self, + mut request: tonic::Request<()>, + ) -> Result, tonic::Status> { + if let Some(provider) = &mut self.auth { + let value = provider.get_token().try_into().map_err(|_err| { + tonic::Status::failed_precondition("Couldn't build authorization header") + })?; + request.metadata_mut().insert("authorization", value); + } Ok(request) } } diff --git a/client/src/lib.rs b/client/src/lib.rs index 84fe574..05044bb 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,15 +1,20 @@ -mod auth; +pub mod auth; -use std::str::FromStr; -use auth::AuthInterceptor; + +use auth::{AuthInterceptor, OAuth2Config}; use generated_api::gateway_client::GatewayClient; use thiserror::Error; +use tracing::instrument; use tonic::{ - codegen::http::uri::InvalidUri, + codegen::{ + http::{ + self, + }, + }, service::Interceptor, - transport::{self, Channel, Uri}, + transport::{self, Channel, ClientTlsConfig, Uri}, }; mod generated_api { @@ -21,13 +26,22 @@ pub mod api { } #[derive(Debug)] -pub enum Protocol { - HTTPS, - HTTP, -} pub enum Connection { - Address(String), - HostPort(Protocol, String, u16), + Address { + insecure: bool, + addr: String, + }, + HostPort { + insecure: bool, + host: String, + port: u16, + }, +} + +#[derive(Debug)] +pub enum Authentication { + Unauthenticated, + Oauth2(OAuth2Config), } #[derive(Error, Debug)] @@ -35,7 +49,7 @@ pub enum ConnectionError { #[error(transparent)] Transport(#[from] transport::Error), #[error(transparent)] - Uri(#[from] InvalidUri), + Http(#[from] http::Error), } struct FakeInterceptor {} @@ -45,21 +59,36 @@ impl Interceptor for FakeInterceptor { todo!() } } -// Service::ResponseBody: Body + Send + 'static, -// >::Future: Send; pub type ZeebeClient = GatewayClient>; -pub async fn connect(conn: Connection) -> Result { - let uri = match conn { - Connection::Address(addr) => Uri::from_str(&addr), - Connection::HostPort(proto, host, port) => { - Uri::from_str(&format!("{:?}://{}:{}", proto, host, port)) - } - }?; - let channel = Channel::builder(uri); + +#[instrument] +pub async fn connect( + conn: Connection, + auth: Authentication, +) -> Result { + let uri = Uri::builder() + .scheme(match &conn { + Connection::Address { insecure: true, .. } => "http", + Connection::HostPort { insecure: true, .. } => "http", + _ => "https", + }) + .authority(match &conn { + Connection::Address { addr, .. } => addr.to_owned(), + Connection::HostPort { host, port, .. } => format!("{}:{}", host, port), + }) + .path_and_query("") + .build()?; + let interceptor = match auth { + Authentication::Unauthenticated => AuthInterceptor::none(), + Authentication::Oauth2(oauth_config) => AuthInterceptor::oauth2(oauth_config), + }; + tracing::debug!("Connecting to {}", uri); + + let channel = Channel::builder(uri).tls_config(ClientTlsConfig::new())?; Ok(api::gateway_client::GatewayClient::with_interceptor( channel.connect().await?, - AuthInterceptor {}, + interceptor, )) } From 964a684a48f4d4ec8411e58e6ce7812bc76526c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Thu, 11 Aug 2022 16:53:45 +0200 Subject: [PATCH 27/52] fix: allow insecure connections --- cli/src/main.rs | 2 +- client/src/lib.rs | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index d17249a..6da632f 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -47,7 +47,7 @@ struct Authentication { #[derive(Parser)] #[clap(group = clap::ArgGroup::new("connection"))] struct Connection { - #[clap(long, default_value_t = false)] + #[clap(long)] insecure: bool, #[clap(long, value_parser, group = "connection", env = "ZEEBE_ADDRESS")] diff --git a/client/src/lib.rs b/client/src/lib.rs index 05044bb..3e4cc9c 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,18 +1,12 @@ pub mod auth; - - use auth::{AuthInterceptor, OAuth2Config}; use generated_api::gateway_client::GatewayClient; use thiserror::Error; use tracing::instrument; use tonic::{ - codegen::{ - http::{ - self, - }, - }, + codegen::http::{self}, service::Interceptor, transport::{self, Channel, ClientTlsConfig, Uri}, }; @@ -63,16 +57,19 @@ impl Interceptor for FakeInterceptor { pub type ZeebeClient = GatewayClient>; -#[instrument] +#[instrument(level = "debug")] pub async fn connect( conn: Connection, auth: Authentication, ) -> Result { + let insecure = match conn { + Connection::Address { insecure, .. } => insecure, + Connection::HostPort { insecure, .. } => insecure, + }; let uri = Uri::builder() - .scheme(match &conn { - Connection::Address { insecure: true, .. } => "http", - Connection::HostPort { insecure: true, .. } => "http", - _ => "https", + .scheme(match insecure { + true => "http", + false => "https", }) .authority(match &conn { Connection::Address { addr, .. } => addr.to_owned(), @@ -85,8 +82,11 @@ pub async fn connect( Authentication::Oauth2(oauth_config) => AuthInterceptor::oauth2(oauth_config), }; tracing::debug!("Connecting to {}", uri); - - let channel = Channel::builder(uri).tls_config(ClientTlsConfig::new())?; + let channel = if insecure { + Channel::builder(uri) + } else { + Channel::builder(uri).tls_config(ClientTlsConfig::new())? + }; Ok(api::gateway_client::GatewayClient::with_interceptor( channel.connect().await?, interceptor, From 1c907d5c4951ba7178bdd6db7f63859a09fec678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Thu, 11 Aug 2022 17:57:29 +0200 Subject: [PATCH 28/52] feat: build oauth client --- client/Cargo.toml | 1 + client/src/auth.rs | 19 +++++++++++++++---- client/src/lib.rs | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/client/Cargo.toml b/client/Cargo.toml index 07aa1f8..efa6cdb 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -8,6 +8,7 @@ tonic = { version = "0.8", features = ["tls", "tls-roots", "gzip"] } prost = "0.11" thiserror = "1.0" tracing = { version="0.1", features = ["async-await"] } +oauth2 = "4.2.3" [build-dependencies] tonic-build = { version = "0.8" } diff --git a/client/src/auth.rs b/client/src/auth.rs index 83f4228..ff31bc2 100644 --- a/client/src/auth.rs +++ b/client/src/auth.rs @@ -1,3 +1,4 @@ +use oauth2::{basic::BasicClient, TokenUrl, ClientSecret, AuthUrl, ClientId, url::ParseError}; use tonic::service::Interceptor; #[derive(Debug)] @@ -9,10 +10,20 @@ pub struct OAuth2Config { } pub struct OAuth2Provider { + client: oauth2::basic::BasicClient, config: OAuth2Config, } impl OAuth2Provider { + fn from_config(config: OAuth2Config) -> Result { + let client = BasicClient::new( + ClientId::new(config.client_id.clone()), + Some(ClientSecret::new(config.client_secret.clone())), + AuthUrl::new(config.auth_server.clone())?, + Some(TokenUrl::new(config.auth_server.clone())?), + ); + Ok(OAuth2Provider {config, client}) + } fn get_token(&mut self) -> String { "fake token".to_owned() } @@ -26,10 +37,10 @@ impl AuthInterceptor { pub fn none() -> AuthInterceptor { AuthInterceptor { auth: None } } - pub fn oauth2(config: OAuth2Config) -> AuthInterceptor { - AuthInterceptor { - auth: Some(OAuth2Provider { config }), - } + pub fn oauth2(config: OAuth2Config) -> Result { + Ok(AuthInterceptor { + auth: Some(OAuth2Provider::from_config(config)?), + }) } } diff --git a/client/src/lib.rs b/client/src/lib.rs index 3e4cc9c..9aeb7ae 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -2,6 +2,7 @@ pub mod auth; use auth::{AuthInterceptor, OAuth2Config}; use generated_api::gateway_client::GatewayClient; +use oauth2::url::ParseError; use thiserror::Error; use tracing::instrument; @@ -44,6 +45,8 @@ pub enum ConnectionError { Transport(#[from] transport::Error), #[error(transparent)] Http(#[from] http::Error), + #[error(transparent)] + Oauth2(#[from] ParseError), } struct FakeInterceptor {} @@ -79,7 +82,7 @@ pub async fn connect( .build()?; let interceptor = match auth { Authentication::Unauthenticated => AuthInterceptor::none(), - Authentication::Oauth2(oauth_config) => AuthInterceptor::oauth2(oauth_config), + Authentication::Oauth2(oauth_config) => AuthInterceptor::oauth2(oauth_config)?, }; tracing::debug!("Connecting to {}", uri); let channel = if insecure { From 870a55b945eb26818614c2e8c3c8aa9f76ca0c03 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:04:10 +0200 Subject: [PATCH 29/52] refactor: box activate jobs response in main --- cli/src/activate.rs | 11 +++++++---- cli/src/main.rs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cli/src/activate.rs b/cli/src/activate.rs index b4314b1..b02e175 100644 --- a/cli/src/activate.rs +++ b/cli/src/activate.rs @@ -3,7 +3,10 @@ use async_trait::async_trait; use clap::{Args, Subcommand}; use color_eyre::Result; -use zeebe_client::{api::ActivateJobsRequest, ZeebeClient}; +use zeebe_client::{ + api::{ActivateJobsRequest, ActivateJobsResponse}, + ZeebeClient, +}; #[derive(Debug, Args)] pub(crate) struct ActivateArgs { @@ -43,7 +46,7 @@ impl From<&ActivateJobsArgs> for ActivateJobsRequest { #[async_trait] impl ExecuteZeebeCommand for ActivateArgs { - type Output = Box; + type Output = Vec; #[tracing::instrument(skip(client))] async fn execute(self, client: &mut ZeebeClient) -> Result { @@ -56,12 +59,12 @@ impl ExecuteZeebeCommand for ActivateArgs { async fn handle_activate_jobs_command( client: &mut ZeebeClient, args: &ActivateJobsArgs, -) -> Result> { +) -> Result> { let request: ActivateJobsRequest = args.into(); let mut stream = client.activate_jobs(request).await?.into_inner(); let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); while let Some(response) = stream.message().await? { result.push(response); } - Ok(Box::new(result)) + Ok(result) } diff --git a/cli/src/main.rs b/cli/src/main.rs index 6da632f..166c54b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -167,7 +167,7 @@ async fn main() -> Result<()> { Commands::Publish(args) => args.execute(&mut client).await?, // Already boxed, Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), - Commands::Activate(args) => args.execute(&mut client).await?, // Already boxed + Commands::Activate(args) => Box::new(args.execute(&mut client).await?), Commands::ThrowError(args) => Box::new(args.execute(&mut client).await?), }; From 379068025c780ab1e9ca48e3aa855debf9eec7ce Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:15:52 +0200 Subject: [PATCH 30/52] refactor: box message response in main --- cli/src/main.rs | 2 +- cli/src/publish.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 166c54b..cce4f08 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -164,7 +164,7 @@ async fn main() -> Result<()> { Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), Commands::Create(args) => args.execute(&mut client).await?, // Already boxed - Commands::Publish(args) => args.execute(&mut client).await?, // Already boxed, + Commands::Publish(args) => Box::new(args.execute(&mut client).await?), Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), Commands::Activate(args) => Box::new(args.execute(&mut client).await?), diff --git a/cli/src/publish.rs b/cli/src/publish.rs index 7e1a0f5..2693813 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish.rs @@ -4,7 +4,10 @@ use std::fmt::Debug; use clap::{Args, Subcommand}; -use zeebe_client::{api::PublishMessageRequest, ZeebeClient}; +use zeebe_client::{ + api::{PublishMessageRequest, PublishMessageResponse}, + ZeebeClient, +}; use crate::ExecuteZeebeCommand; @@ -46,7 +49,7 @@ impl From<&PublishMessageArgs> for PublishMessageRequest { #[async_trait] impl ExecuteZeebeCommand for PublishArgs { - type Output = Box; + type Output = PublishMessageResponse; #[tracing::instrument(skip(client))] async fn execute(self, client: &mut ZeebeClient) -> Result { @@ -61,9 +64,7 @@ impl ExecuteZeebeCommand for PublishArgs { async fn handle_publish_message_command( client: &mut ZeebeClient, args: &PublishMessageArgs, -) -> Result> { +) -> Result { let request: PublishMessageRequest = args.into(); - Ok(Box::new( - client.publish_message(request).await?.into_inner(), - )) + Ok(client.publish_message(request).await?.into_inner()) } From 07c606442688eeb8285f84f14be5470ea9bc526f Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:21:06 +0200 Subject: [PATCH 31/52] refactor: rename deploy to deploy resource --- cli/src/{deploy.rs => deploy_resource.rs} | 8 ++++---- cli/src/main.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename cli/src/{deploy.rs => deploy_resource.rs} (83%) diff --git a/cli/src/deploy.rs b/cli/src/deploy_resource.rs similarity index 83% rename from cli/src/deploy.rs rename to cli/src/deploy_resource.rs index bafb972..fb3fb72 100644 --- a/cli/src/deploy.rs +++ b/cli/src/deploy_resource.rs @@ -12,12 +12,12 @@ use crate::ExecuteZeebeCommand; use color_eyre::Result; #[derive(Args)] -pub(crate) struct DeployArgs { +pub(crate) struct DeployResourceArgs { #[clap(required = true, value_parser, value_name = "FILE")] resources: Vec, } #[async_trait] -impl ExecuteZeebeCommand for DeployArgs { +impl ExecuteZeebeCommand for DeployResourceArgs { type Output = DeployResourceResponse; async fn execute(self, client: &mut ZeebeClient) -> Result { @@ -28,10 +28,10 @@ impl ExecuteZeebeCommand for DeployArgs { } } -impl TryFrom<&DeployArgs> for DeployResourceRequest { +impl TryFrom<&DeployResourceArgs> for DeployResourceRequest { type Error = color_eyre::Report; - fn try_from(args: &DeployArgs) -> Result { + fn try_from(args: &DeployResourceArgs) -> Result { let mut resources = Vec::with_capacity(args.resources.len()); for path in &args.resources { let resource = Resource { diff --git a/cli/src/main.rs b/cli/src/main.rs index cce4f08..458e136 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,7 +1,7 @@ mod activate; mod cancel_process_instance; mod create; -mod deploy; +mod deploy_resource; mod fail_job; mod incident; mod publish; @@ -75,8 +75,8 @@ struct Connection { #[derive(Subcommand)] enum Commands { - Status(status::StatusArgs), - Deploy(deploy::DeployArgs), + Status(status::StatusArgs), //aka topology + DeployResource(deploy_resource::DeployResourceArgs), ResolveIncident(incident::IncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), @@ -159,7 +159,7 @@ async fn main() -> Result<()> { zeebe_client::connect(cli.connection.into(), cli.auth.try_into()?).await?; let response: Box = match cli.command { Commands::Status(args) => Box::new(args.execute(&mut client).await?), - Commands::Deploy(args) => Box::new(args.execute(&mut client).await?), + Commands::DeployResource(args) => Box::new(args.execute(&mut client).await?), Commands::ResolveIncident(args) => Box::new(args.execute(&mut client).await?), Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), From 93c59d3872e8b5038afeeec71d7c60feca5256f4 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:24:30 +0200 Subject: [PATCH 32/52] refactor: rename incident to resolve incident --- cli/src/main.rs | 4 ++-- cli/src/{incident.rs => resolve_incident.rs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename cli/src/{incident.rs => resolve_incident.rs} (87%) diff --git a/cli/src/main.rs b/cli/src/main.rs index 458e136..71c9562 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,8 +3,8 @@ mod cancel_process_instance; mod create; mod deploy_resource; mod fail_job; -mod incident; mod publish; +mod resolve_incident; mod retries; mod set_variables; mod status; @@ -77,7 +77,7 @@ struct Connection { enum Commands { Status(status::StatusArgs), //aka topology DeployResource(deploy_resource::DeployResourceArgs), - ResolveIncident(incident::IncidentArgs), + ResolveIncident(resolve_incident::ResolveIncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), Create(create::CreateArgs), diff --git a/cli/src/incident.rs b/cli/src/resolve_incident.rs similarity index 87% rename from cli/src/incident.rs rename to cli/src/resolve_incident.rs index 6710857..82145d9 100644 --- a/cli/src/incident.rs +++ b/cli/src/resolve_incident.rs @@ -10,12 +10,12 @@ use zeebe_client::{ use crate::ExecuteZeebeCommand; #[derive(Args)] -pub struct IncidentArgs { +pub struct ResolveIncidentArgs { incident_key: i64, } #[async_trait] -impl ExecuteZeebeCommand for IncidentArgs { +impl ExecuteZeebeCommand for ResolveIncidentArgs { type Output = ResolveIncidentResponse; async fn execute(self, client: &mut ZeebeClient) -> Result { From b07b45562862ba4a225102f955f80119a263556f Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:40:05 +0200 Subject: [PATCH 33/52] refactor: rename create to create process instance --- .../{create.rs => create_process_instance.rs} | 29 +++++-------------- cli/src/main.rs | 6 ++-- 2 files changed, 10 insertions(+), 25 deletions(-) rename cli/src/{create.rs => create_process_instance.rs} (70%) diff --git a/cli/src/create.rs b/cli/src/create_process_instance.rs similarity index 70% rename from cli/src/create.rs rename to cli/src/create_process_instance.rs index db03692..ddf64dc 100644 --- a/cli/src/create.rs +++ b/cli/src/create_process_instance.rs @@ -1,6 +1,6 @@ use crate::{Debug, ExecuteZeebeCommand}; use async_trait::async_trait; -use clap::{Args, Subcommand}; +use clap::Args; use color_eyre::eyre::Result; use zeebe_client::{ api::{CreateProcessInstanceRequest, CreateProcessInstanceWithResultRequest}, @@ -8,18 +8,7 @@ use zeebe_client::{ }; #[derive(Args, Clone, Debug)] -pub(crate) struct CreateArgs { - #[clap(subcommand)] - resource_type: CreateResourceType, -} - -#[derive(Subcommand, Clone, Debug)] -enum CreateResourceType { - Instance(CreateInstanceArgs), -} - -#[derive(Args, Clone, Debug)] -struct CreateInstanceArgs { +pub(crate) struct CreateProcessInstanceArgs { process: i64, #[clap(long, required = false)] @@ -30,8 +19,8 @@ struct CreateInstanceArgs { version: i32, } -impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { - fn from(args: &CreateInstanceArgs) -> Self { +impl From<&CreateProcessInstanceArgs> for CreateProcessInstanceRequest { + fn from(args: &CreateProcessInstanceArgs) -> Self { CreateProcessInstanceRequest { process_definition_key: args.process, bpmn_process_id: String::new(), @@ -43,22 +32,18 @@ impl From<&CreateInstanceArgs> for CreateProcessInstanceRequest { } #[async_trait] -impl ExecuteZeebeCommand for CreateArgs { +impl ExecuteZeebeCommand for CreateProcessInstanceArgs { type Output = Box; #[tracing::instrument(skip(client))] async fn execute(self, client: &mut ZeebeClient) -> Result { - match &self.resource_type { - CreateResourceType::Instance(args) => { - handle_create_instance_command(client, args).await - } - } + handle_create_instance_command(client, &self).await } } async fn handle_create_instance_command( client: &mut ZeebeClient, - args: &CreateInstanceArgs, + args: &CreateProcessInstanceArgs, ) -> Result> { let request: CreateProcessInstanceRequest = args.into(); match args.with_results { diff --git a/cli/src/main.rs b/cli/src/main.rs index 71c9562..bc5dda2 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,6 +1,6 @@ mod activate; mod cancel_process_instance; -mod create; +mod create_process_instance; mod deploy_resource; mod fail_job; mod publish; @@ -80,7 +80,7 @@ enum Commands { ResolveIncident(resolve_incident::ResolveIncidentArgs), CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), - Create(create::CreateArgs), + CreateProcessInstance(create_process_instance::CreateProcessInstanceArgs), Publish(publish::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), SetVariables(set_variables::SetVariablesArgs), @@ -163,7 +163,7 @@ async fn main() -> Result<()> { Commands::ResolveIncident(args) => Box::new(args.execute(&mut client).await?), Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), - Commands::Create(args) => args.execute(&mut client).await?, // Already boxed + Commands::CreateProcessInstance(args) => args.execute(&mut client).await?, // Already boxed, because it could be one of two results Commands::Publish(args) => Box::new(args.execute(&mut client).await?), Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), From 0af837d503a80176cfe613e064a75e649142f4d2 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:46:44 +0200 Subject: [PATCH 34/52] refactor: rename publish to publihs message --- cli/src/main.rs | 6 ++-- cli/src/{publish.rs => publish_message.rs} | 33 ++++------------------ 2 files changed, 9 insertions(+), 30 deletions(-) rename cli/src/{publish.rs => publish_message.rs} (57%) diff --git a/cli/src/main.rs b/cli/src/main.rs index bc5dda2..8c6e2fc 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -3,7 +3,7 @@ mod cancel_process_instance; mod create_process_instance; mod deploy_resource; mod fail_job; -mod publish; +mod publish_message; mod resolve_incident; mod retries; mod set_variables; @@ -81,7 +81,7 @@ enum Commands { CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), CreateProcessInstance(create_process_instance::CreateProcessInstanceArgs), - Publish(publish::PublishArgs), + PublishMessage(publish_message::PublishArgs), UpdateRetries(retries::UpdateRetriesArgs), SetVariables(set_variables::SetVariablesArgs), Activate(activate::ActivateArgs), @@ -164,7 +164,7 @@ async fn main() -> Result<()> { Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), Commands::CreateProcessInstance(args) => args.execute(&mut client).await?, // Already boxed, because it could be one of two results - Commands::Publish(args) => Box::new(args.execute(&mut client).await?), + Commands::PublishMessage(args) => Box::new(args.execute(&mut client).await?), Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), Commands::Activate(args) => Box::new(args.execute(&mut client).await?), diff --git a/cli/src/publish.rs b/cli/src/publish_message.rs similarity index 57% rename from cli/src/publish.rs rename to cli/src/publish_message.rs index 2693813..5057687 100644 --- a/cli/src/publish.rs +++ b/cli/src/publish_message.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use color_eyre::eyre::Result; use std::fmt::Debug; -use clap::{Args, Subcommand}; +use clap::Args; use zeebe_client::{ api::{PublishMessageRequest, PublishMessageResponse}, @@ -13,17 +13,6 @@ use crate::ExecuteZeebeCommand; #[derive(Args, Clone, Debug)] pub(crate) struct PublishArgs { - #[clap(subcommand)] - resource_type: PublishResourceType, -} - -#[derive(Subcommand, Clone, Debug)] -enum PublishResourceType { - Message(PublishMessageArgs), -} - -#[derive(Args, Clone, Debug)] -struct PublishMessageArgs { name: String, #[clap(long)] correlation_key: String, @@ -35,8 +24,8 @@ struct PublishMessageArgs { ttl: i64, // todo: should be duration } -impl From<&PublishMessageArgs> for PublishMessageRequest { - fn from(args: &PublishMessageArgs) -> Self { +impl From<&PublishArgs> for PublishMessageRequest { + fn from(args: &PublishArgs) -> Self { PublishMessageRequest { name: args.name.to_owned(), correlation_key: args.correlation_key.to_owned(), @@ -53,18 +42,8 @@ impl ExecuteZeebeCommand for PublishArgs { #[tracing::instrument(skip(client))] async fn execute(self, client: &mut ZeebeClient) -> Result { - match &self.resource_type { - PublishResourceType::Message(args) => { - handle_publish_message_command(client, args).await - } - } + let args = &self; + let request: PublishMessageRequest = args.into(); + Ok(client.publish_message(request).await?.into_inner()) } } - -async fn handle_publish_message_command( - client: &mut ZeebeClient, - args: &PublishMessageArgs, -) -> Result { - let request: PublishMessageRequest = args.into(); - Ok(client.publish_message(request).await?.into_inner()) -} From c69af6d60e226f6f8ae09172c9565b3d94fb5ea1 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:48:14 +0200 Subject: [PATCH 35/52] fixup refactor: rename publish to publish message --- cli/src/main.rs | 2 +- cli/src/publish_message.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 8c6e2fc..3a40d11 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -81,7 +81,7 @@ enum Commands { CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), FailJob(fail_job::FailJobArgs), CreateProcessInstance(create_process_instance::CreateProcessInstanceArgs), - PublishMessage(publish_message::PublishArgs), + PublishMessage(publish_message::PublishMessageArgs), UpdateRetries(retries::UpdateRetriesArgs), SetVariables(set_variables::SetVariablesArgs), Activate(activate::ActivateArgs), diff --git a/cli/src/publish_message.rs b/cli/src/publish_message.rs index 5057687..984a22a 100644 --- a/cli/src/publish_message.rs +++ b/cli/src/publish_message.rs @@ -12,7 +12,7 @@ use zeebe_client::{ use crate::ExecuteZeebeCommand; #[derive(Args, Clone, Debug)] -pub(crate) struct PublishArgs { +pub(crate) struct PublishMessageArgs { name: String, #[clap(long)] correlation_key: String, @@ -24,8 +24,8 @@ pub(crate) struct PublishArgs { ttl: i64, // todo: should be duration } -impl From<&PublishArgs> for PublishMessageRequest { - fn from(args: &PublishArgs) -> Self { +impl From<&PublishMessageArgs> for PublishMessageRequest { + fn from(args: &PublishMessageArgs) -> Self { PublishMessageRequest { name: args.name.to_owned(), correlation_key: args.correlation_key.to_owned(), @@ -37,7 +37,7 @@ impl From<&PublishArgs> for PublishMessageRequest { } #[async_trait] -impl ExecuteZeebeCommand for PublishArgs { +impl ExecuteZeebeCommand for PublishMessageArgs { type Output = PublishMessageResponse; #[tracing::instrument(skip(client))] From aa7536c9fa934453d0b3679cf5ea797cd4b499a9 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:49:38 +0200 Subject: [PATCH 36/52] fixup refactor: rename retries to update retries --- cli/src/main.rs | 4 ++-- cli/src/{retries.rs => update_retries.rs} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename cli/src/{retries.rs => update_retries.rs} (100%) diff --git a/cli/src/main.rs b/cli/src/main.rs index 3a40d11..649c021 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -5,10 +5,10 @@ mod deploy_resource; mod fail_job; mod publish_message; mod resolve_incident; -mod retries; mod set_variables; mod status; mod throw_error; +mod update_retries; use std::fmt::Debug; @@ -82,7 +82,7 @@ enum Commands { FailJob(fail_job::FailJobArgs), CreateProcessInstance(create_process_instance::CreateProcessInstanceArgs), PublishMessage(publish_message::PublishMessageArgs), - UpdateRetries(retries::UpdateRetriesArgs), + UpdateRetries(update_retries::UpdateRetriesArgs), SetVariables(set_variables::SetVariablesArgs), Activate(activate::ActivateArgs), ThrowError(throw_error::ThrowErrorArgs), diff --git a/cli/src/retries.rs b/cli/src/update_retries.rs similarity index 100% rename from cli/src/retries.rs rename to cli/src/update_retries.rs From 830cbf16537a8796776014c73383c4bd51aa73bd Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 11:54:41 +0200 Subject: [PATCH 37/52] fixup refactor: rename active to activate jobs --- cli/src/{activate.rs => activate_jobs.rs} | 39 ++++++----------------- cli/src/main.rs | 6 ++-- 2 files changed, 13 insertions(+), 32 deletions(-) rename cli/src/{activate.rs => activate_jobs.rs} (55%) diff --git a/cli/src/activate.rs b/cli/src/activate_jobs.rs similarity index 55% rename from cli/src/activate.rs rename to cli/src/activate_jobs.rs index b02e175..46d1206 100644 --- a/cli/src/activate.rs +++ b/cli/src/activate_jobs.rs @@ -1,6 +1,6 @@ use crate::{Debug, ExecuteZeebeCommand}; use async_trait::async_trait; -use clap::{Args, Subcommand}; +use clap::Args; use color_eyre::Result; use zeebe_client::{ @@ -9,18 +9,7 @@ use zeebe_client::{ }; #[derive(Debug, Args)] -pub(crate) struct ActivateArgs { - #[clap(subcommand)] - resource_type: ActivateResourceType, -} - -#[derive(Debug, Subcommand)] -enum ActivateResourceType { - Jobs(ActivateJobsArgs), -} - -#[derive(Args, Debug)] -struct ActivateJobsArgs { +pub(crate) struct ActivateJobsArgs { job_type: String, #[clap(long, default_value_t = 1)] max_jobs_to_activate: u32, @@ -45,26 +34,18 @@ impl From<&ActivateJobsArgs> for ActivateJobsRequest { } #[async_trait] -impl ExecuteZeebeCommand for ActivateArgs { +impl ExecuteZeebeCommand for ActivateJobsArgs { type Output = Vec; #[tracing::instrument(skip(client))] async fn execute(self, client: &mut ZeebeClient) -> Result { - match &self.resource_type { - ActivateResourceType::Jobs(args) => handle_activate_jobs_command(client, args).await, + let args = &self; + let request: ActivateJobsRequest = args.into(); + let mut stream = client.activate_jobs(request).await?.into_inner(); + let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); + while let Some(response) = stream.message().await? { + result.push(response); } + Ok(result) } } - -async fn handle_activate_jobs_command( - client: &mut ZeebeClient, - args: &ActivateJobsArgs, -) -> Result> { - let request: ActivateJobsRequest = args.into(); - let mut stream = client.activate_jobs(request).await?.into_inner(); - let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); - while let Some(response) = stream.message().await? { - result.push(response); - } - Ok(result) -} diff --git a/cli/src/main.rs b/cli/src/main.rs index 649c021..84d929f 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,4 +1,4 @@ -mod activate; +mod activate_jobs; mod cancel_process_instance; mod create_process_instance; mod deploy_resource; @@ -84,7 +84,7 @@ enum Commands { PublishMessage(publish_message::PublishMessageArgs), UpdateRetries(update_retries::UpdateRetriesArgs), SetVariables(set_variables::SetVariablesArgs), - Activate(activate::ActivateArgs), + ActivateJobs(activate_jobs::ActivateJobsArgs), ThrowError(throw_error::ThrowErrorArgs), } @@ -167,7 +167,7 @@ async fn main() -> Result<()> { Commands::PublishMessage(args) => Box::new(args.execute(&mut client).await?), Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), - Commands::Activate(args) => Box::new(args.execute(&mut client).await?), + Commands::ActivateJobs(args) => Box::new(args.execute(&mut client).await?), Commands::ThrowError(args) => Box::new(args.execute(&mut client).await?), }; From 93012c5bfb5e1896b151c01a2cf459f74943362d Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 12:01:01 +0200 Subject: [PATCH 38/52] fixup refactor: reorder commands --- cli/src/main.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 84d929f..7a96ba9 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -75,16 +75,29 @@ struct Connection { #[derive(Subcommand)] enum Commands { + // status Status(status::StatusArgs), //aka topology + + // deployment DeployResource(deploy_resource::DeployResourceArgs), - ResolveIncident(resolve_incident::ResolveIncidentArgs), - CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), - FailJob(fail_job::FailJobArgs), + + // process instance CreateProcessInstance(create_process_instance::CreateProcessInstanceArgs), + CancelProcessInstance(cancel_process_instance::CancelProcessInstanceArgs), + + // message PublishMessage(publish_message::PublishMessageArgs), - UpdateRetries(update_retries::UpdateRetriesArgs), + + // incident + ResolveIncident(resolve_incident::ResolveIncidentArgs), + + // variables SetVariables(set_variables::SetVariablesArgs), + + //jobs ActivateJobs(activate_jobs::ActivateJobsArgs), + FailJob(fail_job::FailJobArgs), + UpdateRetries(update_retries::UpdateRetriesArgs), ThrowError(throw_error::ThrowErrorArgs), } @@ -158,17 +171,17 @@ async fn main() -> Result<()> { let mut client: ZeebeClient = zeebe_client::connect(cli.connection.into(), cli.auth.try_into()?).await?; let response: Box = match cli.command { - Commands::Status(args) => Box::new(args.execute(&mut client).await?), - Commands::DeployResource(args) => Box::new(args.execute(&mut client).await?), - Commands::ResolveIncident(args) => Box::new(args.execute(&mut client).await?), + Commands::ActivateJobs(args) => Box::new(args.execute(&mut client).await?), Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), - Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), Commands::CreateProcessInstance(args) => args.execute(&mut client).await?, // Already boxed, because it could be one of two results + Commands::DeployResource(args) => Box::new(args.execute(&mut client).await?), + Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), Commands::PublishMessage(args) => Box::new(args.execute(&mut client).await?), - Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), + Commands::ResolveIncident(args) => Box::new(args.execute(&mut client).await?), Commands::SetVariables(args) => Box::new(args.execute(&mut client).await?), - Commands::ActivateJobs(args) => Box::new(args.execute(&mut client).await?), + Commands::Status(args) => Box::new(args.execute(&mut client).await?), Commands::ThrowError(args) => Box::new(args.execute(&mut client).await?), + Commands::UpdateRetries(args) => Box::new(args.execute(&mut client).await?), }; println!("{:#?}", response); From e7e5313acb17e86e7ed18bf065dd4140abae33df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Fri, 12 Aug 2022 12:23:23 +0200 Subject: [PATCH 39/52] feat: request oauth tokens --- cli/src/main.rs | 2 +- client/Cargo.toml | 2 +- client/src/auth.rs | 57 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 7a96ba9..458779a 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -128,7 +128,7 @@ impl TryFrom for zeebe_client::Authentication { client_id, client_secret, auth_server: auth.authorization_server, - audience: "zeebe".to_owned(), + audience: "zeebe.camunda.io".to_owned(), }, )), _ => Err(color_eyre::eyre::eyre!( diff --git a/client/Cargo.toml b/client/Cargo.toml index efa6cdb..56e815b 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -8,7 +8,7 @@ tonic = { version = "0.8", features = ["tls", "tls-roots", "gzip"] } prost = "0.11" thiserror = "1.0" tracing = { version="0.1", features = ["async-await"] } -oauth2 = "4.2.3" +oauth2 = { version = "4.2.3", features = ["ureq"] } [build-dependencies] tonic-build = { version = "0.8" } diff --git a/client/src/auth.rs b/client/src/auth.rs index ff31bc2..6161026 100644 --- a/client/src/auth.rs +++ b/client/src/auth.rs @@ -1,5 +1,12 @@ -use oauth2::{basic::BasicClient, TokenUrl, ClientSecret, AuthUrl, ClientId, url::ParseError}; -use tonic::service::Interceptor; +use oauth2::{ + basic::{BasicClient, BasicTokenResponse}, + url::ParseError, + AuthUrl, ClientId, ClientSecret, + TokenResponse, TokenUrl, +}; +use thiserror::Error; +use tonic::{metadata::MetadataValue, service::Interceptor}; +use tracing::instrument; #[derive(Debug)] pub struct OAuth2Config { @@ -9,11 +16,18 @@ pub struct OAuth2Config { pub audience: String, } +#[derive(Debug)] pub struct OAuth2Provider { client: oauth2::basic::BasicClient, config: OAuth2Config, } +#[derive(Error, Debug)] +pub enum AuthError { + #[error("Token request failed")] + TokenRequestFailed, +} + impl OAuth2Provider { fn from_config(config: OAuth2Config) -> Result { let client = BasicClient::new( @@ -21,11 +35,22 @@ impl OAuth2Provider { Some(ClientSecret::new(config.client_secret.clone())), AuthUrl::new(config.auth_server.clone())?, Some(TokenUrl::new(config.auth_server.clone())?), - ); - Ok(OAuth2Provider {config, client}) + ).set_auth_type(oauth2::AuthType::RequestBody); + Ok(OAuth2Provider { config, client }) } - fn get_token(&mut self) -> String { - "fake token".to_owned() + + #[instrument] + fn get_token(&mut self) -> Result { + let request = self.client + .exchange_client_credentials() + .add_extra_param("audience", &self.config.audience); + tracing::debug!(request = ?request, "requesting token"); + request + .request(oauth2::ureq::http_client) + .map_err(|e| { + tracing::error!(error = ?e, "request to get token failed"); + AuthError::TokenRequestFailed + }) } } @@ -49,11 +74,23 @@ impl Interceptor for AuthInterceptor { &mut self, mut request: tonic::Request<()>, ) -> Result, tonic::Status> { + // TODO: Don't request a new token for every request. Look into tower to handle this + // elegantly. if let Some(provider) = &mut self.auth { - let value = provider.get_token().try_into().map_err(|_err| { - tonic::Status::failed_precondition("Couldn't build authorization header") - })?; - request.metadata_mut().insert("authorization", value); + let token = match provider.get_token() { + Ok(token) => token.access_token().secret().to_owned(), + Err(e) => { + tracing::error!(error = ?e, "failed to get token"); + return Err(tonic::Status::unauthenticated("failed to get token")); + }, + }; + let header_value = format!("Bearer {}", token); + request.metadata_mut().insert( + "authorization", + MetadataValue::from_str(&header_value).map_err(|_| { + tonic::Status::unauthenticated("token is not a valid header value") + })?, + ); } Ok(request) } From 36df6a6245fea7df43273124680f89c86582d070 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 14:32:04 +0200 Subject: [PATCH 40/52] refactor: code cleanup --- client/src/auth.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/client/src/auth.rs b/client/src/auth.rs index 6161026..329bfc5 100644 --- a/client/src/auth.rs +++ b/client/src/auth.rs @@ -1,8 +1,7 @@ use oauth2::{ basic::{BasicClient, BasicTokenResponse}, url::ParseError, - AuthUrl, ClientId, ClientSecret, - TokenResponse, TokenUrl, + AuthUrl, ClientId, ClientSecret, TokenResponse, TokenUrl, }; use thiserror::Error; use tonic::{metadata::MetadataValue, service::Interceptor}; @@ -18,7 +17,7 @@ pub struct OAuth2Config { #[derive(Debug)] pub struct OAuth2Provider { - client: oauth2::basic::BasicClient, + client: BasicClient, config: OAuth2Config, } @@ -35,22 +34,22 @@ impl OAuth2Provider { Some(ClientSecret::new(config.client_secret.clone())), AuthUrl::new(config.auth_server.clone())?, Some(TokenUrl::new(config.auth_server.clone())?), - ).set_auth_type(oauth2::AuthType::RequestBody); + ) + .set_auth_type(oauth2::AuthType::RequestBody); Ok(OAuth2Provider { config, client }) } #[instrument] fn get_token(&mut self) -> Result { - let request = self.client + let request = self + .client .exchange_client_credentials() .add_extra_param("audience", &self.config.audience); tracing::debug!(request = ?request, "requesting token"); - request - .request(oauth2::ureq::http_client) - .map_err(|e| { - tracing::error!(error = ?e, "request to get token failed"); - AuthError::TokenRequestFailed - }) + request.request(oauth2::ureq::http_client).map_err(|e| { + tracing::error!(error = ?e, "request to get token failed"); + AuthError::TokenRequestFailed + }) } } @@ -79,10 +78,10 @@ impl Interceptor for AuthInterceptor { if let Some(provider) = &mut self.auth { let token = match provider.get_token() { Ok(token) => token.access_token().secret().to_owned(), - Err(e) => { + Err(e) => { tracing::error!(error = ?e, "failed to get token"); return Err(tonic::Status::unauthenticated("failed to get token")); - }, + } }; let header_value = format!("Bearer {}", token); request.metadata_mut().insert( From 2b6fbc7e86cb543ba04cd9bf5bd7fb7f531c6258 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 14:48:58 +0200 Subject: [PATCH 41/52] feat: add complete job command --- cli/src/complete_job.rs | 38 ++++++++++++++++++++++++++++++++++++++ cli/src/main.rs | 3 +++ 2 files changed, 41 insertions(+) create mode 100644 cli/src/complete_job.rs diff --git a/cli/src/complete_job.rs b/cli/src/complete_job.rs new file mode 100644 index 0000000..6a6d9fb --- /dev/null +++ b/cli/src/complete_job.rs @@ -0,0 +1,38 @@ +use crate::{Debug, ExecuteZeebeCommand}; +use async_trait::async_trait; +use clap::Args; +use color_eyre::eyre::Result; +use zeebe_client::{ + api::{CompleteJobRequest, CompleteJobResponse}, + ZeebeClient, +}; + +#[derive(Args, Clone, Debug)] +pub(crate) struct CompleteJobArgs { + #[clap(short, long)] + job_key: i64, + + #[clap(long, required = false, default_value = "")] + variables: String, +} + +impl From<&CompleteJobArgs> for CompleteJobRequest { + fn from(args: &CompleteJobArgs) -> Self { + CompleteJobRequest { + job_key: args.job_key, + variables: args.variables.clone(), + } + } +} + +#[async_trait] +impl ExecuteZeebeCommand for CompleteJobArgs { + type Output = CompleteJobResponse; + + #[tracing::instrument(skip(client))] + async fn execute(self, client: &mut ZeebeClient) -> Result { + let args = &self; + let request: CompleteJobRequest = args.into(); + Ok(client.complete_job(request).await?.into_inner()) + } +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 458779a..1791f17 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,5 +1,6 @@ mod activate_jobs; mod cancel_process_instance; +mod complete_job; mod create_process_instance; mod deploy_resource; mod fail_job; @@ -96,6 +97,7 @@ enum Commands { //jobs ActivateJobs(activate_jobs::ActivateJobsArgs), + CompleteJob(complete_job::CompleteJobArgs), FailJob(fail_job::FailJobArgs), UpdateRetries(update_retries::UpdateRetriesArgs), ThrowError(throw_error::ThrowErrorArgs), @@ -173,6 +175,7 @@ async fn main() -> Result<()> { let response: Box = match cli.command { Commands::ActivateJobs(args) => Box::new(args.execute(&mut client).await?), Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), + Commands::CompleteJob(args) => Box::new(args.execute(&mut client).await?), Commands::CreateProcessInstance(args) => args.execute(&mut client).await?, // Already boxed, because it could be one of two results Commands::DeployResource(args) => Box::new(args.execute(&mut client).await?), Commands::FailJob(args) => Box::new(args.execute(&mut client).await?), From bf531156015b5354892ffcad4ca826a21bd3e3e1 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 14:55:43 +0200 Subject: [PATCH 42/52] refactor: use pub(crate) consistently --- cli/src/cancel_process_instance.rs | 2 +- cli/src/fail_job.rs | 2 +- cli/src/resolve_incident.rs | 2 +- cli/src/status.rs | 2 +- cli/src/throw_error.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cli/src/cancel_process_instance.rs b/cli/src/cancel_process_instance.rs index 85279cd..98d9149 100644 --- a/cli/src/cancel_process_instance.rs +++ b/cli/src/cancel_process_instance.rs @@ -10,7 +10,7 @@ use zeebe_client::{ use crate::ExecuteZeebeCommand; #[derive(Args)] -pub struct CancelProcessInstanceArgs { +pub(crate) struct CancelProcessInstanceArgs { process_instance_key: i64, } diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs index 5bf6b42..cf86fc3 100644 --- a/cli/src/fail_job.rs +++ b/cli/src/fail_job.rs @@ -9,7 +9,7 @@ use zeebe_client::{ ZeebeClient, }; #[derive(Args)] -pub struct FailJobArgs { +pub(crate) struct FailJobArgs { // the unique job identifier, as obtained when activating the job #[clap(required = true, short, long)] job_key: i64, diff --git a/cli/src/resolve_incident.rs b/cli/src/resolve_incident.rs index 82145d9..5fca9ce 100644 --- a/cli/src/resolve_incident.rs +++ b/cli/src/resolve_incident.rs @@ -10,7 +10,7 @@ use zeebe_client::{ use crate::ExecuteZeebeCommand; #[derive(Args)] -pub struct ResolveIncidentArgs { +pub(crate) struct ResolveIncidentArgs { incident_key: i64, } diff --git a/cli/src/status.rs b/cli/src/status.rs index 8dfc34a..936ec7d 100644 --- a/cli/src/status.rs +++ b/cli/src/status.rs @@ -9,7 +9,7 @@ use zeebe_client::{ }; #[derive(Args)] -pub struct StatusArgs {} +pub(crate) struct StatusArgs {} #[async_trait] impl ExecuteZeebeCommand for StatusArgs { diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs index f8150a7..efe0840 100644 --- a/cli/src/throw_error.rs +++ b/cli/src/throw_error.rs @@ -10,7 +10,7 @@ use zeebe_client::{ use crate::ExecuteZeebeCommand; #[derive(Args)] -pub struct ThrowErrorArgs { +pub(crate) struct ThrowErrorArgs { // the unique job identifier, as obtained when activating the job #[clap(short, long)] job_key: i64, From 32d146660ad7d51d236a13835fa1934b750cc37d Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 15:41:01 +0200 Subject: [PATCH 43/52] refactor: harmonize CLI annotations following the conventions described in README.md --- README.md | 10 ++++++++++ cli/src/activate_jobs.rs | 6 ++++-- cli/src/complete_job.rs | 1 - cli/src/create_process_instance.rs | 4 ++-- cli/src/fail_job.rs | 8 ++++---- cli/src/publish_message.rs | 5 +++-- cli/src/set_variables.rs | 3 ++- cli/src/throw_error.rs | 2 +- cli/src/update_retries.rs | 4 ++-- 9 files changed, 28 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6dbee2b..0732d15 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,13 @@ These repositories also implement Zeebe clients for Rust. Most of them are more Your best choice is probably: https://github.com/OutThereLabs/zeebe-rust + +# Developer Guide + +## CLI + +Conventions: +* Named parameters by default +* Use positional parameters only if there is just one parameter, or just one required parameter +* For required parameters use short and long version `#[clap(short, long)]` +* For optional parameters use long version only `#[clap(long, default_value_t = 1)]` diff --git a/cli/src/activate_jobs.rs b/cli/src/activate_jobs.rs index 46d1206..a085d5d 100644 --- a/cli/src/activate_jobs.rs +++ b/cli/src/activate_jobs.rs @@ -11,10 +11,12 @@ use zeebe_client::{ #[derive(Debug, Args)] pub(crate) struct ActivateJobsArgs { job_type: String, - #[clap(long, default_value_t = 1)] + + #[clap(short, long, default_value_t = 10)] max_jobs_to_activate: u32, - #[clap(long, default_value_t = 5 * 60 * 1000)] + #[clap(short= 't', long, default_value_t = 5 * 60 * 1000)] job_timeout: u64, // todo: should be duration + #[clap(long, required = false, default_value = "worker")] worker: String, #[clap(long, required = false)] variables: Vec, diff --git a/cli/src/complete_job.rs b/cli/src/complete_job.rs index 6a6d9fb..7cd72b2 100644 --- a/cli/src/complete_job.rs +++ b/cli/src/complete_job.rs @@ -9,7 +9,6 @@ use zeebe_client::{ #[derive(Args, Clone, Debug)] pub(crate) struct CompleteJobArgs { - #[clap(short, long)] job_key: i64, #[clap(long, required = false, default_value = "")] diff --git a/cli/src/create_process_instance.rs b/cli/src/create_process_instance.rs index ddf64dc..d184e94 100644 --- a/cli/src/create_process_instance.rs +++ b/cli/src/create_process_instance.rs @@ -9,7 +9,7 @@ use zeebe_client::{ #[derive(Args, Clone, Debug)] pub(crate) struct CreateProcessInstanceArgs { - process: i64, + process_instance_key: i64, #[clap(long, required = false)] with_results: bool, @@ -22,7 +22,7 @@ pub(crate) struct CreateProcessInstanceArgs { impl From<&CreateProcessInstanceArgs> for CreateProcessInstanceRequest { fn from(args: &CreateProcessInstanceArgs) -> Self { CreateProcessInstanceRequest { - process_definition_key: args.process, + process_definition_key: args.process_instance_key, bpmn_process_id: String::new(), version: args.version, variables: args.variables.clone(), diff --git a/cli/src/fail_job.rs b/cli/src/fail_job.rs index cf86fc3..1b8ab67 100644 --- a/cli/src/fail_job.rs +++ b/cli/src/fail_job.rs @@ -11,18 +11,18 @@ use zeebe_client::{ #[derive(Args)] pub(crate) struct FailJobArgs { // the unique job identifier, as obtained when activating the job - #[clap(required = true, short, long)] + #[clap(short, long)] job_key: i64, // the amount of retries the job should have left - #[clap(required = true, short, long)] + #[clap(short, long)] retries: i32, // an optional message describing why the job failed // this is particularly useful if a job runs out of retries and an incident is raised, // as it this message can help explain why an incident was raised - #[clap(required = false, short, long, default_value = "")] + #[clap(long, required = false, default_value = "")] error_message: String, // the back off timeout for the next retry - #[clap(required = false, short = 'b', long, default_value = "0")] + #[clap(long, required = false, default_value_t = 0)] retry_back_off: i64, } diff --git a/cli/src/publish_message.rs b/cli/src/publish_message.rs index 984a22a..770a787 100644 --- a/cli/src/publish_message.rs +++ b/cli/src/publish_message.rs @@ -13,10 +13,11 @@ use crate::ExecuteZeebeCommand; #[derive(Args, Clone, Debug)] pub(crate) struct PublishMessageArgs { + #[clap(short, long)] name: String, - #[clap(long)] + #[clap(short, long)] correlation_key: String, - #[clap(long)] + #[clap(long, required = false)] message_id: String, #[clap(long, required = false, default_value = "")] variables: String, diff --git a/cli/src/set_variables.rs b/cli/src/set_variables.rs index 26968e7..447e1e3 100644 --- a/cli/src/set_variables.rs +++ b/cli/src/set_variables.rs @@ -13,8 +13,9 @@ use zeebe_client::{ #[derive(Args)] pub(crate) struct SetVariablesArgs { + #[clap(short, long)] element_instance_key: i64, - #[clap(long)] + #[clap(short, long)] local: bool, #[clap(long, value_parser, group = "value")] path: Option, diff --git a/cli/src/throw_error.rs b/cli/src/throw_error.rs index efe0840..4047c20 100644 --- a/cli/src/throw_error.rs +++ b/cli/src/throw_error.rs @@ -18,7 +18,7 @@ pub(crate) struct ThrowErrorArgs { #[clap(short = 'c', long)] error_code: String, // an optional error message that provides additional context - #[clap(short = 'm', long, default_value = "")] + #[clap(long, default_value = "")] error_message: String, } diff --git a/cli/src/update_retries.rs b/cli/src/update_retries.rs index 4d6824f..ae882f2 100644 --- a/cli/src/update_retries.rs +++ b/cli/src/update_retries.rs @@ -10,9 +10,9 @@ use zeebe_client::{ #[derive(Debug, Args)] pub(crate) struct UpdateRetriesArgs { - #[clap(long)] + #[clap(short, long)] job_key: u64, - #[clap(long)] + #[clap(short, long)] retries: u32, } From 9cb1e219ac57568bc385344f46712ca5dc703288 Mon Sep 17 00:00:00 2001 From: pihme Date: Fri, 12 Aug 2022 15:44:32 +0200 Subject: [PATCH 44/52] docs: improve readme --- README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0732d15..8b65170 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,16 @@ # Zeebe Rust Client -Rust client for Zeebe +Rust client for Zeebe in early stages. Suitable for early adopters -In very early stages. +Features +* CLI for all commands based on Zeebe Client 8.0 +* Support for OAuth authentication + +Next Steps +1. Worker implementation +2. Publish crates +3. Build an application that uses this Rust client ## Prior Work/Alternatives @@ -23,7 +30,7 @@ Your best choice is probably: https://github.com/OutThereLabs/zeebe-rust ## CLI -Conventions: +**Conventions for CLI Argument Annotations** * Named parameters by default * Use positional parameters only if there is just one parameter, or just one required parameter * For required parameters use short and long version `#[clap(short, long)]` From 48585f20ddf5462e9ad8d87cac20a1c5395d932d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Fri, 12 Aug 2022 16:15:10 +0200 Subject: [PATCH 45/52] docs: add README content for the cli tool --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/README.md b/README.md index 8b65170..25812b5 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,44 @@ Next Steps 2. Publish crates 3. Build an application that uses this Rust client +## Cli Tool + +> **Warning** +> The Cli Tool might leak credentials in log messages + +Run `cargo run -- help` to see available commands and options. + +**Authentication for Camunda Cloud** + +First, [generate and download](https://docs.camunda.io/docs/next/components/console/manage-clusters/manage-api-clients/) client credentials from Console. Let's assume they are in a file called credentials.txt. + +The `credentials.txt` file contains environment variables, so let's source them: +```shell +$ source credentials.txt +``` + +Finally, run the cli tool: + +```shell +$ cargo run -- status +TopologyResponse { + brokers: [ + BrokerInfo { + node_id: 0, +... +``` + +Alternatively, you can also provide your credentials as arguments: + +```shell +$ cargo run -- --address
--client-id --client_secret --authorization-server status +TopologyResponse { + brokers: [ + BrokerInfo { + node_id: 0, +... +``` + ## Prior Work/Alternatives These repositories also implement Zeebe clients for Rust. Most of them are more feature-complete than this repository currently, but also a little older. From e0dbd8bf1781d756e76c79c4b9e3a3441188dc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 17:16:52 +0200 Subject: [PATCH 46/52] fix: remove dead code --- client/src/lib.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 9aeb7ae..1826303 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -8,7 +8,6 @@ use tracing::instrument; use tonic::{ codegen::http::{self}, - service::Interceptor, transport::{self, Channel, ClientTlsConfig, Uri}, }; @@ -49,14 +48,6 @@ pub enum ConnectionError { Oauth2(#[from] ParseError), } -struct FakeInterceptor {} - -impl Interceptor for FakeInterceptor { - fn call(&mut self, _request: tonic::Request<()>) -> Result, tonic::Status> { - todo!() - } -} - pub type ZeebeClient = GatewayClient>; From e2042203c780cec141fabc638b0452f1b8ef7a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 17:50:02 +0200 Subject: [PATCH 47/52] fix: replace deprecated method usage --- client/src/auth.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/auth.rs b/client/src/auth.rs index 329bfc5..d4fa9d8 100644 --- a/client/src/auth.rs +++ b/client/src/auth.rs @@ -86,7 +86,7 @@ impl Interceptor for AuthInterceptor { let header_value = format!("Bearer {}", token); request.metadata_mut().insert( "authorization", - MetadataValue::from_str(&header_value).map_err(|_| { + MetadataValue::try_from(&header_value).map_err(|_| { tonic::Status::unauthenticated("token is not a valid header value") })?, ); From 51f1b97bda47cf5d8b487887172d9b37409bac1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 17:52:13 +0200 Subject: [PATCH 48/52] refactor: client only accepts address based connection --- cli/src/main.rs | 40 ++++++++++++++++++++-------------------- client/src/lib.rs | 28 +++++++--------------------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 1791f17..4c51aaa 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -15,7 +15,7 @@ use std::fmt::Debug; use async_trait::async_trait; use clap::{AppSettings, Parser, Subcommand}; -use color_eyre::eyre::Report; + use color_eyre::eyre::Result; use zeebe_client::ZeebeClient; @@ -106,35 +106,34 @@ enum Commands { impl From for zeebe_client::Connection { fn from(conn: Connection) -> Self { match conn.address { - Some(addr) => zeebe_client::Connection::Address { + Some(addr) => zeebe_client::Connection { insecure: conn.insecure, addr, }, - None => zeebe_client::Connection::HostPort { + None => zeebe_client::Connection { insecure: conn.insecure, - host: conn.host, - port: conn.port, + addr: format!("{}:{}", conn.host, conn.port), }, } } } -impl TryFrom for zeebe_client::Authentication { - type Error = Report; - - fn try_from(auth: Authentication) -> Result { - match (auth.client_id, auth.client_secret) { +impl Authentication { + fn for_connection(&self, _conn: &zeebe_client::Connection) -> Result { + match (&self.client_id, &self.client_secret) { (None, None) => Ok(zeebe_client::Authentication::Unauthenticated), - (Some(client_id), Some(client_secret)) => Ok(zeebe_client::Authentication::Oauth2( - zeebe_client::auth::OAuth2Config { - client_id, - client_secret, - auth_server: auth.authorization_server, - audience: "zeebe.camunda.io".to_owned(), - }, - )), + (Some(client_id), Some(client_secret)) => { + Ok(zeebe_client::Authentication::Oauth2( + zeebe_client::auth::OAuth2Config { + client_id: client_id.clone(), + client_secret: client_secret.clone(), + auth_server: self.authorization_server.clone(), + audience: "zeebe.camunda.io".to_owned(), + }, + )) + }, _ => Err(color_eyre::eyre::eyre!( - "Partial authentication info, needs at least client id and client secret" + "Partial authentication info, needs at least client id and client secret" )), } } @@ -170,8 +169,9 @@ async fn main() -> Result<()> { color_eyre::install()?; let cli: Cli = Cli::parse(); + let conn: zeebe_client::Connection = cli.connection.into(); let mut client: ZeebeClient = - zeebe_client::connect(cli.connection.into(), cli.auth.try_into()?).await?; + zeebe_client::connect(conn.clone(), cli.auth.for_connection(&conn)?).await?; let response: Box = match cli.command { Commands::ActivateJobs(args) => Box::new(args.execute(&mut client).await?), Commands::CancelProcessInstance(args) => Box::new(args.execute(&mut client).await?), diff --git a/client/src/lib.rs b/client/src/lib.rs index 1826303..8fa6d30 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -19,17 +19,10 @@ pub mod api { pub use super::generated_api::*; } -#[derive(Debug)] -pub enum Connection { - Address { - insecure: bool, - addr: String, - }, - HostPort { - insecure: bool, - host: String, - port: u16, - }, +#[derive(Debug, Clone)] +pub struct Connection { + pub insecure: bool, + pub addr: String, } #[derive(Debug)] @@ -56,19 +49,12 @@ pub async fn connect( conn: Connection, auth: Authentication, ) -> Result { - let insecure = match conn { - Connection::Address { insecure, .. } => insecure, - Connection::HostPort { insecure, .. } => insecure, - }; let uri = Uri::builder() - .scheme(match insecure { + .scheme(match conn.insecure { true => "http", false => "https", }) - .authority(match &conn { - Connection::Address { addr, .. } => addr.to_owned(), - Connection::HostPort { host, port, .. } => format!("{}:{}", host, port), - }) + .authority(conn.addr) .path_and_query("") .build()?; let interceptor = match auth { @@ -76,7 +62,7 @@ pub async fn connect( Authentication::Oauth2(oauth_config) => AuthInterceptor::oauth2(oauth_config)?, }; tracing::debug!("Connecting to {}", uri); - let channel = if insecure { + let channel = if conn.insecure { Channel::builder(uri) } else { Channel::builder(uri).tls_config(ClientTlsConfig::new())? From b574a33e08b6a4512c3073b4948ef6f12704deb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 17:52:40 +0200 Subject: [PATCH 49/52] fix: set audience based connection --- cli/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 4c51aaa..df7859b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -119,16 +119,17 @@ impl From for zeebe_client::Connection { } impl Authentication { - fn for_connection(&self, _conn: &zeebe_client::Connection) -> Result { + fn for_connection(&self, conn: &zeebe_client::Connection) -> Result { match (&self.client_id, &self.client_secret) { (None, None) => Ok(zeebe_client::Authentication::Unauthenticated), (Some(client_id), Some(client_secret)) => { + let audience = conn.addr.rsplit_once(':').map(|(authority, _port)| authority).unwrap_or(&conn.addr).to_owned(); Ok(zeebe_client::Authentication::Oauth2( zeebe_client::auth::OAuth2Config { client_id: client_id.clone(), client_secret: client_secret.clone(), auth_server: self.authorization_server.clone(), - audience: "zeebe.camunda.io".to_owned(), + audience, }, )) }, From a04b1ad76ddca9eed1f95de1552c347c6889666c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 17:57:13 +0200 Subject: [PATCH 50/52] style: fix formatting --- cli/src/main.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index df7859b..ab8ff95 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -119,22 +119,30 @@ impl From for zeebe_client::Connection { } impl Authentication { - fn for_connection(&self, conn: &zeebe_client::Connection) -> Result { + fn for_connection( + &self, + conn: &zeebe_client::Connection, + ) -> Result { match (&self.client_id, &self.client_secret) { (None, None) => Ok(zeebe_client::Authentication::Unauthenticated), (Some(client_id), Some(client_secret)) => { - let audience = conn.addr.rsplit_once(':').map(|(authority, _port)| authority).unwrap_or(&conn.addr).to_owned(); + let audience = conn + .addr + .rsplit_once(':') + .map(|(authority, _port)| authority) + .unwrap_or(&conn.addr) + .to_owned(); Ok(zeebe_client::Authentication::Oauth2( - zeebe_client::auth::OAuth2Config { - client_id: client_id.clone(), - client_secret: client_secret.clone(), - auth_server: self.authorization_server.clone(), - audience, - }, + zeebe_client::auth::OAuth2Config { + client_id: client_id.clone(), + client_secret: client_secret.clone(), + auth_server: self.authorization_server.clone(), + audience, + }, )) - }, + } _ => Err(color_eyre::eyre::eyre!( - "Partial authentication info, needs at least client id and client secret" + "Partial authentication info, needs at least client id and client secret" )), } } From f90b3378539422b04163c76a8f4e8bd1ee863b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Sch=C3=B6nburg?= Date: Wed, 12 Oct 2022 18:04:41 +0200 Subject: [PATCH 51/52] fix: use usize for argument to reflect usage --- cli/src/activate_jobs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/src/activate_jobs.rs b/cli/src/activate_jobs.rs index a085d5d..6ee708d 100644 --- a/cli/src/activate_jobs.rs +++ b/cli/src/activate_jobs.rs @@ -13,7 +13,7 @@ pub(crate) struct ActivateJobsArgs { job_type: String, #[clap(short, long, default_value_t = 10)] - max_jobs_to_activate: u32, + max_jobs_to_activate: usize, #[clap(short= 't', long, default_value_t = 5 * 60 * 1000)] job_timeout: u64, // todo: should be duration #[clap(long, required = false, default_value = "worker")] @@ -44,7 +44,7 @@ impl ExecuteZeebeCommand for ActivateJobsArgs { let args = &self; let request: ActivateJobsRequest = args.into(); let mut stream = client.activate_jobs(request).await?.into_inner(); - let mut result = Vec::with_capacity(args.max_jobs_to_activate.try_into().unwrap()); + let mut result = Vec::with_capacity(args.max_jobs_to_activate); while let Some(response) = stream.message().await? { result.push(response); } From d860b11bb59147c166fd91428e8803953c2e8071 Mon Sep 17 00:00:00 2001 From: Peter Ihme Date: Thu, 13 Oct 2022 09:57:59 +0200 Subject: [PATCH 52/52] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 25812b5..83ef066 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Run `cargo run -- help` to see available commands and options. **Authentication for Camunda Cloud** -First, [generate and download](https://docs.camunda.io/docs/next/components/console/manage-clusters/manage-api-clients/) client credentials from Console. Let's assume they are in a file called credentials.txt. +First, [generate and download](https://docs.camunda.io/docs/next/components/console/manage-clusters/manage-api-clients/) client credentials for Camunda Cloud. Let's assume they are in a file called credentials.txt. The `credentials.txt` file contains environment variables, so let's source them: ```shell