Files
java-template/client/config/config_loader.py
T
2025-09-06 23:39:04 +08:00

200 lines
6.9 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
LJWX系统配置加载器
统一配置管理,支持YAML配置文件和环境变量覆盖
"""
import os
import yaml
from typing import Dict, Any, Optional
from pathlib import Path
class LJWXConfigLoader:
"""LJWX配置加载器"""
def __init__(self, config_path: Optional[str] = None):
"""
初始化配置加载器
Args:
config_path: 配置文件路径,默认为当前目录下的ljwx-config.yaml
"""
if config_path is None:
# 尝试多个可能的配置文件位置
possible_paths = [
"/app/config/ljwx-config.yaml", # 容器内路径
"/client/config/ljwx-config.yaml", # 挂载路径
os.path.join(os.path.dirname(__file__), "ljwx-config.yaml"), # 同级目录
"client/config/ljwx-config.yaml", # 相对路径
"config/ljwx-config.yaml" # 简化路径
]
config_path = None
for path in possible_paths:
if os.path.exists(path):
config_path = path
break
if config_path is None:
raise FileNotFoundError("配置文件未找到,请确保ljwx-config.yaml存在")
self.config_path = config_path
self.config = self._load_config()
def _load_config(self) -> Dict[str, Any]:
"""加载配置文件"""
try:
with open(self.config_path, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
# 环境变量覆盖
config = self._apply_env_overrides(config)
return config
except Exception as e:
raise Exception(f"加载配置文件失败: {e}")
def _apply_env_overrides(self, config: Dict[str, Any]) -> Dict[str, Any]:
"""应用环境变量覆盖"""
# 数据库配置覆盖
if 'MYSQL_HOST' in os.environ:
config['database']['mysql']['host'] = os.environ['MYSQL_HOST']
if 'MYSQL_PORT' in os.environ:
config['database']['mysql']['port'] = int(os.environ['MYSQL_PORT'])
if 'MYSQL_DATABASE' in os.environ:
config['database']['mysql']['database'] = os.environ['MYSQL_DATABASE']
if 'MYSQL_USERNAME' in os.environ:
config['database']['mysql']['username'] = os.environ['MYSQL_USERNAME']
if 'MYSQL_PASSWORD' in os.environ:
config['database']['mysql']['password'] = os.environ['MYSQL_PASSWORD']
if 'REDIS_HOST' in os.environ:
config['database']['redis']['host'] = os.environ['REDIS_HOST']
if 'REDIS_PORT' in os.environ:
config['database']['redis']['port'] = int(os.environ['REDIS_PORT'])
if 'REDIS_PASSWORD' in os.environ:
config['database']['redis']['password'] = os.environ['REDIS_PASSWORD']
# 服务端口覆盖
if 'SERVER_PORT' in os.environ:
service_name = os.environ.get('SERVICE_NAME', 'ljwx-boot')
if service_name in config['services']:
config['services'][service_name]['port'] = int(os.environ['SERVER_PORT'])
return config
def get(self, key: str, default: Any = None) -> Any:
"""
获取配置值,支持点号分隔的嵌套键
Args:
key: 配置键,如 'database.mysql.host'
default: 默认值
Returns:
配置值
"""
keys = key.split('.')
value = self.config
for k in keys:
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value
def get_database_config(self, db_type: str = 'mysql') -> Dict[str, Any]:
"""获取数据库配置"""
return self.get(f'database.{db_type}', {})
def get_service_config(self, service_name: str) -> Dict[str, Any]:
"""获取服务配置"""
return self.get(f'services.{service_name}', {})
def get_image_config(self) -> Dict[str, str]:
"""获取镜像配置"""
return self.get('images', {})
def get_database_url(self, db_type: str = 'mysql') -> str:
"""获取数据库连接URL"""
db_config = self.get_database_config(db_type)
if db_type == 'mysql':
return f"mysql+pymysql://{db_config['username']}:{db_config['password']}@{db_config['host']}:{db_config['port']}/{db_config['database']}?charset={db_config.get('charset', 'utf8mb4')}"
elif db_type == 'redis':
password_part = f":{db_config['password']}@" if db_config.get('password') else ""
return f"redis://{password_part}{db_config['host']}:{db_config['port']}/{db_config.get('db', 0)}"
return ""
def reload(self):
"""重新加载配置"""
self.config = self._load_config()
# 全局配置实例
_config_loader = None
def get_config() -> LJWXConfigLoader:
"""获取全局配置实例"""
global _config_loader
if _config_loader is None:
_config_loader = LJWXConfigLoader()
return _config_loader
def reload_config():
"""重新加载全局配置"""
global _config_loader
if _config_loader is not None:
_config_loader.reload()
# 便捷函数
def get_database_config(db_type: str = 'mysql') -> Dict[str, Any]:
"""获取数据库配置"""
return get_config().get_database_config(db_type)
def get_service_config(service_name: str) -> Dict[str, Any]:
"""获取服务配置"""
return get_config().get_service_config(service_name)
def get_database_url(db_type: str = 'mysql') -> str:
"""获取数据库连接URL"""
return get_config().get_database_url(db_type)
if __name__ == "__main__":
# 测试配置加载
config = get_config()
print("=== LJWX配置测试 ===")
print(f"系统名称: {config.get('system.name')}")
print(f"系统版本: {config.get('system.version')}")
print()
print("=== 数据库配置 ===")
mysql_config = get_database_config('mysql')
print(f"MySQL: {mysql_config}")
print(f"MySQL URL: {get_database_url('mysql')}")
print()
redis_config = get_database_config('redis')
print(f"Redis: {redis_config}")
print(f"Redis URL: {get_database_url('redis')}")
print()
print("=== 服务配置 ===")
for service in ['ljwx-admin', 'ljwx-bigscreen', 'ljwx-boot']:
service_config = get_service_config(service)
print(f"{service}: {service_config}")
print()
print("=== 镜像配置 ===")
image_config = config.get_image_config()
print(f"镜像仓库: {image_config.get('registry')}")
print(f"Admin镜像: {image_config.get('ljwx-admin')}")
print(f"Bigscreen镜像: {image_config.get('ljwx-bigscreen')}")
print(f"Boot镜像: {image_config.get('ljwx-boot')}")