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:
@@ -10,9 +10,14 @@ use database::generated::entities::{upstream, upstream_target};
|
||||
use crate::{
|
||||
errors::service_error::ServiceError,
|
||||
helpers::database::PaginationFilter,
|
||||
services::nginx::info::{
|
||||
upstream::{UpdateUpstreamInfo, UpstreamCreateInfo, UpstreamInfo},
|
||||
upstream_target::{UpdateUpstreamTargetInfo, UpstreamTargetCreateInfo, UpstreamTargetInfo},
|
||||
services::nginx::{
|
||||
builder::NginxConfigBuilder,
|
||||
info::{
|
||||
upstream::{UpdateUpstreamInfo, UpstreamCreateInfo, UpstreamInfo},
|
||||
upstream_target::{
|
||||
UpdateUpstreamTargetInfo, UpstreamTargetCreateInfo, UpstreamTargetInfo,
|
||||
},
|
||||
},
|
||||
},
|
||||
with_conn,
|
||||
};
|
||||
@@ -57,6 +62,7 @@ pub trait UpstreamService: Send + Sync {
|
||||
options: Option<GetUpstreamTargetOptions>,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<UpstreamTargetInfo, ServiceError>;
|
||||
#[allow(dead_code)]
|
||||
async fn get_upstream_targets_by_upstream(
|
||||
&self,
|
||||
upstream_id: uuid::Uuid,
|
||||
@@ -73,6 +79,11 @@ pub trait UpstreamService: Send + Sync {
|
||||
target_id: uuid::Uuid,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError>;
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError>;
|
||||
}
|
||||
|
||||
pub struct UpstreamServiceImpl {
|
||||
@@ -387,6 +398,26 @@ impl UpstreamService for UpstreamServiceImpl {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
async fn generate_config(
|
||||
&self,
|
||||
builder: &mut NginxConfigBuilder,
|
||||
tx: Option<&mut DatabaseTransaction>,
|
||||
) -> Result<(), ServiceError> {
|
||||
// get all upstreams and their targets
|
||||
let upstreams = with_conn!(&*self.connection, tx, conn, {
|
||||
upstream::Entity::find()
|
||||
.find_with_related(upstream_target::Entity)
|
||||
.all(*conn)
|
||||
.await?
|
||||
});
|
||||
let upstreams_info = upstreams
|
||||
.into_iter()
|
||||
.map(|(up_model, target_models)| (up_model, target_models).into())
|
||||
.collect::<Vec<UpstreamInfo>>();
|
||||
builder.add_upstreams(upstreams_info);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -649,10 +680,16 @@ mod tests {
|
||||
|
||||
let db = MockDatabase::new(DatabaseBackend::Sqlite)
|
||||
.append_query_results(vec![vec![existing.clone()]])
|
||||
.append_exec_results(vec![MockExecResult {
|
||||
rows_affected: 1,
|
||||
last_insert_id: 0,
|
||||
}])
|
||||
.append_exec_results(vec![
|
||||
MockExecResult {
|
||||
rows_affected: 1,
|
||||
last_insert_id: 0,
|
||||
},
|
||||
MockExecResult {
|
||||
rows_affected: 1,
|
||||
last_insert_id: 0,
|
||||
},
|
||||
])
|
||||
.into_connection();
|
||||
|
||||
let svc = UpstreamServiceImpl::new(Arc::new(db));
|
||||
|
||||
Reference in New Issue
Block a user