Skip to content
Clone

fix(config): load every section from a single AppConfig

ZhenYi committed
parent d6dc02f commit 23daab3 Browse files

4 files changed

+25 −113

File tree 4
Modified app/src/main.rs View app/src/main.rs
@@ -23,7 +23,7 @@
2323async fn serve() -> anyhow::Result<()> {
2424 use actix_web::middleware::from_fn;
2525 use actix_web::{App, HttpServer, web};
26 use config::scoped::{ApihostConfig, ScopedConfig};
26 use config::AppConfig;
2727 use tokio_util::sync::CancellationToken;
2828 use tracing::{info, warn};
2929 use utoipa_swagger_ui::SwaggerUi;
@@ -31,14 +31,14 @@
3131
3232 let telemetry = oltp::init(&oltp::TelemetryConfig::from_env("gitdata"));
3333
34 let cfg = ApihostConfig::load().context("loading configuration")?;
34 let cfg = AppConfig::load().context("loading configuration")?;
3535 if !cfg.apihost.enabled() {
3636 info!("apihost is disabled by config; exiting");
3737 return Ok(());
3838 }
3939
4040 let cancel = CancellationToken::new();
41 let app_config = cfg.clone().into_app_config();
41 let app_config = cfg.clone();
4242 let session_config = app_config.session.clone();
4343 let session_store = auth::session::RedisStore::connect(&app_config.redis)
4444 .await
@@ -232,7 +232,7 @@
232232
233233#[tokio::main]
234234async fn migrate() -> anyhow::Result<()> {
235 use config::scoped::{MigrateConfig, ScopedConfig};
235 use config::migrate::MigrateConfig;
236236 use models::migrate::sync_schema;
237237 use sea_orm::Database;
238238 use tracing::info;
Modified lib/config/src/lib.rs View lib/config/src/lib.rs
@@ -7,13 +7,13 @@
77pub mod internal;
88pub mod issues;
99pub mod livekit;
10pub mod migrate;
1011pub mod pow;
1112pub mod push;
1213pub mod quota;
1314pub mod redis;
1415pub mod rocketmq;
1516pub mod s3;
16pub mod scoped;
1717pub mod session;
1818pub mod smtp;
1919pub mod space;
Added lib/config/src/migrate.rs View lib/config/src/migrate.rs
@@ -0,0 +1,20 @@
1use serde::Deserialize;
2
3use crate::database::DatabaseConfig;
4use crate::error::ConfigError;
5
6#[derive(Clone, Debug, Default, Deserialize)]
7#[serde(default)]
8pub struct MigrateConfig {
9 pub database: DatabaseConfig,
10}
11
12impl MigrateConfig {
13 pub fn load() -> Result<Self, ConfigError> {
14 let config: Self = crate::loader::figment()?
15 .extract()
16 .map_err(ConfigError::from)?;
17 config.database.validate().map_err(ConfigError::Validation)?;
18 Ok(config)
19 }
20}
Deleted lib/config/src/scoped.rs
@@ -1,108 +0,0 @@
1use serde::Deserialize;
2use serde::de::DeserializeOwned;
3
4use crate::apihost::ApihostConfig as ApihostSection;
5use crate::auth::AuthConfig;
6use crate::chat::ChatConfig;
7use crate::database::DatabaseConfig;
8use crate::email::EmailConfig;
9use crate::error::ConfigError;
10use crate::git::GitConfig;
11use crate::issues::IssueConfig;
12use crate::livekit::LiveKitConfig;
13use crate::pow::PowConfig;
14use crate::push::PushConfig;
15use crate::quota::QuotaConfig;
16use crate::redis::RedisConfig;
17use crate::rocketmq::RocketMqConfig;
18use crate::s3::S3Config;
19use crate::session::SessionConfig;
20use crate::space::SpaceConfig;
21use crate::user::UserConfig;
22use crate::web::WebConfig;
23use crate::{AppConfig, loader};
24
25pub trait ScopedConfig: DeserializeOwned + Sized {
26 fn validate_scoped(&self) -> Result<(), String>;
27
28 fn load() -> Result<Self, ConfigError> {
29 let cfg: Self = loader::figment()?.extract().map_err(ConfigError::from)?;
30 cfg.validate_scoped().map_err(ConfigError::Validation)?;
31 Ok(cfg)
32 }
33}
34
35#[derive(Clone, Debug, Default, Deserialize)]
36#[serde(default)]
37pub struct MigrateConfig {
38 pub database: DatabaseConfig,
39}
40
41impl ScopedConfig for MigrateConfig {
42 fn validate_scoped(&self) -> Result<(), String> {
43 self.database.validate()
44 }
45}
46
47#[derive(Clone, Debug, Default, Deserialize)]
48#[serde(default)]
49pub struct ApihostConfig {
50 pub s3: S3Config,
51 pub redis: RedisConfig,
52 pub chat: ChatConfig,
53 pub database: DatabaseConfig,
54 pub pow: PowConfig,
55 pub auth: AuthConfig,
56 pub web: WebConfig,
57 pub user: UserConfig,
58 pub quota: QuotaConfig,
59 pub space: SpaceConfig,
60 pub issues: IssueConfig,
61 pub git: GitConfig,
62 pub email: EmailConfig,
63 pub session: SessionConfig,
64 pub apihost: ApihostSection,
65 pub livekit: LiveKitConfig,
66 pub rocketmq: RocketMqConfig,
67 pub push: PushConfig,
68}
69
70impl ApihostConfig {
71 pub fn into_app_config(self) -> AppConfig {
72 AppConfig {
73 s3: self.s3,
74 redis: self.redis,
75 chat: self.chat,
76 database: self.database,
77 pow: self.pow,
78 auth: self.auth,
79 web: self.web,
80 user: self.user,
81 quota: self.quota,
82 space: self.space,
83 issues: self.issues,
84 git: self.git,
85 email: self.email,
86 session: self.session,
87 apihost: self.apihost,
88 livekit: self.livekit,
89 rocketmq: self.rocketmq,
90 push: self.push,
91 ..Default::default()
92 }
93 }
94}
95
96impl ScopedConfig for ApihostConfig {
97 fn validate_scoped(&self) -> Result<(), String> {
98 self.redis.validate()?;
99 self.database.validate()?;
100 self.pow.validate()?;
101 self.auth.validate()?;
102 self.chat.is_valid()?;
103 self.apihost.is_valid()?;
104 self.livekit.is_valid()?;
105 self.rocketmq.is_valid()?;
106 self.push.is_valid()
107 }
108}