put all files in their expected file
This commit is contained in:
149
WatcherAgent/src/api.rs
Normal file
149
WatcherAgent/src/api.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::models::{HardwareDto, HeartbeatDto, IdResponse, MetricDto, RegistrationDto};
|
||||
use anyhow::Result;
|
||||
use reqwest::{Client, StatusCode};
|
||||
use std::error::Error;
|
||||
use tokio::time::{interval, sleep};
|
||||
|
||||
pub async fn register_with_server(base_url: &str) -> Result<(i32, String), Box<dyn Error>> {
|
||||
// First get local IP
|
||||
let ip = local_ip_address::local_ip()?.to_string();
|
||||
println!("Local IP address detected: {}", ip);
|
||||
|
||||
// Get server ID from backend (this will retry until successful)
|
||||
let (server_id, registered_ip) = get_server_id_by_ip(base_url, &ip).await?;
|
||||
|
||||
// Create HTTP client for registration
|
||||
let client = Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()?;
|
||||
|
||||
// Collect hardware info
|
||||
let hardware = HardwareDto::collect().await?;
|
||||
|
||||
// Prepare registration data
|
||||
let registration = RegistrationDto {
|
||||
id: server_id,
|
||||
ip_address: registered_ip.clone(),
|
||||
cpu_type: hardware.cpu_type,
|
||||
cpu_cores: hardware.cpu_cores,
|
||||
gpu_type: hardware.gpu_type,
|
||||
ram_size: hardware.ram_size,
|
||||
};
|
||||
|
||||
// Try to register (will retry on failure)
|
||||
loop {
|
||||
println!("Attempting to register with server...");
|
||||
let url = format!("{}/monitoring/register-agent-by-id", base_url);
|
||||
match client.post(&url).json(®istration).send().await {
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
println!("✅ Successfully registered with server.");
|
||||
return Ok((server_id, registered_ip));
|
||||
}
|
||||
Ok(resp) => {
|
||||
let status = resp.status();
|
||||
let text = resp.text().await.unwrap_or_default();
|
||||
println!(
|
||||
"⚠️ Registration failed ({}): {} (will retry in 10 seconds)",
|
||||
status, text
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("⚠️ Registration error: {} (will retry in 10 seconds)", err);
|
||||
}
|
||||
}
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_server_id_by_ip(base_url: &str, ip: &str) -> Result<(i32, String), Box<dyn Error>> {
|
||||
let client = Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()?;
|
||||
|
||||
let url = format!("{}/monitoring/server-id-by-ip?ipAddress={}", base_url, ip);
|
||||
|
||||
loop {
|
||||
println!("Attempting to fetch server ID for IP {}...", ip);
|
||||
match client.get(&url).send().await {
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
let text = resp.text().await?;
|
||||
println!("Raw response: {}", text); // Debug output
|
||||
|
||||
let id_resp: IdResponse = serde_json::from_str(&text).map_err(|e| {
|
||||
println!("Failed to parse response: {}", e);
|
||||
e
|
||||
})?;
|
||||
|
||||
println!(
|
||||
"✅ Received ID {} for IP {}",
|
||||
id_resp.id, id_resp.ip_address
|
||||
);
|
||||
return Ok((id_resp.id, id_resp.ip_address));
|
||||
}
|
||||
Ok(resp) if resp.status() == StatusCode::NOT_FOUND => {
|
||||
println!(
|
||||
"❌ Server with IP {} not found in database (will retry in 10 seconds)",
|
||||
ip
|
||||
);
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
Ok(resp) => {
|
||||
println!(
|
||||
"⚠️ Server responded with status: {} - {}",
|
||||
resp.status(),
|
||||
resp.text().await?
|
||||
);
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
Err(err) => {
|
||||
println!("⚠️ Request failed: {} (will retry in 10 seconds)", err);
|
||||
sleep(Duration::from_secs(10)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn heartbeat_loop(base_url: &str, ip: &str) -> Result<(), Box<dyn Error>> {
|
||||
let client = Client::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.build()?;
|
||||
let url = format!("{}/heartbeat/receive", base_url);
|
||||
|
||||
loop {
|
||||
let payload = HeartbeatDto {
|
||||
ip_address: ip.to_string(),
|
||||
};
|
||||
|
||||
match client.post(&url).json(&payload).send().await {
|
||||
Ok(res) if res.status().is_success() => {
|
||||
println!("Heartbeat sent successfully.");
|
||||
}
|
||||
Ok(res) => eprintln!("Server responded with status: {}", res.status()),
|
||||
Err(e) => eprintln!("Heartbeat error: {}", e),
|
||||
}
|
||||
|
||||
sleep(Duration::from_secs(20)).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_metrics(base_url: &str, metrics: &MetricDto) -> Result<(), Box<dyn Error>> {
|
||||
let client = Client::new();
|
||||
let url = format!("{}/monitoring/metric", base_url);
|
||||
let mut interval = interval(Duration::from_secs(20));
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let metric = metrics;
|
||||
|
||||
match client.post(&url).json(&metric).send().await {
|
||||
Ok(res) => println!(
|
||||
"✅ Sent metrics for server {} | Status: {}",
|
||||
metric.server_id,
|
||||
res.status()
|
||||
),
|
||||
Err(err) => eprintln!("❌ Failed to send metrics: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user