diff options
Diffstat (limited to 'backend/cmd')
| -rw-r--r-- | backend/cmd/server/main.go | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go new file mode 100644 index 0000000..f734885 --- /dev/null +++ b/backend/cmd/server/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "context" + "log" + "net/http" + "os" + + "os/signal" + "syscall" + + "github.com/joho/godotenv" + "golang.org/x/crypto/bcrypt" + + "yaum/internal/alerts" + "yaum/internal/api" + "yaum/internal/config" + "yaum/internal/monitor" + "yaum/internal/sse" + "yaum/internal/store" +) + +func main() { + godotenv.Load() + + cfgPath := os.Getenv("CONFIG_PATH") + cfg, err := config.Load(cfgPath) + if err != nil { + log.Fatalf("config: %v", err) + } + + passwordHash := cfg.AdminPasswordHash() + if passwordHash == "" { + if pw := os.Getenv("ADMIN_PASSWORD"); pw != "" { + hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost) + if err != nil { + log.Fatalf("erro ao gerar hash da senha: %v", err) + } + passwordHash = string(hash) + } + } + if passwordHash == "" { + log.Fatal("ADMIN_PASSWORD_HASH ou ADMIN_PASSWORD nao definido — defina no .env ou config.json") + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var st store.Store + + if dbURL := cfg.DatabaseURL(); dbURL != "" { + log.Println("conectando ao postgres...") + pg, err := store.NewPostgresStore(ctx, dbURL) + if err != nil { + log.Fatalf("banco: %v", err) + } + defer pg.Close() + st = pg + log.Println("conectado ao postgres") + } else { + log.Println("database.url vazio — usando store em memoria") + ms := store.NewMemoryStore() + ms.SeedMockData() + st = ms + } + + broadcaster := sse.NewBroadcaster() + + worker := monitor.NewWorker(st, cfg.CheckInterval(), cfg.CheckTimeout(), broadcaster) + if cfg.SMTP.From != "" { + smtpCfg := &alerts.SMTPConfig{ + Host: cfg.SMTP.Host, + Port: cfg.SMTP.Port, + Username: cfg.SMTP.Username, + Password: cfg.SMTP.Password, + From: cfg.SMTP.From, + } + worker.WithSMTP(smtpCfg) + } + handler := api.NewHandler(st, int(cfg.CheckTimeout().Seconds())) + streamHandler := api.NewStreamHandler(broadcaster) + authHandler := api.NewAuthHandler( + cfg.AdminUsername(), + passwordHash, + cfg.JWTSecret(), + ) + + server := &http.Server{ + Addr: cfg.ServerAddr(), + Handler: api.NewRouter(handler, streamHandler, authHandler), + } + + go worker.Start(ctx) + + go func() { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + sig := <-sigCh + log.Printf("sinal recebido: %s. desligando...", sig) + worker.Stop() + server.Shutdown(context.Background()) + }() + + log.Printf("yaum rodando em %s", cfg.ServerAddr()) + if err := server.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("erro ao iniciar servidor: %v", err) + } + log.Println("servidor encerrado com sucesso") +} |