Skip to content

Commit

Permalink
Introduce app package. Move repo mocks into the repository package
Browse files Browse the repository at this point in the history
  • Loading branch information
mgerasimchuk committed Oct 31, 2024
1 parent 90d7725 commit 840e381
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 175 deletions.
84 changes: 3 additions & 81 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -1,91 +1,13 @@
package main

import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"strconv"
"syscall"
"time"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/app"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/config"

"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/mgerasimchuk/space-trouble/internal/adapter/controller"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/api"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/pg"
"github.com/mgerasimchuk/space-trouble/internal/entity/service"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/config"
"github.com/mgerasimchuk/space-trouble/internal/usecase"
"github.com/mgerasimchuk/space-trouble/pkg/util"
"github.com/sirupsen/logrus"
"github.com/toorop/gin-logrus"
)

func main() {
cfg := config.GetRootConfig()

logger := logrus.New()
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.Level(cfg.Log.Level))

logger.Info("Application starting...")

dbConnectionString := fmt.Sprintf(
"host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
cfg.DB.Host, cfg.DB.Port, cfg.DB.User, cfg.DB.Name, cfg.DB.Password,
)
db, err := gorm.Open("postgres", dbConnectionString)
if err != nil {
panic(err)
}

bookingRepo := pg.NewBookingRepository(db)
launchpadRepo := api.NewLaunchpadRepository(cfg.Launchpad.APIBaseURL)
landpadRepo := api.NewLandpadRepository(cfg.Landpad.APIBaseURL)
bookingService := service.NewBookingVerifierService()
bookingUsecase := usecase.NewBookingUsecase(bookingService, bookingRepo, launchpadRepo, landpadRepo)
bookingController := controller.NewBookingController(bookingUsecase, logger)

gin.SetMode(cfg.HTTPServer.Mode)
router := gin.Default()
router.Use(ginlogrus.Logger(logger), gin.Recovery())
router.Use(util.RequestLogger(logger))

router.POST("/v1/bookings", bookingController.CreateBooking)
router.GET("/v1/bookings", bookingController.GetBookings)
router.DELETE("/v1/bookings/:id", bookingController.DeleteBooking)

srv := &http.Server{
Addr: ":" + strconv.Itoa(cfg.HTTPServer.Port),
Handler: router,
}

go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatalf("listen: %s\n", err)
}
}()

logger.Infof("Application has been started")

// Wait for interrupting signal to gracefully shutdown the server with a 5 seconds timeout
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutting down server...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server forced to shutdown:", err)
}

if err := db.Close(); err != nil {
logger.Fatal("Error during db connection close:", err)
}

logger.Info("Service stopped")
app.StartAPIApp(cfg)
}
89 changes: 2 additions & 87 deletions cmd/verifier/main.go
Original file line number Diff line number Diff line change
@@ -1,98 +1,13 @@
package main

import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/jinzhu/gorm"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/api"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/app"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/config"

_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/sirupsen/logrus"

"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/pg"
"github.com/mgerasimchuk/space-trouble/internal/entity/service"
"github.com/mgerasimchuk/space-trouble/internal/usecase"
)

const logDateTimeLayout = "2006-01-02 15:04:05"

func main() {
cfg := config.GetRootConfig()

logger := logrus.New()
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.Level(cfg.Log.Level))

logger.Info("Application starting...")

dbConnectionString := fmt.Sprintf(
"host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
cfg.DB.Host, cfg.DB.Port, cfg.DB.User, cfg.DB.Name, cfg.DB.Password,
)
db, err := gorm.Open("postgres", dbConnectionString)
if err != nil {
panic(err)
}

bookingRepo := pg.NewBookingRepository(db)
launchpadRepo := api.NewLaunchpadRepository(cfg.Launchpad.APIBaseURL)
landpadRepo := api.NewLandpadRepository(cfg.Landpad.APIBaseURL)
bookingService := service.NewBookingVerifierService()
bookingUsecase := usecase.NewBookingUsecase(bookingService, bookingRepo, launchpadRepo, landpadRepo)

defer func() {
if r := recover(); r != nil {
logger.Panicf("App crashed & recovered with: %#v", r)
}
}()

ticker := time.NewTicker(time.Duration(cfg.Verifier.RunWorkersEveryMilliseconds * int(time.Millisecond)))
tickerDone := make(chan bool)
go func() {
for {
select {
case <-tickerDone:
return
case t := <-ticker.C:
logger.Debugf("[%s] Ticker triggered", t.Format(logDateTimeLayout))

wg := sync.WaitGroup{}
for i := 1; i < cfg.Verifier.WorkersCount; i++ {
wg.Add(1)
go func() {
defer wg.Done()
err = bookingUsecase.VerifyFirstAvailableBooking()
if err != nil {
logger.Error(err)
}
}()
}
wg.Wait()
}
}
}()

logger.Infof("Application has been started")

// Wait for interrupting signal to gracefully shutdown the server with a 5 seconds timeout
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

ticker.Stop()
tickerDone <- true

logger.Info("Ticker stopped")

if err := db.Close(); err != nil {
logger.Fatal("Error during db connection close:", err)
}

logger.Info("Service stopped")
app.StartVerifierApp(cfg)
}
89 changes: 89 additions & 0 deletions internal/infrastructure/app/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package app

import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"strconv"
"syscall"
"time"

"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/mgerasimchuk/space-trouble/internal/adapter/controller"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/api"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/pg"
"github.com/mgerasimchuk/space-trouble/internal/entity/service"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/config"
"github.com/mgerasimchuk/space-trouble/internal/usecase"
"github.com/mgerasimchuk/space-trouble/pkg/util"
"github.com/sirupsen/logrus"
"github.com/toorop/gin-logrus"
)

func StartAPIApp(cfg *config.RootConfig) {
logger := logrus.New()
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.Level(cfg.Log.Level))

logger.Info("Application starting...")

dbConnectionString := fmt.Sprintf(
"host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
cfg.DB.Host, cfg.DB.Port, cfg.DB.User, cfg.DB.Name, cfg.DB.Password,
)
db, err := gorm.Open("postgres", dbConnectionString)
if err != nil {
panic(err)
}

bookingRepo := pg.NewBookingRepository(db)
launchpadRepo := api.NewLaunchpadRepository(cfg.Launchpad.APIBaseURL)
landpadRepo := api.NewLandpadRepository(cfg.Landpad.APIBaseURL)
bookingService := service.NewBookingVerifierService()
bookingUsecase := usecase.NewBookingUsecase(bookingService, bookingRepo, launchpadRepo, landpadRepo)
bookingController := controller.NewBookingController(bookingUsecase, logger)

gin.SetMode(cfg.HTTPServer.Mode)
router := gin.Default()
router.Use(ginlogrus.Logger(logger), gin.Recovery())
router.Use(util.RequestLogger(logger))

router.POST("/v1/bookings", bookingController.CreateBooking)
router.GET("/v1/bookings", bookingController.GetBookings)
router.DELETE("/v1/bookings/:id", bookingController.DeleteBooking)

srv := &http.Server{
Addr: ":" + strconv.Itoa(cfg.HTTPServer.Port),
Handler: router,
}

go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatalf("listen: %s\n", err)
}
}()

logger.Infof("Application has been started")

// Wait for interrupting signal to gracefully shutdown the server with a 5 seconds timeout
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutting down server...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
logger.Fatal("Server forced to shutdown:", err)
}

if err := db.Close(); err != nil {
logger.Fatal("Error during db connection close:", err)
}

logger.Info("Service stopped")
}
96 changes: 96 additions & 0 deletions internal/infrastructure/app/verifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package app

import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/jinzhu/gorm"
"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/api"
"github.com/mgerasimchuk/space-trouble/internal/infrastructure/config"

_ "github.com/jinzhu/gorm/dialects/postgres"
"github.com/sirupsen/logrus"

"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/pg"
"github.com/mgerasimchuk/space-trouble/internal/entity/service"
"github.com/mgerasimchuk/space-trouble/internal/usecase"
)

const logDateTimeLayout = "2006-01-02 15:04:05"

func StartVerifierApp(cfg *config.RootConfig) {
logger := logrus.New()
logger.SetOutput(os.Stdout)
logger.SetLevel(logrus.Level(cfg.Log.Level))

logger.Info("Application starting...")

dbConnectionString := fmt.Sprintf(
"host=%s port=%d user=%s dbname=%s password=%s sslmode=disable",
cfg.DB.Host, cfg.DB.Port, cfg.DB.User, cfg.DB.Name, cfg.DB.Password,
)
db, err := gorm.Open("postgres", dbConnectionString)
if err != nil {
panic(err)
}

bookingRepo := pg.NewBookingRepository(db)
launchpadRepo := api.NewLaunchpadRepository(cfg.Launchpad.APIBaseURL)
landpadRepo := api.NewLandpadRepository(cfg.Landpad.APIBaseURL)
bookingService := service.NewBookingVerifierService()
bookingUsecase := usecase.NewBookingUsecase(bookingService, bookingRepo, launchpadRepo, landpadRepo)

defer func() {
if r := recover(); r != nil {
logger.Panicf("App crashed & recovered with: %#v", r)
}
}()

ticker := time.NewTicker(time.Duration(cfg.Verifier.RunWorkersEveryMilliseconds * int(time.Millisecond)))
tickerDone := make(chan bool)
go func() {
for {
select {
case <-tickerDone:
return
case t := <-ticker.C:
logger.Debugf("[%s] Ticker triggered", t.Format(logDateTimeLayout))

wg := sync.WaitGroup{}
for i := 1; i < cfg.Verifier.WorkersCount; i++ {
wg.Add(1)
go func() {
defer wg.Done()
err = bookingUsecase.VerifyFirstAvailableBooking()
if err != nil {
logger.Error(err)
}
}()
}
wg.Wait()
}
}
}()

logger.Infof("Application has been started")

// Wait for interrupting signal to gracefully shutdown the server with a 5 seconds timeout
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

ticker.Stop()
tickerDone <- true

logger.Info("Ticker stopped")

if err := db.Close(); err != nil {
logger.Fatal("Error during db connection close:", err)
}

logger.Info("Service stopped")
}
2 changes: 1 addition & 1 deletion internal/usecase/booking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"
"time"

"github.com/mgerasimchuk/space-trouble/internal/adapter/repository/mock"
"github.com/mgerasimchuk/space-trouble/internal/usecase/repository/mock"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)
Expand Down
Loading

0 comments on commit 840e381

Please sign in to comment.