use std::marker::PhantomData;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use z_osmf_macros::{Endpoint, Getters};
use crate::convert::TryFromResponse;
use crate::{ClientCore, Result};
use super::WorkflowAccess;
#[derive(Clone, Debug, Deserialize, Eq, Getters, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct WorkflowCreate {
description: Arc<str>,
id: Arc<str>,
key: Arc<str>,
vendor: Arc<str>,
version: Arc<str>,
}
impl TryFromResponse for WorkflowCreate {
async fn try_from_response(value: reqwest::Response) -> Result<Self> {
Ok(value.json().await?)
}
}
#[derive(Clone, Debug, Endpoint)]
#[endpoint(method = post, path = "/zosmf/workflow/rest/1.0/workflows")]
pub struct WorkflowCreateBuilder<T>
where
T: TryFromResponse,
{
core: Arc<ClientCore>,
#[endpoint(builder_fn = build_body)]
name: Arc<str>,
definition_file: Arc<str>,
system: Arc<str>,
owner: Arc<str>,
definition_file_system: Option<Arc<str>>,
variable_input_file: Option<Arc<str>>,
variables: Option<Arc<[WorkflowVariableOverride]>>,
resolve_global_conflict_by_using: Option<WorkflowCreateResolveVariableConflict>,
archive_saf_id: Option<Arc<str>>,
comments: Option<Arc<str>>,
assign_to_owner: Option<bool>,
access_type: Option<WorkflowAccess>,
account_info: Option<Arc<str>>,
job_statement: Option<Arc<str>>,
delete_completed_jobs: Option<bool>,
jobs_output_directory: Option<Arc<str>>,
auto_delete_on_completion: Option<bool>,
target_system_uid: Option<Arc<str>>,
target_system_password: Option<Arc<str>>,
target_type: PhantomData<T>,
}
#[derive(Clone, Debug, Deserialize, Eq, Getters, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct WorkflowVariableOverride {
name: Arc<str>,
value: Arc<str>,
}
impl WorkflowVariableOverride {
pub fn new<N, V>(name: N, value: V) -> Self
where
N: std::fmt::Display,
V: std::fmt::Display,
{
WorkflowVariableOverride {
name: name.to_string().into(),
value: value.to_string().into(),
}
}
}
#[derive(
Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize,
)]
#[serde(rename_all = "lowercase")]
pub enum WorkflowCreateResolveVariableConflict {
#[default]
Global,
Input,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct RequestJson<'a> {
workflow_name: &'a str,
workflow_definition_file: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
workflow_definition_file_system: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
variable_input_file: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
variables: Option<&'a [WorkflowVariableOverride]>,
#[serde(skip_serializing_if = "Option::is_none")]
resolve_global_conflict_by_using: Option<&'a WorkflowCreateResolveVariableConflict>,
system: &'a str,
owner: &'a str,
#[serde(skip_serializing_if = "Option::is_none")]
workflow_archive_s_a_f_i_d: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
comments: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
assign_to_owner: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
access_type: Option<&'a WorkflowAccess>,
#[serde(skip_serializing_if = "Option::is_none")]
account_info: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
job_statement: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
delete_completed_jobs: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
jobs_output_directory: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
auto_delete_on_completion: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
target_systemuid: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
target_systempwd: Option<&'a str>,
}
fn build_body<T>(
request_builder: reqwest::RequestBuilder,
builder: &WorkflowCreateBuilder<T>,
) -> reqwest::RequestBuilder
where
T: TryFromResponse,
{
request_builder.json(&RequestJson {
workflow_name: &builder.name,
workflow_definition_file: &builder.definition_file,
system: &builder.system,
owner: &builder.owner,
workflow_definition_file_system: builder.definition_file_system.as_deref(),
variable_input_file: builder.variable_input_file.as_deref(),
variables: builder.variables.as_deref(),
resolve_global_conflict_by_using: builder.resolve_global_conflict_by_using.as_ref(),
workflow_archive_s_a_f_i_d: builder.archive_saf_id.as_deref(),
comments: builder.comments.as_deref(),
assign_to_owner: builder.assign_to_owner,
access_type: builder.access_type.as_ref(),
account_info: builder.account_info.as_deref(),
job_statement: builder.job_statement.as_deref(),
delete_completed_jobs: builder.delete_completed_jobs,
jobs_output_directory: builder.jobs_output_directory.as_deref(),
auto_delete_on_completion: builder.auto_delete_on_completion,
target_systemuid: builder.target_system_uid.as_deref(),
target_systempwd: builder.target_system_password.as_deref(),
})
}
#[cfg(test)]
mod tests {
use crate::tests::*;
use crate::workflows::create::WorkflowAccess;
#[test]
fn example() -> anyhow::Result<()> {
let zosmf = get_zosmf();
let json: serde_json::Value = serde_json::from_str(
r#"
{
"workflowName":"AutomationExample",
"workflowDefinitionFile":"/usr/lpp/zosmf/samples/workflow_sample_automation.xml",
"system":"SY1",
"owner":"zosmfad",
"assignToOwner" :true,
"accessType": "Restricted",
"deleteCompletedJobs" : true,
"autoDeleteOnCompletion" : true
}
"#,
)?;
let manual_request = zosmf
.core
.client
.post("https://test.com/zosmf/workflow/rest/1.0/workflows")
.json(&json)
.build()?;
let create = zosmf
.workflows()
.create(
"AutomationExample",
"/usr/lpp/zosmf/samples/workflow_sample_automation.xml",
"SY1",
"zosmfad",
)
.assign_to_owner(true)
.access_type(WorkflowAccess::Restricted)
.delete_completed_jobs(true)
.auto_delete_on_completion(true)
.get_request()?;
assert_eq!(format!("{:?}", manual_request), format!("{:?}", create));
assert_eq!(manual_request.json(), create.json());
Ok(())
}
}