1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00
wakapi/main.go

166 lines
4.8 KiB
Go
Raw Normal View History

2019-05-05 23:36:49 +03:00
package main
import (
"github.com/gorilla/handlers"
2019-05-06 01:58:01 +03:00
"log"
2019-05-05 23:36:49 +03:00
"net/http"
"strconv"
"time"
2019-05-06 00:23:54 +03:00
"github.com/gorilla/mux"
2019-05-11 18:49:56 +03:00
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
_ "github.com/jinzhu/gorm/dialects/postgres"
_ "github.com/jinzhu/gorm/dialects/sqlite"
2020-03-31 13:22:17 +03:00
"github.com/muety/wakapi/middlewares"
"github.com/muety/wakapi/models"
"github.com/muety/wakapi/routes"
"github.com/muety/wakapi/services"
"github.com/muety/wakapi/utils"
2019-05-05 23:36:49 +03:00
)
2020-05-24 17:34:32 +03:00
var (
db *gorm.DB
config *models.Config
)
var (
aliasService *services.AliasService
heartbeatService *services.HeartbeatService
userService *services.UserService
summaryService *services.SummaryService
aggregationService *services.AggregationService
keyValueService *services.KeyValueService
2020-05-24 17:34:32 +03:00
)
2020-03-31 12:24:44 +03:00
// TODO: Refactor entire project to be structured after business domains
2019-05-05 23:36:49 +03:00
func main() {
config = models.GetConfig()
2020-05-24 17:34:32 +03:00
2020-04-20 02:58:54 +03:00
// Enable line numbers in logging
if config.IsDev() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
2019-05-05 23:36:49 +03:00
2019-05-11 18:49:56 +03:00
// Connect to database
2020-05-24 17:34:32 +03:00
var err error
db, err = gorm.Open(config.DbDialect, utils.MakeConnectionString(config))
2020-04-20 02:58:54 +03:00
if config.DbDialect == "sqlite3" {
db.DB().Exec("PRAGMA foreign_keys = ON;")
}
2020-03-09 19:30:23 +03:00
db.LogMode(config.IsDev())
db.DB().SetMaxIdleConns(int(config.DbMaxConn))
db.DB().SetMaxOpenConns(int(config.DbMaxConn))
2019-05-05 23:36:49 +03:00
if err != nil {
2020-04-20 02:58:54 +03:00
log.Println(err)
log.Fatal("could not connect to database")
2019-05-05 23:36:49 +03:00
}
2020-03-31 13:03:49 +03:00
// TODO: Graceful shutdown
2019-05-11 18:49:56 +03:00
defer db.Close()
// Migrate database schema
runDatabaseMigrations()
applyFixtures()
2019-05-05 23:36:49 +03:00
2019-05-06 01:40:41 +03:00
// Services
aliasService = services.NewAliasService(db)
heartbeatService = services.NewHeartbeatService(db)
userService = services.NewUserService(db)
summaryService = services.NewSummaryService(db, heartbeatService, aliasService)
aggregationService = services.NewAggregationService(db, userService, summaryService, heartbeatService)
keyValueService = services.NewKeyValueService(db)
2020-02-20 16:28:55 +03:00
2020-05-24 17:34:32 +03:00
// Custom migrations and initial data
migrateLanguages()
2019-10-11 10:06:34 +03:00
// Aggregate heartbeats to summaries and persist them
2020-05-24 17:34:32 +03:00
go aggregationService.Schedule()
2019-05-06 01:40:41 +03:00
2020-03-09 19:30:23 +03:00
if config.CleanUp {
2020-05-24 17:34:32 +03:00
go heartbeatService.ScheduleCleanUp()
2020-03-09 19:30:23 +03:00
}
2019-05-06 01:40:41 +03:00
// Handlers
heartbeatHandler := routes.NewHeartbeatHandler(heartbeatService)
summaryHandler := routes.NewSummaryHandler(summaryService)
healthHandler := routes.NewHealthHandler(db)
publicHandler := routes.NewIndexHandler(userService, keyValueService)
2019-05-06 01:40:41 +03:00
// Setup Routers
2019-05-06 00:23:54 +03:00
router := mux.NewRouter()
publicRouter := router.PathPrefix("/").Subrouter()
summaryRouter := publicRouter.PathPrefix("/summary").Subrouter()
apiRouter := router.PathPrefix("/api").Subrouter()
2019-05-06 00:23:54 +03:00
// Middlewares
recoveryMiddleware := handlers.RecoveryHandler()
loggingMiddleware := middlewares.NewLoggingMiddleware().Handler
corsMiddleware := handlers.CORS()
authenticateMiddleware := middlewares.NewAuthenticateMiddleware(
2020-05-24 17:34:32 +03:00
userService,
[]string{"/api/health"},
).Handler
// Router configs
router.Use(loggingMiddleware, recoveryMiddleware)
summaryRouter.Use(authenticateMiddleware)
apiRouter.Use(corsMiddleware, authenticateMiddleware)
// Public Routes
publicRouter.Path("/").Methods(http.MethodGet).HandlerFunc(publicHandler.Index)
publicRouter.Path("/login").Methods(http.MethodPost).HandlerFunc(publicHandler.Login)
publicRouter.Path("/logout").Methods(http.MethodPost).HandlerFunc(publicHandler.Logout)
publicRouter.Path("/signup").Methods(http.MethodGet, http.MethodPost).HandlerFunc(publicHandler.Signup)
publicRouter.Path("/imprint").Methods(http.MethodGet).HandlerFunc(publicHandler.Imprint)
// Summary Routes
summaryRouter.Methods(http.MethodGet).HandlerFunc(summaryHandler.Index)
2020-02-20 16:28:55 +03:00
2019-05-06 00:23:54 +03:00
// API Routes
2020-03-31 12:24:44 +03:00
apiRouter.Path("/heartbeat").Methods(http.MethodPost).HandlerFunc(heartbeatHandler.ApiPost)
apiRouter.Path("/summary").Methods(http.MethodGet).HandlerFunc(summaryHandler.ApiGet)
2020-04-08 22:29:11 +03:00
apiRouter.Path("/health").Methods(http.MethodGet).HandlerFunc(healthHandler.ApiGet)
2019-05-06 00:23:54 +03:00
2020-02-20 16:28:55 +03:00
// Static Routes
router.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./static")))
2020-02-21 14:41:29 +03:00
2019-05-05 23:36:49 +03:00
// Listen HTTP
portString := config.Addr + ":" + strconv.Itoa(config.Port)
2019-05-05 23:36:49 +03:00
s := &http.Server{
2019-05-06 00:23:54 +03:00
Handler: router,
2019-05-05 23:36:49 +03:00
Addr: portString,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
2019-05-06 01:58:01 +03:00
log.Printf("Listening on %+s\n", portString)
2019-05-05 23:36:49 +03:00
s.ListenAndServe()
}
2019-05-21 23:01:14 +03:00
func runDatabaseMigrations() {
if err := config.GetMigrationFunc(config.DbDialect)(db); err != nil {
log.Fatal(err)
}
}
func applyFixtures() {
if err := config.GetFixturesFunc(config.DbDialect)(db); err != nil {
log.Fatal(err)
}
}
2020-05-24 17:34:32 +03:00
func migrateLanguages() {
for k, v := range config.CustomLanguages {
2019-05-21 23:01:14 +03:00
result := db.Model(models.Heartbeat{}).
Where("language = ?", "").
Where("entity LIKE ?", "%."+k).
Updates(models.Heartbeat{Language: v})
if result.Error != nil {
log.Fatal(result.Error)
}
2019-05-22 00:09:47 +03:00
if result.RowsAffected > 0 {
log.Printf("Migrated %+v rows for custom language %+s.\n", result.RowsAffected, k)
}
}
}