implement work with services
This commit is contained in:
90
cmd/serve.go
90
cmd/serve.go
@@ -13,16 +13,23 @@ import (
|
||||
|
||||
"git.oblat.lv/alex/triggerssmith/api"
|
||||
application "git.oblat.lv/alex/triggerssmith/internal/app"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/auth"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/config"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/jwt"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/server"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/token"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/user"
|
||||
"git.oblat.lv/alex/triggerssmith/internal/vars"
|
||||
"github.com/spf13/cobra"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var optsServeCmd = struct {
|
||||
ConfigPath *string
|
||||
Debug *bool
|
||||
HideGreetings *bool
|
||||
NoPIDFile *bool
|
||||
}{}
|
||||
|
||||
// // simple middleware for request logging
|
||||
@@ -99,10 +106,8 @@ var serveCmd = &cobra.Command{
|
||||
fmt.Fprintf(f, "Panic: %v\n", r)
|
||||
f.Write(stack)
|
||||
f.WriteString("\n\n")
|
||||
}
|
||||
|
||||
slog.Error("Application panicked: the stack is flushed to disk", slog.Any("error", r))
|
||||
|
||||
}
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
@@ -114,6 +119,7 @@ var serveCmd = &cobra.Command{
|
||||
slog.SetDefault(slog.New(slog.NewTextHandler(cmd.OutOrStdout(), &slog.HandlerOptions{Level: slog.LevelInfo})))
|
||||
}
|
||||
|
||||
if !*optsServeCmd.NoPIDFile {
|
||||
pid := os.Getpid()
|
||||
slog.Debug("Starting server", slog.Int("pid", pid))
|
||||
if err := writePID(vars.PID_PATH); err != nil {
|
||||
@@ -121,6 +127,9 @@ var serveCmd = &cobra.Command{
|
||||
}
|
||||
slog.Debug("created pid file", slog.String("path", vars.PID_PATH))
|
||||
defer os.Remove(vars.PID_PATH)
|
||||
} else {
|
||||
slog.Warn("Starting server without PID file as requested by --no-pidfile flag: this may complicate process management")
|
||||
}
|
||||
|
||||
// load config
|
||||
slog.Debug("Reading configuration", slog.String("path", *optsServeCmd.ConfigPath))
|
||||
@@ -141,8 +150,80 @@ var serveCmd = &cobra.Command{
|
||||
|
||||
srv := app.Server()
|
||||
|
||||
// Services initialization
|
||||
var jwtSigner jwt.Signer
|
||||
// TODO: support more signing algorithms
|
||||
// : support hot config reload for signing alg and secret
|
||||
switch cfg.Auth.SignAlg {
|
||||
case "HS256":
|
||||
secretBytes, err := os.ReadFile(cfg.Auth.HMACSecretPath)
|
||||
if err != nil {
|
||||
slog.Error("Failed to read HMAC secret file", slog.String("path", cfg.Auth.HMACSecretPath), slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
jwtSigner = jwt.NewHMACSigner(secretBytes)
|
||||
default:
|
||||
slog.Error("Unsupported JWT signing algorithm", slog.String("alg", cfg.Auth.SignAlg))
|
||||
return
|
||||
}
|
||||
jwtService := jwt.NewService(jwtSigner)
|
||||
|
||||
router := api.NewRouter(cfg)
|
||||
err = os.MkdirAll(cfg.Data.DataPath, 0755)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create data directory", slog.String("path", cfg.Data.DataPath), slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
tokenDb, err := gorm.Open(sqlite.Open(filepath.Join(cfg.Data.DataPath, "tokens.sqlite3")), &gorm.Config{})
|
||||
if err != nil {
|
||||
slog.Error("Failed to open token database", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
err = tokenDb.AutoMigrate(&token.Token{})
|
||||
if err != nil {
|
||||
slog.Error("Failed to migrate token database", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
tokenStore, err := token.NewSQLiteTokenStore(tokenDb)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create token store", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
tokenService, err := token.NewTokenService(&cfg.Auth, tokenStore)
|
||||
|
||||
userDb, err := gorm.Open(sqlite.Open(filepath.Join(cfg.Data.DataPath, "users.sqlite3")), &gorm.Config{})
|
||||
if err != nil {
|
||||
slog.Error("Failed to open user database", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
err = userDb.AutoMigrate(&user.User{})
|
||||
if err != nil {
|
||||
slog.Error("Failed to migrate user database", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
userStore, err := user.NewGormUserStore(userDb)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create user store", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
userService, err := user.NewService(userStore)
|
||||
|
||||
authService, err := auth.NewAuthService(auth.AuthServiceDependencies{
|
||||
Configuration: cfg,
|
||||
|
||||
JWTService: jwtService,
|
||||
UserService: userService,
|
||||
TokenService: tokenService,
|
||||
})
|
||||
if err != nil {
|
||||
slog.Error("Failed to create auth service", slog.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
router := api.NewRouter(api.RouterDependencies{
|
||||
AuthService: authService,
|
||||
Configuration: cfg,
|
||||
})
|
||||
|
||||
srv.SetHandler(router.MustRoute())
|
||||
srv.Init()
|
||||
@@ -204,5 +285,6 @@ func init() {
|
||||
optsServeCmd.Debug = serveCmd.Flags().BoolP("debug", "d", false, "Enable debug logs")
|
||||
optsServeCmd.ConfigPath = serveCmd.Flags().StringP("config", "c", "config.yaml", "Path to configuration file")
|
||||
optsServeCmd.HideGreetings = serveCmd.Flags().BoolP("hide-greetings", "g", false, "Hide the welcome message and version when starting the server")
|
||||
optsServeCmd.NoPIDFile = serveCmd.Flags().BoolP("no-pidfile", "p", false, "Do not write a PID file")
|
||||
rootCmd.AddCommand(serveCmd)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user