package main import ( "code.osinet.fr/fgm/kurz/web" "context" "database/sql" "github.com/davecgh/go-spew/spew" "github.com/spf13/viper" "log" "net/http" "os" "os/signal" "time" "code.osinet.fr/fgm/kurz/api" "code.osinet.fr/fgm/kurz/domain" "code.osinet.fr/fgm/kurz/infrastructure" "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() // This default is the relative position of the assets from the kurzd binary during development. viper.SetDefault("web.assetsPath", "../../web/public") assetsPath := viper.Get("web.assetsPath").(string) router := mux.NewRouter() api.SetupRoutes(router) spew.Dump(viper.Get("web")) web.SetupRoutes(router, assetsPath) http.Handle("/", router) address := viper.Get("web.address").(string) // Start a server that can handle a SIGINT to shutdown. stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) server := &http.Server{Addr: address, Handler: router} go func() { log.Printf("Listening on %s", address) err := server.ListenAndServe() log.Fatal(err) }() <-stop log.Println("Shutting down server") ctx, _ := context.WithTimeout(context.Background(), 1*time.Second) server.Shutdown(ctx) log.Println("Server gracefully stopped") }