91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
// oci-portal 后端服务启动入口。
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"oci-portal/internal/api"
|
|
"oci-portal/internal/config"
|
|
"oci-portal/internal/crypto"
|
|
"oci-portal/internal/database"
|
|
"oci-portal/internal/oci"
|
|
"oci-portal/internal/service"
|
|
)
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// bootstrap 完成配置加载、数据库打开与加密组件构建。
|
|
func bootstrap() (*config.Config, *gorm.DB, *crypto.Cipher, error) {
|
|
cfg, err := config.Load()
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
db, err := database.Open(cfg.DBPath)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
cipher, err := crypto.NewCipher(cfg.DataKey)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
return cfg, db, cipher, nil
|
|
}
|
|
|
|
func run() error {
|
|
cfg, db, cipher, err := bootstrap()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
auth := service.NewAuthService(db, cfg.JWTSecret)
|
|
auth.SetCipher(cipher)
|
|
if err := auth.EnsureAdmin(cfg.AdminUsername, cfg.AdminPassword); err != nil {
|
|
return err
|
|
}
|
|
ociClient := oci.NewCachedClient(oci.NewClient())
|
|
ociConfigs := service.NewOciConfigService(db, cipher, ociClient)
|
|
settings := service.NewSettingService(db, cipher)
|
|
settings.SetEnvPublicURL(cfg.PublicURL)
|
|
if err := settings.ReloadSecurity(context.Background()); err != nil {
|
|
return err
|
|
}
|
|
notifier := service.NewNotifier(settings)
|
|
auth.SetNotifier(notifier, settings)
|
|
oauth := service.NewOAuthService(db, settings, auth)
|
|
systemLogs := service.NewSystemLogService(db)
|
|
logEvents := service.NewLogEventService(db)
|
|
logEvents.SetRelayDeps(ociConfigs, ociClient, cfg.PublicURL)
|
|
logEvents.SetNotifier(notifier, settings)
|
|
cleanupCtx, stopCleanup := context.WithCancel(context.Background())
|
|
systemLogs.StartCleanup(cleanupCtx)
|
|
logEvents.StartParser(cleanupCtx)
|
|
logEvents.StartCleanup(cleanupCtx)
|
|
aiGateway := service.NewAiGatewayService(db, ociConfigs, ociClient)
|
|
aiGateway.StartCleanup(cleanupCtx)
|
|
// defer 为 LIFO:先停调度与清理,再等在途通知与日志写完
|
|
defer logEvents.Wait()
|
|
defer systemLogs.Wait()
|
|
defer notifier.Wait()
|
|
defer aiGateway.Wait()
|
|
defer stopCleanup()
|
|
tasks := service.NewTaskService(db, ociConfigs, notifier, settings)
|
|
tasks.AttachAiGateway(aiGateway)
|
|
aiGateway.SetOnChannelsChanged(tasks.SyncAiProbeTask)
|
|
if err := tasks.Start(); err != nil {
|
|
return err
|
|
}
|
|
defer tasks.Stop()
|
|
// 启动时对齐一次探测任务(已有渠道而任务缺失/暂停时自动建立或激活)
|
|
tasks.SyncAiProbeTask(context.Background())
|
|
console := service.NewConsoleService(ociConfigs)
|
|
proxies := service.NewProxyService(db, cipher)
|
|
defer proxies.Wait()
|
|
return api.NewRouter(auth, oauth, ociConfigs, tasks, console, settings, notifier, systemLogs, logEvents, proxies, aiGateway).Run(cfg.Addr)
|
|
}
|