Skip to content

Commit

Permalink
fix: config endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: bkioshn <[email protected]>
  • Loading branch information
bkioshn committed Oct 15, 2024
1 parent 939df7e commit c522ce4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 46 deletions.
35 changes: 16 additions & 19 deletions catalyst-gateway/bin/src/db/event/config/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{net::IpAddr, sync::LazyLock};

use serde_json::Value;
use serde_json::{json, Value};
use tracing::error;

/// Configuration key
Expand All @@ -15,19 +15,21 @@ pub(crate) enum ConfigKey {
}

/// Frontend schema configuration.
static FRONTEND_SCHEMA: LazyLock<Option<Value>> =
static FRONTEND_SCHEMA: LazyLock<Value> =
LazyLock::new(|| load_json_lazy(include_str!("jsonschema/frontend.json")));

/// Frontend default configuration.
static FRONTEND_DEFAULT: LazyLock<Option<Value>> =
static FRONTEND_DEFAULT: LazyLock<Value> =
LazyLock::new(|| load_json_lazy(include_str!("default/frontend.json")));

/// Helper function to convert a JSON string to a JSON value.
fn load_json_lazy(data: &str) -> Option<Value> {
let json = serde_json::from_str(data);

json.inspect_err(|e| error!("Error parsing JSON : {e}"))
.ok()
fn load_json_lazy(data: &str) -> Value {
serde_json::from_str(data).unwrap_or_else(|e| {
// Log the error
error!("Error parsing JSON: {}", e);
// And return an empty JSON object
json!({})
})
}

impl ConfigKey {
Expand All @@ -48,25 +50,20 @@ impl ConfigKey {
ConfigKey::Frontend | ConfigKey::FrontendForIp(_) => &*FRONTEND_SCHEMA,
};

let Some(schema) = schema else {
return Err(anyhow::anyhow!("Failed to retrieve JSON schema"));
};
let validator = jsonschema::validator_for(schema)
.map_err(|e| anyhow::anyhow!("Failed to create JSON validator: {:?}", e))?;

// Validate the value against the schema
anyhow::ensure!(validator.is_valid(value), "Invalid configuration");
anyhow::ensure!(validator.is_valid(value), "Failed schema validation");
Ok(())
}

/// Retrieve the default configuration value.
pub(super) fn default(&self) -> Option<Value> {
pub(super) fn default(&self) -> Value {
// Retrieve the default value based on the ConfigKey
let default = match self {
ConfigKey::Frontend | ConfigKey::FrontendForIp(_) => &*FRONTEND_DEFAULT,
};

default.clone()
match self {
ConfigKey::Frontend | ConfigKey::FrontendForIp(_) => FRONTEND_DEFAULT.clone(),
}
}
}

Expand All @@ -88,6 +85,6 @@ mod tests {
#[test]
fn test_default() {
let result = ConfigKey::Frontend.default();
assert!(result.is_some());
assert!(result.is_object());
}
}
3 changes: 1 addition & 2 deletions catalyst-gateway/bin/src/db/event/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ impl Config {
Ok(value)
} else {
// If data not found return default config value
id.default()
.ok_or(anyhow::anyhow!("Default value not found for {:?}", id))
Ok(id.default())
}
}

Expand Down
35 changes: 10 additions & 25 deletions catalyst-gateway/bin/src/service/api/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
use std::{net::IpAddr, str::FromStr};

use poem_openapi::{
param::{Header, Query},
payload::Json,
ApiResponse, OpenApi,
};
use poem::web::RealIp;
use poem_openapi::{param::Query, payload::Json, ApiResponse, OpenApi};
use serde_json::Value;
use tracing::info;

use crate::{
db::event::config::{key::ConfigKey, Config},
Expand All @@ -34,35 +32,22 @@ enum Responses {
#[OpenApi(tag = "ApiTags::Config")]
impl ConfigApi {
/// Get the configuration for the frontend.
/// Retrieving IP from X-Forwarded-For header if provided.
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
///
/// Retrieving IP from X-Real-IP, Forwarded, X-Forwarded-For or Remote Address.
#[oai(
path = "/draft/config/frontend",
method = "get",
operation_id = "get_config_frontend"
)]
async fn get_frontend(
&self, #[oai(name = "X-Forwarded-For")] header: Header<Option<String>>,
) -> Responses {
// Retrieve the IP address from the header
// According to the X-Forwarded-For header spec, the first value is the IP address
let ip_address = header
.0
.as_ref()
.and_then(|h| h.split(',').next())
.map(String::from);
async fn get_frontend(&self, ip_address: RealIp) -> Responses {
info!("IP Address: {:?}", ip_address.0);

// Fetch the general configuration
let general_config = Config::get(ConfigKey::Frontend).await;

// Attempt to fetch the IP configuration
let ip_config = if let Some(ip) = ip_address {
match IpAddr::from_str(&ip) {
Ok(parsed_ip) => Config::get(ConfigKey::FrontendForIp(parsed_ip)).await.ok(),
Err(_) => {
return Responses::BadRequest(Json(format!("Invalid IP address: {ip}")));
},
}
let ip_config = if let Some(ip) = ip_address.0 {
Config::get(ConfigKey::FrontendForIp(ip)).await.ok()
} else {
None
};
Expand All @@ -84,7 +69,7 @@ impl ConfigApi {
}
}

/// Insert or update the frontend configuration.
/// Set the frontend configuration.
#[oai(
path = "/draft/config/frontend",
method = "put",
Expand Down

0 comments on commit c522ce4

Please sign in to comment.