Files
backend/cloudprint-backend/cmd/server/main.go

164 lines
4.7 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"net"
"os"
"os/signal"
"syscall"
"github.com/cloudprint/cloudprint-backend/config"
"github.com/cloudprint/cloudprint-backend/internal/grpc"
"github.com/cloudprint/cloudprint-backend/internal/grpc/interceptor"
"github.com/cloudprint/cloudprint-backend/internal/grpc/service"
"github.com/cloudprint/cloudprint-backend/internal/model"
"github.com/cloudprint/cloudprint-backend/internal/repository"
"github.com/cloudprint/cloudprint-backend/internal/service"
"github.com/cloudprint/cloudprint-backend/pkg/jwt"
"github.com/cloudprint/cloudprint-backend/pkg/pay"
"github.com/cloudprint/cloudprint-backend/pkg/upload"
pb "github.com/cloudprint/cloudprint-backend/proto/generated"
"go.uber.org/zap"
"google.golang.org/grpc"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func main() {
configPath := flag.String("config", "config.yaml", "path to config file")
flag.Parse()
// Load configuration
cfg, err := config.LoadConfig(*configPath)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// Initialize logger
zapLogger, _ := zap.NewProduction()
defer zapLogger.Sync()
// Initialize database
db, err := initDB(cfg)
if err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
// Auto migrate
if err := db.AutoMigrate(
&model.User{},
&model.Admin{},
&model.Printer{},
&model.Order{},
&model.OrderItem{},
&model.File{},
&model.LibraryCategory{},
&model.LibraryFile{},
&model.PrintJob{},
&model.PriceList{},
&model.Payment{},
); err != nil {
log.Fatalf("Failed to migrate database: %v", err)
}
// Initialize repositories
userRepo := repository.NewUserRepository(db)
adminRepo := repository.NewAdminRepository(db)
fileRepo := repository.NewFileRepository(db)
orderRepo := repository.NewOrderRepository(db)
orderItemRepo := repository.NewOrderItemRepository(db)
printerRepo := repository.NewPrinterRepository(db)
printJobRepo := repository.NewPrintJobRepository(db)
libraryRepo := repository.NewLibraryRepository(db)
priceRepo := repository.NewPriceRepository(db)
paymentRepo := repository.NewPaymentRepository(db)
// Initialize JWT manager
jwtManager := jwt.NewJWTManager(
cfg.JWT.Secret,
cfg.JWT.AccessTokenTTL,
cfg.JWT.RefreshTokenTTL,
)
// Initialize file uploader
fileUploader := upload.NewFileUploader(
cfg.Upload.Path,
cfg.Upload.ChunkPath,
cfg.Upload.MaxSize,
)
// Initialize WeChat pay
weChatPay := pay.NewWeChatPay(&cfg.WeChat)
// Initialize services
authService := service.NewAuthService(userRepo, adminRepo, jwtManager, nil, &cfg.WeChat)
fileService := service.NewFileService(fileRepo, fileUploader, cfg.Upload.Path)
orderService := service.NewOrderService(orderRepo, orderItemRepo, fileRepo, priceRepo, userRepo, printerRepo, printJobRepo)
printService := service.NewPrintService(printerRepo, printJobRepo, orderRepo)
// Initialize gRPC server
grpcServer := grpc.NewServer(
grpc.UnaryInterceptor(interceptor.NewAuthInterceptor(jwtManager).UnaryServerInterceptor()),
)
// Register gRPC services
pb.RegisterAuthServiceServer(grpcServer, service.NewAuthServiceServer(authService))
pb.RegisterFileServiceServer(grpcServer, service.NewFileServiceServer(fileService))
pb.RegisterOrderServiceServer(grpcServer, service.NewOrderServiceServer(orderService))
pb.RegisterPrintServiceServer(grpcServer, service.NewPrintServiceServer(printService))
pb.RegisterLibraryServiceServer(grpcServer, service.NewLibraryServiceServer(libraryRepo, fileRepo))
pb.RegisterPriceServiceServer(grpcServer, service.NewPriceServiceServer(priceRepo))
pb.RegisterPayServiceServer(grpcServer, service.NewPayServiceServer(orderService, paymentRepo, weChatPay, userRepo))
pb.RegisterAdminServiceServer(grpcServer, service.NewAdminServiceServer(authService, orderRepo, printerRepo))
// Start server
addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
lis, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
// Graceful shutdown
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigCh
grpcServer.GracefulStop()
}()
zapLogger.Info("Starting gRPC server", zap.String("address", addr))
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
func initDB(cfg *config.Config) (*gorm.DB, error) {
gormLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags),
logger.Config{
LogLevel: logger.Info,
},
)
db, err := gorm.Open(mysql.Open(cfg.Database.DSN()), &gorm.Config{
Logger: gormLogger,
})
if err != nil {
return nil, err
}
sqlDB, err := db.DB()
if err != nil {
return nil, err
}
sqlDB.SetMaxOpenConns(cfg.Database.MaxOpenConns)
sqlDB.SetMaxIdleConns(cfg.Database.MaxIdleConns)
return db, nil
}