Files
NianAIGC/backend/internal/application/application.go

114 lines
2.7 KiB
Go

// Package application composes the Go backend foundation Modules.
package application
import (
"context"
"net/http"
"os"
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/httpapi"
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity"
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/postgres"
)
type Options struct {
Context context.Context
Getenv postgres.Getenv
ReadFile postgres.ReadFile
// AuthorizationLoader is an optional Identity persistence Adapter used by
// composition tests and alternate runtime backends. Production defaults to
// the PostgreSQL Store opened below.
AuthorizationLoader identity.AuthorizationSnapshotLoader
}
type App struct {
handler http.Handler
db *postgres.Module
}
func New(options Options) (*App, error) {
ctx := options.Context
if ctx == nil {
ctx = context.Background()
}
getenv := options.Getenv
if getenv == nil {
getenv = os.Getenv
}
readFile := options.ReadFile
if readFile == nil {
readFile = os.ReadFile
}
authConfig, err := ParseAuthConfig(getenv)
if err != nil {
return nil, err
}
config, err := postgres.ParseConfig(getenv, readFile)
if err != nil {
return nil, err
}
database, err := postgres.Open(ctx, config)
if err != nil {
return nil, err
}
closeOnError := true
defer func() {
if closeOnError {
database.Close()
}
}()
readiness := databaseReadiness{config: config, store: database.Store}
var resolver httpapi.SessionResolver
if authConfig.Configured {
loader := options.AuthorizationLoader
if loader == nil {
loader = database.Store
}
resolver = identity.NewResolver(loader, authConfig.SessionSecret, "platform", nil)
}
authMe, err := httpapi.NewAuthMeHandler(httpapi.AuthState{
Required: authConfig.Required, Configured: authConfig.Configured,
}, resolver)
if err != nil {
return nil, err
}
foundation := httpapi.NewHandler(readiness)
mux := http.NewServeMux()
mux.Handle("/api/auth/me", authMe)
mux.Handle("/", foundation)
closeOnError = false
return &App{
db: database,
handler: mux,
}, nil
}
func (app *App) Handler() http.Handler {
return app.handler
}
func (app *App) Close() {
if app.db != nil {
app.db.Close()
}
}
type databaseReadiness struct {
config postgres.Config
store *postgres.Store
}
func (adapter databaseReadiness) Status() httpapi.DatabaseStatus {
configured := adapter.config.Backend == postgres.BackendLocal || adapter.config.DatabaseURL != ""
return httpapi.DatabaseStatus{
Backend: string(adapter.config.Backend),
Configured: configured,
}
}
func (adapter databaseReadiness) Ready(ctx context.Context) (httpapi.DatabaseStatus, error) {
status := adapter.Status()
return status, adapter.store.Readiness(ctx)
}