heruvym/app/app.go
2024-11-26 02:11:24 +03:00

268 lines
6.6 KiB
Go

package app
import (
"context"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
"heruvym/dal/minio"
"heruvym/dal/mongo"
"heruvym/middleware"
"heruvym/router"
"heruvym/service"
"heruvym/tools"
"net/http"
"time"
"github.com/skeris/appInit"
tb "gopkg.in/tucnak/telebot.v2"
"gitea.pena/PenaSide/hlog"
"go.uber.org/zap"
)
type App struct {
err chan error
logger *zap.Logger
}
const (
ENV = "env"
DEFAULT = "default"
)
type Options struct {
MongoURI string `env:"BB_MONGO_URI" default:"mongodb://localhost:27017"`
NumberPortLocal string `env:"BB_PORT" default:"1488"`
AccountAddress string `env:"BB_AccountAddress" default:":8931"`
LoggerDevMode bool `env:"BB_IS_PROD" default:"false"`
MinioEndpoint string `env:"BB_MINIO_EP" default:"minio:9001"`
MinioAccessKey string `env:"BB_MINIO_AK" default:"minio"`
MinioSecretKey string `env:"BB_MINIO_SK" default:"miniostorage"`
MinioRegion string `env:"S3_REGION" default:""`
MinioToken string `env:"BB_MINIO_TOKEN" default:""`
MongoDbTable string `env:"DATABASE_TABLE" default:"profile"`
MongoCollections string `env:"COLLECTION_NAME" default:"profile,role"`
TgToken string `env:"TELEGRAM_TOKEN" default:"5851043588:AAGXhigZAaNV1--n-jfS8eBgM7iZ2IDm668"`
RedisHost string `env:"REDIS_HOST" default:"localhost:6379"`
RedisPassword string `env:"REDIS_PASSWORD" default:""`
RedisDB uint64 `env:"REDIS_DB" default:"0"`
TgChatID uint64 `env:"TELEGRAM_CHAT_ID" default:"1001344671794"`
}
var (
errInvalidOptions = errors.New("invalid options")
)
var _ appInit.CommonApp = (*App)(nil)
type InfoSvcStarted struct{}
type InfoSvcReady struct{}
type InfoSvcShutdown struct {
Signal string
}
type ErrorStoring struct {
Err error
Uri string
}
type ErrorCanNotServe struct {
Err error
}
var zapOptions = []zap.Option{
zap.AddCaller(),
zap.AddCallerSkip(2),
zap.AddStacktrace(zap.ErrorLevel),
}
func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) {
var (
err error
zapLogger *zap.Logger
errChan = make(chan error)
options Options
ok bool
)
if options, ok = opts.(Options); !ok {
return App{}, errInvalidOptions
}
if options.LoggerDevMode {
zapLogger, err = zap.NewProduction(zapOptions...)
if err != nil {
return nil, err
}
} else {
zapLogger, err = zap.NewDevelopment(zapOptions...)
if err != nil {
return nil, err
}
}
zapLogger = zapLogger.With(
zap.String("SvcCommit", ver.Commit),
zap.String("SvcVersion", ver.Release),
zap.String("SvcBuildTime", ver.BuildTime),
)
logger := hlog.New(zapLogger)
logger.Emit(InfoSvcStarted{})
database, err := mongo.New(
ctx,
options.MongoURI,
"support",
logger,
)
if err != nil {
return nil, err
}
miniostore, err := minio.New(ctx, logger, options.MinioEndpoint, options.MinioAccessKey, options.MinioSecretKey, options.MinioToken, options.MinioRegion, false)
if err != nil {
fmt.Println(err)
return nil, err
}
redisClient := redis.NewClient(&redis.Options{
Addr: options.RedisHost,
Password: options.RedisPassword,
DB: int(options.RedisDB),
})
var newBot *tb.Bot
newBot, err = tb.NewBot(tb.Settings{
Token: options.TgToken,
Verbose: false,
ParseMode: tb.ModeHTML,
Poller: &tb.LongPoller{
Timeout: time.Second,
},
})
if err != nil {
//logger.Emit(json.Token(err))
return nil, err
}
heruvym := service.New(miniostore, database, logger, newBot, -int64(options.TgChatID), redisClient)
mux := router.NewRouter(map[string]http.HandlerFunc{
"/create": heruvym.CreateTicket,
"/subscribe": tools.SseWrapper(heruvym.GetList),
"/ticket": tools.SseWrapper(heruvym.Subscribe),
"/send": tools.HandlerWrapper(heruvym.PutMessage),
"/requestScreenshot": tools.HandlerWrapper(heruvym.RequestScreenshot),
"/sendFiles": heruvym.PutFile,
"/sendSC": heruvym.PutSC,
"/getTickets": tools.HandlerWrapper(heruvym.GetTickets),
"/getMessages": tools.HandlerWrapper(heruvym.GetMessages),
"/pick": tools.HandlerWrapper(heruvym.Pick),
"/delegate": tools.HandlerWrapper(heruvym.Delegate),
"/vote": tools.HandlerWrapper(heruvym.Vote),
"/close": tools.HandlerWrapper(heruvym.CloseTicket),
"/shown": tools.HandlerWrapper(heruvym.SetShown),
})
mw := middleware.NewMiddleware(
logger,
"*",
nil,
)
mux.Use(
func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// w.Header().Set("Access-Control-Allow-Origin", r.Header["Origin"][0])
// w.Header().Set("Access-Control-Allow-Credentials", "true")
// w.Header().Set("Access-Control-Allow-Headers", "content-type")
// w.Header().Set("Access-Control-Expose-Headers", "*")
if r.Method == http.MethodOptions {
return
}
handler.ServeHTTP(w, r)
})
},
mw.MiddlewareLogger,
//mw.MiddlewareOriginAccess,
mw.MiddlewareRecovery,
mw.MiddlewareJwt,
mw.MiddlewareGetJwt,
//mw.MiddlewareJwtPlug,
//mw.MiddlewareRoleAccess,
mw.ExtractHostMiddleware,
)
fmt.Println("mux")
server := &http.Server{
Handler: mux,
Addr: fmt.Sprintf(":%s", options.NumberPortLocal),
}
// Account Server
accountService := service.NewAccount(database)
accountServer := NewAccountHTTP(database, zapLogger)
accountServer.Register(accountService.GetRoutes()...)
go func() {
defer func() {
if err := server.Shutdown(ctx); err != nil {
errChan <- err
}
if err := accountServer.Stop(); err != nil {
errChan <- err
}
}()
logger.Emit(InfoSvcStarted{})
tmplKey := "%s.key"
tmplCrt := "%s.crt"
tmplCrt = fmt.Sprintf(tmplCrt, "prod")
tmplKey = fmt.Sprintf(tmplKey, "prod")
fmt.Println("ISPROd", options.LoggerDevMode)
if options.LoggerDevMode {
if err := server.ListenAndServeTLS(tmplCrt, tmplKey); err != nil {
logger.Emit(ErrorCanNotServe{
Err: err,
})
errChan <- err
}
go func() {
if err := accountServer.StartTLS(options.AccountAddress, tmplCrt, tmplKey); err != nil {
logger.Emit(ErrorCanNotServe{Err: err})
errChan <- err
}
}()
} else {
fmt.Println("startserver" + options.NumberPortLocal)
if err := server.ListenAndServe(); err != nil {
errChan <- err
}
go func() {
if err := accountServer.Start(options.AccountAddress); err != nil {
logger.Emit(ErrorCanNotServe{Err: err})
errChan <- err
}
}()
}
}()
return &App{
logger: zapLogger,
err: errChan,
}, nil
}
func (a App) GetLogger() *zap.Logger {
return a.logger
}
func (a App) GetErr() chan error {
return a.err
}