Files
watcheragent/WatcherAgent/src/api.rs
donpat1to c16547628a
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Has been cancelled
Rust Cross-Platform Build / Setup Rust Toolchain (push) Has been cancelled
Rust Cross-Platform Build / Run Tests (push) Has been cancelled
Rust Cross-Platform Build / Set Tag Name (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been cancelled
Rust Cross-Platform Build / Create Tag (push) Has been cancelled
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
test
2025-09-23 16:24:44 +02:00

157 lines
5.2 KiB
Rust

use std::time::Duration;
use crate::hardware::HardwareInfo;
use crate::models::{HeartbeatDto, IdResponse, MetricDto, RegistrationDto};
use anyhow::Result;
use reqwest::{Client, StatusCode};
use std::error::Error;
use tokio::time::sleep;
pub async fn register_with_server(
base_url: &str,
) -> Result<(i32, String), Box<dyn Error + Send + Sync>> {
// 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 = HardwareInfo::collect().await?;
// Prepare registration data
let registration = RegistrationDto {
id: server_id,
ip_address: registered_ip.clone(),
cpu_type: hardware.cpu.name.clone().unwrap_or_default(),
cpu_cores: (hardware.cpu.cores).unwrap_or_default(),
gpu_type: hardware.gpu.name.clone().unwrap_or_default(),
ram_size: hardware.memory.total.unwrap_or_default(),
};
// 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(&registration).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 + Send + Sync>> {
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 + Send + Sync>> {
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 + Send + Sync>> {
let client = Client::new();
let url = format!("{}/monitoring/metric", base_url);
println!("Metrics: {:?}", metrics);
match client.post(&url).json(&metrics).send().await {
Ok(res) => println!(
"✅ Sent metrics for server {} | Status: {}",
metrics.server_id,
res.status()
),
Err(err) => eprintln!("❌ Failed to send metrics: {}", err),
}
Ok(())
}
//test