use crate::client::Context;
use derive_new::new;
use serde::{Deserialize, Serialize};
use serde_json::{Error, Value};
use super::{traits::Service, HttpMethods, KeyValue, Limits, ACTION_ENDPOINT, NAMESPACE_ENDPOINT};
#[derive(new, Debug, Default, Deserialize, Serialize, Clone)]
pub struct ActionService<T> {
client: T,
context: Context,
}
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct Action {
#[serde(default)]
pub namespace: String,
#[serde(default)]
pub name: String,
#[serde(skip_serializing)]
pub version: String,
#[serde(skip_serializing)]
pub limits: Limits,
pub exec: Exec,
#[serde(default)]
#[serde(skip_serializing)]
pub error: String,
#[serde(skip_serializing)]
pub publish: bool,
#[serde(skip_serializing)]
pub updated: i64,
pub annotations: Vec<KeyValue>,
}
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct Exec {
#[serde(default)]
pub kind: String,
#[serde(default)]
pub code: String,
#[serde(default)]
pub image: String,
#[serde(default)]
pub init: String,
#[serde(default)]
pub main: String,
#[serde(default)]
pub components: Vec<String>,
#[serde(default)]
pub binary: bool,
}
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct ActionList {
pub name: String,
pub namespace: String,
}
impl<T> ActionService<T>
where
T: Service,
{
pub fn list(&self) -> Result<Vec<ActionList>, String> {
let url = format!(
"{}/api/v1/{}/{}/{}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
ACTION_ENDPOINT
);
let user_auth = self.context.auth();
let user = user_auth.0;
let pass = user_auth.1;
let request = match self.client.new_request(
Some(HttpMethods::GET),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => {
let actions: Result<Vec<Action>, Error> = serde_json::from_value(x);
match actions {
Ok(actions) => {
let mut result = Vec::new();
for action in actions.into_iter() {
let actionlist = ActionList {
name: action.name,
namespace: action.namespace,
};
result.push(actionlist)
}
Ok(result)
}
Err(error) => return Err(format!("Failed to deserailize actions {}", error)),
}
}
Err(error) => Err(format!("Failed to fetch the list of actions {}", error)),
}
}
pub fn get(&self, action_name: &str, fetch_code: bool) -> Result<Action, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}?code={}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
ACTION_ENDPOINT,
action_name,
fetch_code
);
let user_auth = self.context.auth();
let user = user_auth.0;
let pass = user_auth.1;
let request = match self.client.new_request(
Some(HttpMethods::GET),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(error) => Err(format!("Failed to deserailize actions {}", error)),
},
Err(error) => Err(format!("Failed to get action properties {}", error)),
}
}
pub fn delete(&self, action_name: &str) -> Result<Action, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}?code=false",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
ACTION_ENDPOINT,
action_name,
);
let user_auth = self.context.auth();
let user = user_auth.0;
let pass = user_auth.1;
let request = match self.client.new_request(
Some(HttpMethods::DELETE),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize actions {}", err)),
},
Err(x) => Err(format!("Failed to get action properties {}", x)),
}
}
pub fn insert(&self, action: &Action, overwrite: bool) -> Result<Action, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}?overwrite={}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
ACTION_ENDPOINT,
action.name,
overwrite,
);
let user_auth = self.context.auth();
let user = user_auth.0;
let pass = user_auth.1;
let body = serde_json::to_value(action).unwrap();
let request = match self.client.new_request(
Some(HttpMethods::PUT),
url.as_str(),
Some((user, pass)),
Some(body),
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize actions {}", err)),
},
Err(x) => Err(format!("Failed to get action properties {}", x)),
}
}
pub fn invoke(
&self,
action_name: &str,
payload: Value,
blocking: bool,
result: bool,
) -> Result<Value, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}?blocking={}&result={}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
ACTION_ENDPOINT,
action_name,
blocking,
result
);
let user_auth = self.context.auth();
let user = user_auth.0;
let pass = user_auth.1;
let request = match self.client.new_request(
Some(HttpMethods::POST),
url.as_str(),
Some((user, pass)),
Some(payload),
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize actions {}", err)),
},
Err(x) => Err(format!("Failed to invoke action {}", x)),
}
}
}