package main import ( "fmt" "os" "time" "os/signal" "log" "net/http" "context" "github.com/getkin/kin-openapi/openapi3" "github.com/deepmap/oapi-codegen/pkg/middleware" "github.com/labstack/echo/v4" echomiddleware "github.com/labstack/echo/v4/middleware" "sku61.com/InvestAccnt/api" "sku61.com/InvestAccnt/api/gen" "sku61.com/InvestAccnt/api/errorh" ) func Run(e *echo.Echo, addressPort string, timeOut time.Duration, msgLevel int) { var runChan = make(chan os.Signal, 1) // Set up a context to allow for graceful server shutdowns in the event // of an OS interrupt (defers the cancel just in case) ctx, cancel := context.WithTimeout( context.Background(), timeOut, ) defer cancel() // Handle ctrl+c/ctrl+x interrupt signal.Notify(runChan, os.Interrupt) if (msgLevel > 0) { log.Printf("Server is starting on %s\n", addressPort) } go func() { if err := e.Start(addressPort); err != nil { if err == http.ErrServerClosed { // Normal interrupt operation, ignore } else { log.Fatalf("Server failed to start due to err: %v", err) } } }() interrupt := <-runChan if (msgLevel > 0) { log.Printf("Server is shutting down due to %+v\n", interrupt) } if err := e.Server.Shutdown(ctx); err != nil { if ("interrupt" != fmt.Sprintf("%v", interrupt)) { log.Printf("Server was unable to gracefully shutdown due to err: '%+v'", err) } } } func main() { configPath := "../config/InvestAccnt.yaml" softwareConfig, err := api.ParseFlags(configPath) if err != nil { fmt.Fprintf(os.Stderr, "Error loading configuration,flags\n") fmt.Fprintf(os.Stderr, "Error detail: %v\n", err) os.Exit(1) } if (softwareConfig.Support.Level > 2) { log.Printf("Message verbosity level: %d", softwareConfig.Support.Level) } swagger, err := gen.GetSwagger() if err != nil { fmt.Fprintf(os.Stderr, "Error loading Open API spec\n: %s", err) os.Exit(1) } // Create an instance of our handler which satisfies the generated interface var microService, _ = api.NewMicroService(*softwareConfig) // Adjust servers to fit configuration swagger.Servers = nil server := openapi3.Server{ URL: microService.Configuration.Server.BasePath, } swagger.AddServer(&server) e := echo.New() // Log all requests e.Use(echomiddleware.Logger()) // Custom error handling e.HTTPErrorHandler = errorh.NewHttpErrorHandler().Handler var options middleware.Options if (!microService.IsProductionEnvironment()) { options.Skipper = func(c echo.Context) bool { return microService.BrowseSkipper(c.Request().URL.Path) } } options.Options.AuthenticationFunc = microService.Authn.AuthnFunc // Use our validation middleware to check all requests against the // OpenAPI schema. e.Use(middleware.OapiRequestValidatorWithOptions(swagger, &options)) e.Use(echomiddleware.GzipWithConfig(echomiddleware.GzipConfig{ Level: 3, })) microService.RegisterHandlers(e) if (microService.Configuration.Support.Level < 1) { e.HideBanner = true } e.Server.ReadTimeout = microService.Configuration.Server.Timeout.Read * time.Second e.Server.WriteTimeout = microService.Configuration.Server.Timeout.Write * time.Second e.Server.IdleTimeout = microService.Configuration.Server.Timeout.Idle * time.Second addressPort := fmt.Sprintf("%s:%d", microService.Configuration.Server.Host, microService.Configuration.Server.Port) timeOut := microService.Configuration.Server.Timeout.Server * time.Second // And we serve HTTP until the world ends. Run(e, addressPort, timeOut, microService.Configuration.Support.Level) }