Adds web endpoint
This commit is contained in:
parent
045c8760fe
commit
0bd05b6efe
5 changed files with 121 additions and 4 deletions
|
@ -47,8 +47,16 @@ func main() {
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
srv.Start()
|
if err := srv.Start(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "ERROR: cannot start server: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
s := <-c
|
s := <-c
|
||||||
srv.Logger.Info("received signal, stopping", "signal", s)
|
srv.Logger.Info("received signal, stopping", "signal", s)
|
||||||
srv.Stop()
|
|
||||||
|
if err := srv.Stop(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "ERROR: cannot stop server: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
---
|
---
|
||||||
|
web:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
birthdays:
|
birthdays:
|
||||||
file: birthdays.csv
|
file: birthdays.csv
|
||||||
template: ./birthday_message.tmpl
|
template: ./birthday_message.tmpl
|
||||||
|
|
|
@ -19,6 +19,7 @@ var (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Birthdays *BirthdaysConfig `yaml:"birthdays"`
|
Birthdays *BirthdaysConfig `yaml:"birthdays"`
|
||||||
Logger *LoggerConfig `yaml:"logger"`
|
Logger *LoggerConfig `yaml:"logger"`
|
||||||
|
Web *WebConfig `yaml:"web"`
|
||||||
TelegramNotifications *TelegramNotificationsConfig `yaml:"telegram_notifications"`
|
TelegramNotifications *TelegramNotificationsConfig `yaml:"telegram_notifications"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,10 @@ func (c *Config) IsValid() error {
|
||||||
return fmt.Errorf("invalid logger config: %w", err)
|
return fmt.Errorf("invalid logger config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.Web.IsValid(); err != nil {
|
||||||
|
return fmt.Errorf("invalid web config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if c.TelegramNotifications != nil {
|
if c.TelegramNotifications != nil {
|
||||||
if err := c.TelegramNotifications.IsValid(); err != nil {
|
if err := c.TelegramNotifications.IsValid(); err != nil {
|
||||||
return fmt.Errorf("invalid telegram notifications config: %w", err)
|
return fmt.Errorf("invalid telegram notifications config: %w", err)
|
||||||
|
@ -53,6 +58,12 @@ func (c *Config) SetDefaults() {
|
||||||
|
|
||||||
c.Logger.SetDefaults()
|
c.Logger.SetDefaults()
|
||||||
|
|
||||||
|
if c.Web == nil {
|
||||||
|
c.Web = &WebConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Web.SetDefaults()
|
||||||
|
|
||||||
if c.TelegramNotifications != nil {
|
if c.TelegramNotifications != nil {
|
||||||
c.TelegramNotifications.SetDefaults()
|
c.TelegramNotifications.SetDefaults()
|
||||||
}
|
}
|
||||||
|
@ -99,6 +110,20 @@ func (lc *LoggerConfig) IsValid() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebConfig struct {
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebConfig) SetDefaults() {
|
||||||
|
if wc.Port == 0 {
|
||||||
|
wc.Port = 8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WebConfig) IsValid() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type TelegramNotificationsConfig struct {
|
type TelegramNotificationsConfig struct {
|
||||||
BotToken string `yaml:"bot_token"`
|
BotToken string `yaml:"bot_token"`
|
||||||
ChannelID string `yaml:"channel_id"`
|
ChannelID string `yaml:"channel_id"`
|
||||||
|
|
|
@ -22,6 +22,7 @@ var (
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Logger *log.Logger
|
Logger *log.Logger
|
||||||
Config *model.Config
|
Config *model.Config
|
||||||
|
WebServer *WebServer
|
||||||
workers []Worker
|
workers []Worker
|
||||||
birthdays []*model.Birthday
|
birthdays []*model.Birthday
|
||||||
notificationServices []notification.NotificationService
|
notificationServices []notification.NotificationService
|
||||||
|
@ -107,23 +108,45 @@ func New(options ...Option) (*Server, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if srv.WebServer == nil {
|
||||||
|
srv.Logger.Debug("creating web server")
|
||||||
|
|
||||||
|
srv.WebServer = NewWebServer(srv)
|
||||||
|
}
|
||||||
|
|
||||||
return srv, nil
|
return srv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() {
|
func (s *Server) Start() error {
|
||||||
s.Logger.Info("starting server")
|
s.Logger.Info("starting server")
|
||||||
|
|
||||||
|
if err := s.WebServer.Start(); err != nil {
|
||||||
|
return fmt.Errorf("cannot start web server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, worker := range s.workers {
|
for _, worker := range s.workers {
|
||||||
worker.Start()
|
worker.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Logger.Debug("server started", "workers", len(s.workers))
|
s.Logger.Debug("server started", "workers", len(s.workers))
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Stop() {
|
func (s *Server) Stop() error {
|
||||||
s.Logger.Info("stopping server")
|
s.Logger.Info("stopping server")
|
||||||
|
|
||||||
|
if err := s.WebServer.Stop(); err != nil {
|
||||||
|
return fmt.Errorf("cannot stop web server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, worker := range s.workers {
|
for _, worker := range s.workers {
|
||||||
worker.Stop()
|
worker.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Logger.Debug("server stopped", "workers", len(s.workers))
|
s.Logger.Debug("server stopped", "workers", len(s.workers))
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Notify(birthday *model.Birthday) error {
|
func (s *Server) Notify(birthday *model.Birthday) error {
|
||||||
|
|
58
server/web.go
Normal file
58
server/web.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/charmbracelet/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WebServer struct {
|
||||||
|
server *Server
|
||||||
|
logger *log.Logger
|
||||||
|
httpServer *http.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebServer(server *Server) *WebServer {
|
||||||
|
ws := &WebServer{
|
||||||
|
server: server,
|
||||||
|
logger: server.Logger,
|
||||||
|
httpServer: &http.Server{
|
||||||
|
Addr: fmt.Sprintf(":%d", server.Config.Web.Port),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/health", ws.healthHandler)
|
||||||
|
|
||||||
|
ws.httpServer.Handler = mux
|
||||||
|
|
||||||
|
return ws
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) Start() error {
|
||||||
|
ws.logger.Debug("starting web server")
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := ws.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||||
|
ws.logger.Fatal("cannot start web server", "error", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) Stop() error {
|
||||||
|
ws.logger.Debug("stopping web server")
|
||||||
|
|
||||||
|
if err := ws.httpServer.Close(); err != nil {
|
||||||
|
return fmt.Errorf("cannot stop web server: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) healthHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprint(w, "OK")
|
||||||
|
}
|
Loading…
Reference in a new issue