use async_trait::async_trait;
use reqwest;
use std::collections::HashMap;
use crate::TaskResult;
use crate::error::{Result, TaskFlowError};
use crate::task::{Task, TaskHandler};
pub struct HttpTaskHandler {
client: reqwest::Client,
}
impl HttpTaskHandler {
pub fn new() -> Self {
Self {
client: reqwest::Client::new(),
}
}
}
#[async_trait]
impl TaskHandler for HttpTaskHandler {
async fn execute(&self, task: &Task) -> Result<TaskResult> {
let start_time = std::time::Instant::now();
let url = task
.definition
.payload
.get("url")
.and_then(|v| v.as_str())
.ok_or_else(|| {
TaskFlowError::InvalidConfiguration("Missing 'url' in payload".to_string())
})?;
let method = task
.definition
.payload
.get("method")
.and_then(|v| v.as_str())
.unwrap_or("GET");
let response = match method.to_uppercase().as_str() {
"GET" => self.client.get(url).send().await?,
"POST" => {
let mut request = self.client.post(url);
if let Some(body) = task.definition.payload.get("body") {
request = request.json(body);
}
request.send().await?
}
_ => {
return Err(TaskFlowError::InvalidConfiguration(format!(
"Unsupported HTTP method: {}",
method
)));
}
};
let status = response.status();
let body = response.text().await?;
let execution_time = start_time.elapsed().as_millis() as u64;
let success = status.is_success();
let mut metadata = HashMap::new();
metadata.insert("status_code".to_string(), status.as_u16().to_string());
metadata.insert("method".to_string(), method.to_string());
Ok(TaskResult {
success,
output: Some(body),
error: if success {
None
} else {
Some(format!("HTTP {}", status))
},
execution_time_ms: execution_time,
metadata,
})
}
fn task_type(&self) -> &str {
"http_request"
}
}