Skip to content

Commit 8bbb768

Browse files
feat(v2): introduce configs and health endpoints for v2 (#8835)
1 parent 951412f commit 8bbb768

File tree

6 files changed

+78
-5
lines changed

6 files changed

+78
-5
lines changed

crates/api_models/src/health_check.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct RouterHealthCheckResponse {
1414
pub grpc_health_check: HealthCheckMap,
1515
#[cfg(feature = "dynamic_routing")]
1616
pub decision_engine: bool,
17+
pub unified_connector_service: Option<bool>,
1718
}
1819

1920
impl common_utils::events::ApiEventMetric for RouterHealthCheckResponse {}

crates/router/src/core/health_check.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub trait HealthCheckInterface {
4040
async fn health_check_decision_engine(
4141
&self,
4242
) -> CustomResult<HealthState, errors::HealthCheckDecisionEngineError>;
43+
44+
async fn health_check_unified_connector_service(
45+
&self,
46+
) -> CustomResult<HealthState, errors::HealthCheckUnifiedConnectorServiceError>;
4347
}
4448

4549
#[async_trait::async_trait]
@@ -210,4 +214,19 @@ impl HealthCheckInterface for app::SessionState {
210214
Ok(HealthState::NotApplicable)
211215
}
212216
}
217+
218+
async fn health_check_unified_connector_service(
219+
&self,
220+
) -> CustomResult<HealthState, errors::HealthCheckUnifiedConnectorServiceError> {
221+
if let Some(_ucs_client) = &self.grpc_client.unified_connector_service_client {
222+
// For now, we'll just check if the client exists and is configured
223+
// In the future, this could be enhanced to make an actual health check call
224+
// to the unified connector service if it supports health check endpoints
225+
logger::debug!("Unified Connector Service client is configured and available");
226+
Ok(HealthState::Running)
227+
} else {
228+
logger::debug!("Unified Connector Service client not configured");
229+
Ok(HealthState::NotApplicable)
230+
}
231+
}
213232
}

crates/router/src/routes/app.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ impl AppState {
565565

566566
pub struct Health;
567567

568+
#[cfg(feature = "v1")]
568569
impl Health {
569570
pub fn server(state: AppState) -> Scope {
570571
web::scope("health")
@@ -574,6 +575,16 @@ impl Health {
574575
}
575576
}
576577

578+
#[cfg(feature = "v2")]
579+
impl Health {
580+
pub fn server(state: AppState) -> Scope {
581+
web::scope("/v2/health")
582+
.app_data(web::Data::new(state))
583+
.service(web::resource("").route(web::get().to(health)))
584+
.service(web::resource("/ready").route(web::get().to(deep_health_check)))
585+
}
586+
}
587+
577588
#[cfg(feature = "dummy_connector")]
578589
pub struct DummyConnector;
579590

@@ -1867,7 +1878,7 @@ impl Webhooks {
18671878

18681879
pub struct Configs;
18691880

1870-
#[cfg(any(feature = "olap", feature = "oltp"))]
1881+
#[cfg(all(feature = "v1", any(feature = "olap", feature = "oltp")))]
18711882
impl Configs {
18721883
pub fn server(config: AppState) -> Scope {
18731884
web::scope("/configs")
@@ -1882,6 +1893,21 @@ impl Configs {
18821893
}
18831894
}
18841895

1896+
#[cfg(all(feature = "v2", any(feature = "olap", feature = "oltp")))]
1897+
impl Configs {
1898+
pub fn server(config: AppState) -> Scope {
1899+
web::scope("/v2/configs")
1900+
.app_data(web::Data::new(config))
1901+
.service(web::resource("/").route(web::post().to(config_key_create)))
1902+
.service(
1903+
web::resource("/{key}")
1904+
.route(web::get().to(config_key_retrieve))
1905+
.route(web::post().to(config_key_update))
1906+
.route(web::delete().to(config_key_delete)),
1907+
)
1908+
}
1909+
}
1910+
18851911
pub struct ApplePayCertificatesMigration;
18861912

18871913
#[cfg(all(feature = "olap", feature = "v1"))]

crates/router/src/routes/configs.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ use crate::{
88
types::api as api_types,
99
};
1010

11+
#[cfg(feature = "v1")]
12+
const ADMIN_API_AUTH: auth::AdminApiAuth = auth::AdminApiAuth;
13+
#[cfg(feature = "v2")]
14+
const ADMIN_API_AUTH: auth::V2AdminApiAuth = auth::V2AdminApiAuth;
15+
1116
#[instrument(skip_all, fields(flow = ?Flow::CreateConfigKey))]
1217
pub async fn config_key_create(
1318
state: web::Data<AppState>,
@@ -23,7 +28,7 @@ pub async fn config_key_create(
2328
&req,
2429
payload,
2530
|state, _, data, _| configs::set_config(state, data),
26-
&auth::AdminApiAuth,
31+
&ADMIN_API_AUTH,
2732
api_locking::LockAction::NotApplicable,
2833
)
2934
.await
@@ -43,7 +48,7 @@ pub async fn config_key_retrieve(
4348
&req,
4449
&key,
4550
|state, _, key, _| configs::read_config(state, key),
46-
&auth::AdminApiAuth,
51+
&ADMIN_API_AUTH,
4752
api_locking::LockAction::NotApplicable,
4853
)
4954
.await
@@ -66,7 +71,7 @@ pub async fn config_key_update(
6671
&req,
6772
&payload,
6873
|state, _, payload, _| configs::update_config(state, payload),
69-
&auth::AdminApiAuth,
74+
&ADMIN_API_AUTH,
7075
api_locking::LockAction::NotApplicable,
7176
)
7277
.await
@@ -87,7 +92,7 @@ pub async fn config_key_delete(
8792
&req,
8893
key,
8994
|state, _, key, _| configs::config_delete(state, key),
90-
&auth::AdminApiAuth,
95+
&ADMIN_API_AUTH,
9196
api_locking::LockAction::NotApplicable,
9297
)
9398
.await

crates/router/src/routes/health.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,21 @@ async fn deep_health_check_func(
150150

151151
logger::debug!("Outgoing Request health check end");
152152

153+
logger::debug!("Unified Connector Service health check begin");
154+
155+
let unified_connector_service_status = state
156+
.health_check_unified_connector_service()
157+
.await
158+
.map_err(|error| {
159+
let message = error.to_string();
160+
error.change_context(errors::ApiErrorResponse::HealthCheckError {
161+
component: "Unified Connector Service",
162+
message,
163+
})
164+
})?;
165+
166+
logger::debug!("Unified Connector Service health check end");
167+
153168
let response = RouterHealthCheckResponse {
154169
database: db_status.into(),
155170
redis: redis_status.into(),
@@ -163,6 +178,7 @@ async fn deep_health_check_func(
163178
grpc_health_check,
164179
#[cfg(feature = "dynamic_routing")]
165180
decision_engine: decision_engine_health_check.into(),
181+
unified_connector_service: unified_connector_service_status.into(),
166182
};
167183

168184
Ok(api::ApplicationResponse::Json(response))

crates/storage_impl/src/errors.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,9 @@ pub enum HealthCheckDecisionEngineError {
294294
#[error("Failed to establish Decision Engine connection")]
295295
FailedToCallDecisionEngineService,
296296
}
297+
298+
#[derive(Debug, Clone, thiserror::Error)]
299+
pub enum HealthCheckUnifiedConnectorServiceError {
300+
#[error("Failed to establish Unified Connector Service connection")]
301+
FailedToCallUnifiedConnectorService,
302+
}

0 commit comments

Comments
 (0)