134 lines
3.6 KiB
Go
134 lines
3.6 KiB
Go
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)
|
|
}
|
|
|