use std::sync::Once;
use genies_core::jwt::*;
use serde::{Deserialize, Serialize};
use genies_config::app_config::ApplicationConfig;
use genies_cache::cache_service::CacheService;
use rbatis::RBatis;
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct RemoteToken {
pub access_token: String,
}
impl RemoteToken {
pub fn new() -> Self {
let config = ApplicationConfig::from_sources("./application.yml").unwrap();
let url = config.keycloak_auth_server_url.clone();
let realm = config.keycloak_realm.clone();
let resource = config.keycloak_resource.clone();
let secret = config.keycloak_credentials_secret.clone();
Self {
access_token: std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
get_temp_access_token(&url, &realm, &resource, &secret)
.await
.unwrap_or_else(|e| {
log::error!("Failed to get temp access token: {}", e);
String::new()
})
})
}).join().unwrap(),
}
}
}
pub struct ApplicationContext {
pub config: ApplicationConfig,
pub rbatis: RBatis,
pub cache_service: CacheService,
pub redis_save_service: CacheService,
pub keycloak_keys: Keys,
mysql_init_once: Once, }
impl ApplicationContext {
pub async fn init_mysql(&self) {
self.mysql_init_once.call_once(|| {
log::debug!("rbatis mysql init ({})...", self.config.database_url);
let _ = self.rbatis.init(rbdc_mysql::driver::MysqlDriver {}, &self.config.database_url).unwrap();
let _ = self.rbatis.get_pool().unwrap().set_max_open_conns(self.config.max_connections as u64);
let _ = self.rbatis.get_pool().unwrap().set_max_idle_conns(self.config.wait_timeout as u64);
let _ = self.rbatis.get_pool().unwrap().set_conn_max_lifetime(Some(std::time::Duration::from_secs(self.config.max_lifetime)));
});
let _ = self.rbatis.get_pool().unwrap().get().await;
log::info!("rbatis mysql init success! pool state = {:?}", self.rbatis.get_pool().unwrap().state().await);
}
pub fn new() -> Self {
let config = ApplicationConfig::from_sources("./application.yml").unwrap();
log::debug!("config = {:?}", config);
let auth_url = config.keycloak_auth_server_url.clone();
let auth_realm = config.keycloak_realm.clone();
ApplicationContext {
keycloak_keys: std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
get_keycloak_keys(&auth_url, &auth_realm).await
})
}).join().unwrap()
.expect("Failed to get keycloak keys"),
rbatis: RBatis::new(),
cache_service: CacheService::new(&config),
redis_save_service: CacheService::new_saved(&config),
config,
mysql_init_once: Once::new(),
}
}
}
impl Default for ApplicationContext {
fn default() -> Self {
Self::new()
}
}