use crate::{proto, Client, Error, Result};
use tokio::{fs::File, io::AsyncReadExt};
use tracing::{debug, trace};
#[derive(Debug)]
pub struct DeployProcessBuilder {
client: Client,
resource_files: Vec<String>,
}
impl DeployProcessBuilder {
pub fn new(client: Client) -> Self {
DeployProcessBuilder {
client,
resource_files: Vec::new(),
}
}
pub fn with_resource_file<T: Into<String>>(self, resource_file: T) -> Self {
DeployProcessBuilder {
resource_files: vec![resource_file.into()],
..self
}
}
pub fn with_resource_files(self, resource_files: Vec<String>) -> Self {
DeployProcessBuilder {
resource_files,
..self
}
}
#[tracing::instrument(skip(self), name = "deploy_process", err)]
pub async fn send(mut self) -> Result<DeployProcessResponse> {
trace!(files = ?self.resource_files, "reading files");
let mut processes = Vec::with_capacity(self.resource_files.len());
for path in self.resource_files.iter() {
let mut file = File::open(path).await.map_err(|e| Error::FileIo {
resource_file: path.clone(),
source: e,
})?;
let mut definition = vec![];
file.read_to_end(&mut definition)
.await
.map_err(|e| Error::FileIo {
resource_file: path.clone(),
source: e,
})?;
processes.push(proto::ProcessRequestObject {
name: path.clone(),
definition,
})
}
debug!(files = ?self.resource_files, "sending request");
let res = self
.client
.gateway_client
.deploy_process(tonic::Request::new(proto::DeployProcessRequest {
processes,
}))
.await?;
Ok(DeployProcessResponse(res.into_inner()))
}
}
#[derive(Debug)]
pub struct DeployProcessResponse(proto::DeployProcessResponse);
impl DeployProcessResponse {
pub fn key(&self) -> i64 {
self.0.key
}
pub fn processes(&self) -> Vec<ProcessMetadata> {
self.0
.processes
.iter()
.map(|proto| ProcessMetadata(proto.clone()))
.collect()
}
}
#[derive(Debug)]
pub struct ProcessMetadata(proto::ProcessMetadata);
impl ProcessMetadata {
pub fn bpmn_process_id(&self) -> &str {
&self.0.bpmn_process_id
}
pub fn version(&self) -> i32 {
self.0.version
}
pub fn process_definition_key(&self) -> i64 {
self.0.process_definition_key
}
pub fn resource_name(&self) -> &str {
&self.0.resource_name
}
}
#[derive(Debug)]
pub struct CreateProcessInstanceBuilder {
client: Client,
process_definition_key: Option<i64>,
bpmn_process_id: Option<String>,
version: i32,
variables: Option<serde_json::Value>,
}
impl CreateProcessInstanceBuilder {
pub fn new(client: Client) -> Self {
CreateProcessInstanceBuilder {
client,
process_definition_key: None,
bpmn_process_id: None,
version: -1,
variables: None,
}
}
pub fn with_process_definition_key(self, key: i64) -> Self {
CreateProcessInstanceBuilder {
process_definition_key: Some(key),
..self
}
}
pub fn with_bpmn_process_id<T: Into<String>>(self, bpmn_process_id: T) -> Self {
CreateProcessInstanceBuilder {
bpmn_process_id: Some(bpmn_process_id.into()),
..self
}
}
pub fn with_version(self, version: i32) -> Self {
CreateProcessInstanceBuilder { version, ..self }
}
pub fn with_latest_version(self) -> Self {
CreateProcessInstanceBuilder {
version: -1,
..self
}
}
pub fn with_variables<T: Into<serde_json::Value>>(self, variables: T) -> Self {
CreateProcessInstanceBuilder {
variables: Some(variables.into()),
..self
}
}
#[tracing::instrument(skip(self), name = "create_process_instance", err)]
pub async fn send(mut self) -> Result<CreateProcessInstanceResponse> {
if self.process_definition_key.is_none() && self.bpmn_process_id.is_none() {
return Err(Error::InvalidParameters(
"`process_definition_key` or `pbmn_process_id` must be set",
));
}
let req = proto::CreateProcessInstanceRequest {
process_definition_key: self.process_definition_key.unwrap_or(0),
bpmn_process_id: self.bpmn_process_id.unwrap_or_else(String::new),
version: self.version,
variables: self
.variables
.map_or(String::new(), |vars| vars.to_string()),
};
debug!(?req, "sending request:");
let res = self
.client
.gateway_client
.create_process_instance(tonic::Request::new(req))
.await?;
Ok(CreateProcessInstanceResponse(res.into_inner()))
}
}
#[derive(Debug)]
pub struct CreateProcessInstanceResponse(proto::CreateProcessInstanceResponse);
impl CreateProcessInstanceResponse {
pub fn process_definition_key(&self) -> i64 {
self.0.process_definition_key
}
pub fn bpmn_process_id(&self) -> &str {
&self.0.bpmn_process_id
}
pub fn version(&self) -> i32 {
self.0.version
}
pub fn process_instance_key(&self) -> i64 {
self.0.process_instance_key
}
}
#[derive(Debug)]
pub struct CreateProcessInstanceWithResultBuilder {
client: Client,
process_definition_key: Option<i64>,
bpmn_process_id: Option<String>,
version: i32,
variables: Option<serde_json::Value>,
request_timeout: u64,
fetch_variables: Vec<String>,
}
impl CreateProcessInstanceWithResultBuilder {
pub fn new(client: Client) -> Self {
CreateProcessInstanceWithResultBuilder {
client,
process_definition_key: None,
bpmn_process_id: None,
version: -1,
variables: None,
request_timeout: 0,
fetch_variables: Vec::new(),
}
}
pub fn with_process_definition_key(self, key: i64) -> Self {
CreateProcessInstanceWithResultBuilder {
process_definition_key: Some(key),
..self
}
}
pub fn with_bpmn_process_id<T: Into<String>>(self, bpmn_process_id: T) -> Self {
CreateProcessInstanceWithResultBuilder {
bpmn_process_id: Some(bpmn_process_id.into()),
..self
}
}
pub fn with_version(self, version: i32) -> Self {
CreateProcessInstanceWithResultBuilder { version, ..self }
}
pub fn with_latest_version(self) -> Self {
CreateProcessInstanceWithResultBuilder {
version: -1,
..self
}
}
pub fn with_variables<T: Into<serde_json::Value>>(self, variables: T) -> Self {
CreateProcessInstanceWithResultBuilder {
variables: Some(variables.into()),
..self
}
}
pub fn with_fetch_variables(self, fetch_variables: Vec<String>) -> Self {
CreateProcessInstanceWithResultBuilder {
fetch_variables,
..self
}
}
pub fn with_request_timeout(self, request_timeout: u64) -> Self {
CreateProcessInstanceWithResultBuilder {
request_timeout,
..self
}
}
#[tracing::instrument(skip(self), name = "create_process_instance_with_result", err)]
pub async fn send(mut self) -> Result<CreateProcessInstanceWithResultResponse> {
if self.process_definition_key.is_none() && self.bpmn_process_id.is_none() {
return Err(Error::InvalidParameters(
"`process_definition_key` or `pbmn_process_id` must be set",
));
}
let req = proto::CreateProcessInstanceWithResultRequest {
request: Some(proto::CreateProcessInstanceRequest {
process_definition_key: self.process_definition_key.unwrap_or(0),
bpmn_process_id: self.bpmn_process_id.unwrap_or_else(String::new),
version: self.version,
variables: self
.variables
.map_or(String::new(), |vars| vars.to_string()),
}),
request_timeout: self.request_timeout as i64,
fetch_variables: self.fetch_variables,
};
debug!(?req, "sending request:");
let res = self
.client
.gateway_client
.create_process_instance_with_result(tonic::Request::new(req))
.await?;
Ok(CreateProcessInstanceWithResultResponse(res.into_inner()))
}
}
#[derive(Debug)]
pub struct CreateProcessInstanceWithResultResponse(proto::CreateProcessInstanceWithResultResponse);
impl CreateProcessInstanceWithResultResponse {
pub fn process_definition_key(&self) -> i64 {
self.0.process_definition_key
}
pub fn bpmn_process_id(&self) -> &str {
&self.0.bpmn_process_id
}
pub fn version(&self) -> i32 {
self.0.version
}
pub fn process_instance_key(&self) -> i64 {
self.0.process_instance_key
}
pub fn variables_str(&self) -> &str {
&self.0.variables
}
pub fn variables(&self) -> serde_json::Value {
serde_json::from_str(&self.0.variables).unwrap_or_else(|_| serde_json::json!({}))
}
pub fn variables_as<'a, T: serde::de::Deserialize<'a>>(&'a self) -> Option<T> {
serde_json::from_str::<'a, T>(&self.0.variables).ok()
}
}
#[derive(Debug)]
pub struct CancelProcessInstanceBuilder {
client: Client,
process_instance_key: Option<i64>,
}
impl CancelProcessInstanceBuilder {
pub fn new(client: Client) -> Self {
CancelProcessInstanceBuilder {
client,
process_instance_key: None,
}
}
pub fn with_process_instance_key(self, key: i64) -> Self {
CancelProcessInstanceBuilder {
process_instance_key: Some(key),
..self
}
}
#[tracing::instrument(skip(self), name = "cancel_process_instance", err)]
pub async fn send(mut self) -> Result<CancelProcessInstanceResponse> {
if self.process_instance_key.is_none() {
return Err(Error::InvalidParameters(
"`process_instance_key` must be set",
));
}
let req = proto::CancelProcessInstanceRequest {
process_instance_key: self.process_instance_key.unwrap(),
};
debug!(?req, "sending request:");
let res = self
.client
.gateway_client
.cancel_process_instance(tonic::Request::new(req))
.await?;
Ok(CancelProcessInstanceResponse(res.into_inner()))
}
}
#[derive(Debug)]
pub struct CancelProcessInstanceResponse(proto::CancelProcessInstanceResponse);
#[derive(Debug)]
pub struct SetVariablesBuilder {
client: Client,
element_instance_key: Option<i64>,
variables: Option<serde_json::Value>,
local: bool,
}
impl SetVariablesBuilder {
pub fn new(client: Client) -> Self {
SetVariablesBuilder {
client,
element_instance_key: None,
variables: None,
local: false,
}
}
pub fn with_element_instance_key(self, element_instance_key: i64) -> Self {
SetVariablesBuilder {
element_instance_key: Some(element_instance_key),
..self
}
}
pub fn with_variables<T: Into<serde_json::Value>>(self, variables: T) -> Self {
SetVariablesBuilder {
variables: Some(variables.into()),
..self
}
}
pub fn with_local(self, local: bool) -> Self {
SetVariablesBuilder { local, ..self }
}
#[tracing::instrument(skip(self), name = "set_variables", err)]
pub async fn send(mut self) -> Result<SetVariablesResponse> {
if self.element_instance_key.is_none() {
return Err(Error::InvalidParameters(
"`element_instance_key` must be set",
));
}
let req = proto::SetVariablesRequest {
element_instance_key: self.element_instance_key.unwrap(),
variables: self
.variables
.map_or(String::new(), |vars| vars.to_string()),
local: self.local,
};
debug!(?req, "sending request:");
let res = self
.client
.gateway_client
.set_variables(tonic::Request::new(req))
.await?;
Ok(SetVariablesResponse(res.into_inner()))
}
}
#[derive(Debug)]
pub struct SetVariablesResponse(proto::SetVariablesResponse);
impl SetVariablesResponse {
pub fn key(&self) -> i64 {
self.0.key
}
}