-
Notifications
You must be signed in to change notification settings - Fork 0
/
Server.go
163 lines (131 loc) · 4.01 KB
/
Server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package server
import (
"fmt"
"os"
"os/signal"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/projectkeas/sdks-service/configuration"
"github.com/projectkeas/sdks-service/healthchecks"
log "github.com/projectkeas/sdks-service/logger"
)
type FiberAppFunc func(app *fiber.App, server *Server)
type Server struct {
AppName string
handlerConfig FiberAppFunc
services map[string]*interface{}
}
func newServer(appName string, handlerConfig FiberAppFunc) Server {
server := Server{
AppName: appName,
handlerConfig: handlerConfig,
services: map[string]*interface{}{},
}
return server
}
func (server *Server) GetConfiguration() *configuration.ConfigurationRoot {
svc, _ := server.GetService(configuration.SERVICE_NAME)
temp := (*svc).(*configuration.ConfigurationRoot)
return temp
}
func (server *Server) GetHealthCheckRunner() *healthchecks.HealthCheckRunner {
svc, _ := server.GetService(healthchecks.SERVICE_NAME)
temp := (*svc).(healthchecks.HealthCheckRunner)
return &temp
}
func (server *Server) RegisterService(name string, service interface{}) {
_, castSuccessful := (service).(Disposable)
if castSuccessful {
log.Logger.Info(fmt.Sprintf("Registering service: %s", name))
}
server.services[name] = &service
}
func (server *Server) GetService(name string) (*interface{}, error) {
service, found := server.services[name]
if found {
return service, nil
}
return nil, fmt.Errorf("unable to locate service '%s'", name)
}
func (server *Server) Run() {
runServer(server, false)
}
func (server *Server) RunDevelopment() {
runServer(server, true)
}
func runServer(server *Server, development bool) {
app := fiber.New(fiber.Config{
AppName: server.AppName,
DisableDefaultDate: true,
DisableStartupMessage: !development,
EnablePrintRoutes: development,
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
// Status code defaults to 500
code := fiber.StatusInternalServerError
// Retrieve the custom status code if it's an fiber.*Error
if e, ok := err.(*fiber.Error); ok {
code = e.Code
}
// Send custom error json
errorResult := map[string]interface{}{
"message": "An error occurred whilst processing your request. Please check the logs for more information.",
}
if development {
errorResult["error"] = err.Error()
}
ctx.Status(code).JSON(errorResult)
return nil
},
})
// Logging must be the first middleware or we miss 500 status codes
app.Use(NewHttpLoggingMiddleware(&LoggingConfig{}))
app.Use(recover.New())
app.Use(compress.New(compress.Config{
Level: compress.LevelBestSpeed,
}))
app.Get("/_system/health/:type?", func(context *fiber.Ctx) error {
var result healthchecks.HealthCheckAggregatedResult
switch context.Params("type") {
case "ready":
result = server.GetHealthCheckRunner().RunReadinessChecks()
default:
result = server.GetHealthCheckRunner().RunLivenessChecks()
}
context.JSON(result)
if result.State.Is(healthchecks.HealthCheckState_Healthy) {
context.SendStatus(200)
} else {
context.SendStatus(503)
}
return nil
})
if server.handlerConfig != nil {
server.handlerConfig(app, server)
}
// Handle graceful shutdown by proxying with a channel
shutdownChannel := make(chan os.Signal, 1)
signal.Notify(shutdownChannel, os.Interrupt)
// Use a GoRoutine to monitor the channel and call app.Shutdown
go func() {
<-shutdownChannel
log.Logger.Info("Application stopping...")
err := app.Shutdown()
if err != nil {
log.Logger.Panic(err.Error())
}
}()
log.Logger.Info("Application starting...")
err := app.Listen(":" + server.GetConfiguration().GetStringValueOrDefault("server.port", "5000"))
if err != nil {
log.Logger.Panic(err.Error())
}
for key, svc := range server.services {
disposable, castSuccessful := (*svc).(Disposable)
if castSuccessful {
log.Logger.Info(fmt.Sprintf("Deregistering service: %s", key))
disposable.Dispose()
}
}
log.Logger.Sync()
}