package server import ( "net" "time" "github.com/go-redis/redis/v8" "github.com/gofiber/fiber/v2" "github.com/jackc/pgx/v5/pgxpool" amqp "github.com/rabbitmq/amqp091-go" "git.pbiernat.io/egommerce/api-entities/http" "git.pbiernat.io/egommerce/go-api-pkg/consul" "git.pbiernat.io/egommerce/go-api-pkg/fluentd" ) type ( Server struct { *fiber.App ID string addr string // e.g. "127.0.0.1:80" handlers map[string]any } HeaderRequestID struct { RequestID string `reqHeader:"x-request-id"` } ) func New(c *Config) *Server { return &Server{ ID: c.ID, App: fiber.New(fiber.Config{ AppName: c.ID, ServerHeader: c.Name + ":" + c.ID, ReadTimeout: c.ReadTimeout * time.Millisecond, WriteTimeout: c.WriteTimeout * time.Millisecond, IdleTimeout: c.IdleTimeout * time.Millisecond, }), addr: c.NetAddr, handlers: make(map[string]any), } } func (s *Server) Start() error { SetupMiddleware(s) SetupRouter(s) // fmt.Printf("Starting server at: %s...\n", s.addr) ln, _ := net.Listen("tcp", s.addr) // ln = tls.NewListener(ln, s.App.Server().TLSConfig) return s.Listener(ln) } func (s *Server) RegisterHandler(name string, fn func() any) { // fmt.Printf("Registering plugin( with handler): %s... OK\n", name) s.handlers[name] = fn() } func (s *Server) OnShutdown() { // s.GetLogger().Log("Server %s is going down...", s.ID) s.GetRegistry().Unregister() // a.clearMetadataCache() s.GetEventBus().Close() s.GetDatabase().Close() s.GetLogger().Log("Gone.") s.GetLogger().Close() s.Shutdown() } func (s *Server) GetRequestID(c *fiber.Ctx) (string, error) { var hdr = new(HeaderRequestID) if err := c.ReqHeaderParser(hdr); err != nil { return "", err } return hdr.RequestID, nil } func (s *Server) Error(c *fiber.Ctx, code int, msg string) error { return c.Status(code).JSON(http.ErrorResponse{Error: msg}) } // Plugin helper funcitons func (s *Server) GetCache() *redis.Client { return (s.handlers["cache"]).(*redis.Client) } func (s *Server) GetDatabase() *pgxpool.Pool { // FIXME hardcoded index issue return (s.handlers["database"]).(*pgxpool.Pool) } func (s *Server) GetEventBus() *amqp.Channel { return (s.handlers["eventbus"]).(*amqp.Channel) } func (s *Server) GetLogger() *fluentd.Logger { return (s.handlers["logger"]).(*fluentd.Logger) } func (s *Server) GetRegistry() *consul.Service { return (s.handlers["registry"]).(*consul.Service) } // @CHECK: merge s.Config and s.Base.Config to display all config as one array/map // func (s *Server) registerKVUpdater() { // @FIXME: merge duplication in server.go and worker.go // go func() { // ticker := time.NewTicker(time.Second * 10) // for range ticker.C { // config, _, err := s.Registry.KV().Get(s.Config.KVNamespace, nil) // if err != nil || config == nil { // return // } // kvCnf := bytes.NewBuffer(config.Value) // decoder := json.NewDecoder(kvCnf) // if err := decoder.Decode(&s.Config); err != nil { // return // } // } // }() // } // func (s *Server) clearMetadataCache() { // ctx := context.Background() // key, address := s.getMetadataIPsKey(), s.Config.Base.AppID // s.Cache.LRem(ctx, key, 0, address) // } // func (s *Server) getMetadataIPsKey() string { // return "internal__" + s.Base.Config.AppName + "__ips" // }