feat: implement transaction handling for upstream and target operations

- Added transaction support in `add_upstream_target`, `remove_upstream`, `remove_upstream_target`, `update_upstream`, and `update_upstream_target` functions to ensure atomicity of operations.
- Updated the `NginxService` to include methods for validating and applying configurations using the agent service.
- Enhanced error handling in agent service interactions, returning appropriate internal server errors when agent communication fails.
- Introduced mock agent service for testing, allowing for simulation of agent interactions without actual network calls.
- Refactored tests to cover scenarios where agent operations fail, ensuring that internal server errors are returned as expected.
This commit is contained in:
GW_MC
2025-12-31 15:57:29 +08:00
parent 4f85d88380
commit 331b4e1e96
14 changed files with 975 additions and 71 deletions

View File

@@ -6,11 +6,21 @@ pub mod upstream;
use std::sync::Arc;
use sea_orm::DatabaseConnection;
use sea_orm::{DatabaseConnection, DatabaseTransaction};
use crate::services::nginx::upstream::{UpstreamService, UpstreamServiceImpl};
use crate::{
errors::service_error::ServiceError,
services::{
agent_client::AgentService,
nginx::{
builder::{NginxConfigBuilder, NginxConfigProvider},
upstream::{UpstreamService, UpstreamServiceImpl},
},
},
};
pub struct NginxService {
#[allow(dead_code)]
connection: Arc<DatabaseConnection>,
//
upstream_service: Arc<dyn UpstreamService>,
@@ -28,4 +38,49 @@ impl NginxService {
pub fn get_upstream_service(&self) -> Arc<dyn UpstreamService> {
self.upstream_service.clone()
}
#[allow(dead_code)]
pub async fn validate_config(
&self,
agent: Arc<dyn AgentService>,
config: &str,
) -> Result<(), ServiceError> {
agent.validate(config).await?;
Ok(())
}
pub async fn apply_changes(
&self,
agent: Arc<dyn AgentService>,
config: &str,
) -> Result<(), ServiceError> {
agent.apply(config).await?;
Ok(())
}
pub async fn generate_config(
&self,
tx: Option<&mut DatabaseTransaction>,
) -> Result<String, ServiceError> {
let mut builder = NginxConfigBuilder::default();
self.upstream_service
.generate_config(&mut builder, tx)
.await?;
Ok(builder.to_nginx_config(None))
}
pub async fn regenerate_and_apply_config(
&self,
agent: Arc<dyn AgentService>,
tx: Option<&mut DatabaseTransaction>,
) -> Result<(), ServiceError> {
let config = self.generate_config(tx).await?;
self.apply_changes(agent, &config).await?;
Ok(())
}
}