package apiimp import ( "context" "github.com/go-chi/chi/v5" "github.com/tech/sendico/notification/interface/api" "github.com/tech/sendico/notification/interface/api/localizer" "github.com/tech/sendico/notification/interface/services/amplitude" "github.com/tech/sendico/notification/interface/services/notification" "github.com/tech/sendico/pkg/db" "github.com/tech/sendico/pkg/domainprovider" "github.com/tech/sendico/pkg/messaging" "github.com/tech/sendico/pkg/mlogger" "github.com/tech/sendico/pkg/mservice" "go.uber.org/zap" ) type Microservices = []mservice.MicroService type APIImp struct { logger mlogger.Logger db db.Factory localizer localizer.Localizer domain domainprovider.DomainProvider config *api.Config services Microservices debug bool mw *Middleware router *chi.Mux } func (a *APIImp) installMicroservice(srv mservice.MicroService) { a.services = append(a.services, srv) a.logger.Info("Microservice installed", zap.String("service", srv.Name())) } func (a *APIImp) addMicroservice(srvf api.MicroServiceFactoryT) error { srv, err := srvf(a) if err != nil { a.logger.Error("Failed to install a microservice", zap.Error(err)) return err } a.installMicroservice(srv) return nil } func (a *APIImp) Logger() mlogger.Logger { return a.logger } func (a *APIImp) Config() *api.Config { return a.config } func (a *APIImp) Localizer() localizer.Localizer { return a.localizer } func (a *APIImp) DBFactory() db.Factory { return a.db } func (a *APIImp) DomainProvider() domainprovider.DomainProvider { return a.domain } func (a *APIImp) Register() messaging.Register { return a.mw } func (a *APIImp) Router() *chi.Mux { return a.router } func (a *APIImp) installServices() error { srvf := make([]api.MicroServiceFactoryT, 0) srvf = append(srvf, amplitude.Create) srvf = append(srvf, notification.Create) for _, v := range srvf { err := a.addMicroservice(v) if err != nil { return err } } a.mw.SetStatus("ok") return nil } func (a *APIImp) Finish(ctx context.Context) error { a.mw.SetStatus("deactivating") a.mw.Finish() var lastError error // stop services in the reverse order for i := len(a.services) - 1; i >= 0; i-- { err := (a.services[i]).Finish(ctx) if err != nil { lastError = err a.logger.Warn("Error occurred when finishing service", zap.Error(err), zap.String("service_name", (a.services[i]).Name())) } else { a.logger.Info("Microservice is down", zap.String("service_name", (a.services[i]).Name())) } } return lastError } func (a *APIImp) Name() string { return "api" } func CreateAPI(logger mlogger.Logger, config *api.Config, l localizer.Localizer, db db.Factory, router *chi.Mux, debug bool) (mservice.MicroService, error) { p := new(APIImp) p.logger = logger.Named("api") p.debug = debug p.config = config p.db = db p.localizer = l p.router = router var err error if p.domain, err = domainprovider.CreateDomainProvider(p.logger, config.Mw.DomainEnv, config.Mw.APIProtocolEnv, config.Mw.EndPointEnv); err != nil { p.logger.Error("Failed to initizlize domain provider") return nil, err } odb, err := db.NewOrganizationDB() if err != nil { p.logger.Warn("Failed to create organization database", zap.Error(err)) return nil, err } if p.mw, err = CreateMiddleware(logger, odb, router, config.Mw, debug); err != nil { p.logger.Warn("Failed to create middleware", zap.Error(err)) return nil, err } p.logger.Info("Installing microservices...") if err := p.installServices(); err != nil { p.logger.Error("Failed to install a microservice", zap.Error(err)) return nil, err } p.logger.Info("Microservices installation complete", zap.Int("microservices", len(p.services))) return p, nil }