123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- package main
- import (
- "context"
- "database/sql"
- "log"
- "net/http"
- "os"
- "os/signal"
- "time"
- "code.osinet.fr/fgm/kurz/web/ui"
- "github.com/spf13/viper"
- "code.osinet.fr/fgm/kurz/domain"
- "code.osinet.fr/fgm/kurz/infrastructure"
- "code.osinet.fr/fgm/kurz/web/api"
- "github.com/gorilla/mux"
- "github.com/spf13/cobra"
- )
- var cmdServe = &cobra.Command{
- Args: cobra.NoArgs,
- Long: "Start HTTP Server",
- Run: serveHandler,
- Short: "Top-level command for HTTP Serving.",
- Use: "serve",
- }
- // db is the database connection shared by "serve *" commands.
- var db *sql.DB
- func init() {
- cmd.AddCommand(cmdServe)
- }
- func ensureInfrastructure(db *sql.DB) *sql.DB {
- if db != nil {
- err := db.Ping()
- if err != nil {
- db = nil
- }
- }
- if db != nil {
- return db
- }
- dbDriver, dbDsn := infrastructure.ParseDbCred()
- db, err := infrastructure.DbDial(dbDriver, dbDsn)
- if err != nil {
- panic(err)
- }
- domain.RegisterRepositories(
- infrastructure.MySQLShortURLRepository{DB: db},
- infrastructure.MySQLTargetURLRepository{DB: db},
- )
- return db
- }
- // serveHandler handles Web paths.
- func serveHandler(_ *cobra.Command, args []string) {
- db = ensureInfrastructure(db)
- defer db.Close()
- cwd, err := os.Getwd()
- if err != nil {
- panic(err)
- }
- log.Printf("Server initializing in %s\n", cwd)
- // Set up globals from configuration, providing a few defaults.
- siteBaseURL := viper.Get("web.siteBaseUrl").(string)
- // This default is the relative position of the assets from the project root during development.
- viper.SetDefault("web.assetsPath", "web/public")
- assetsPath := viper.Get("web.assetsPath").(string)
- webConfig := viper.Get("web").(map[string]interface{})
- ui.SetupGlobals(webConfig)
- // Set up Web API and UI routes.
- router := mux.NewRouter()
- api.SetupRoutes(router)
- ui.SetupUI(router, assetsPath)
- http.Handle("/", router)
- // Start a server that can handle a SIGINT to shutdown.
- stop := make(chan os.Signal, 1)
- signal.Notify(stop, os.Interrupt)
- listenAddress := viper.Get("web.listenAddress").(string)
- server := &http.Server{Addr: listenAddress, Handler: router}
- go func() {
- log.Printf("Listening on %s, exposed as %s", listenAddress, siteBaseURL)
- err := server.ListenAndServe()
- log.Fatal(err)
- }()
- <-stop
- // Shutdown cleanly.
- log.Println("Shutting down server")
- ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
- server.Shutdown(ctx)
- log.Println("Server gracefully stopped")
- }
|