generated from rizalgowandy/library-template-go
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathserver.go
168 lines (144 loc) · 4.3 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
164
165
166
167
168
package cronx
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/rizalgowandy/cronx/page"
gdkMiddleware "github.com/rizalgowandy/gdk/pkg/httpx/echo/middleware"
)
const (
QueryParamSort = "sort"
)
// SleepDuration defines the duration to sleep the server if the defined address is busy.
const SleepDuration = time.Second * 10
// NewServer creates a new HTTP server.
// - / => current server status.
// - /jobs => current jobs as frontend html.
// - /api/jobs => current jobs as json.
func NewServer(manager *Manager, address string) (*http.Server, error) {
// Create server.
e := echo.New()
e.HideBanner = true
e.HidePort = true
e.Use(middleware.CORS())
e.Use(middleware.Recover())
e.Use(middleware.RemoveTrailingSlash())
e.Use(gdkMiddleware.RequestID())
// Create server controller.
ctrl := &ServerController{Manager: manager}
// Register routes.
e.GET("/", ctrl.HealthCheck)
e.GET("/jobs", ctrl.Jobs)
e.GET("/histories", ctrl.Histories)
e.GET("/api/jobs", ctrl.APIJobs)
e.GET("/api/histories", ctrl.APIHistories)
return &http.Server{
Addr: address,
Handler: e,
ReadHeaderTimeout: 60 * time.Second,
}, nil
}
// NewSideCarServer creates a new sidecar HTTP server.
// HTTP server will be start automatically.
// - / => current server status.
// - /jobs => current jobs as frontend html.
// - /api/jobs => current jobs as json.
func NewSideCarServer(manager *Manager, address string) {
// Create server.
e := echo.New()
e.HideBanner = true
e.HidePort = true
e.Use(middleware.CORS())
e.Use(middleware.Recover())
e.Use(middleware.RemoveTrailingSlash())
e.Use(gdkMiddleware.RequestID())
// Create server controller.
ctrl := &ServerController{Manager: manager}
// Register routes.
e.GET("/", ctrl.HealthCheck)
e.GET("/jobs", ctrl.Jobs)
e.GET("/histories", ctrl.Histories)
e.GET("/api/jobs", ctrl.APIJobs)
e.GET("/api/histories", ctrl.APIHistories)
// Overcome issue with socket-master respawning 2nd app,
// We will keep trying to run the server.
// If the current address is busy,
// sleep then try again until the address has become available.
for {
if err := e.Start(address); err != nil {
time.Sleep(SleepDuration)
}
}
}
// ServerController is http server controller.
type ServerController struct {
// Manager controls all the underlying job.
Manager *Manager
}
// HealthCheck returns server status.
func (c *ServerController) HealthCheck(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, c.Manager.GetInfo())
}
// Jobs return job status as frontend template.
func (c *ServerController) Jobs(ctx echo.Context) error {
index, err := page.GetJobsPageTemplate()
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
return index.Execute(
ctx.Response().Writer,
c.Manager.GetStatusData(ctx.QueryParam(QueryParamSort)),
)
}
// APIJobs returns job status as json.
func (c *ServerController) APIJobs(ctx echo.Context) error {
return ctx.JSON(
http.StatusOK,
c.Manager.GetStatusData(ctx.QueryParam(QueryParamSort)),
)
}
// Histories return job history as frontend template.
func (c *ServerController) Histories(ctx echo.Context) error {
index, err := page.GetHistoryTemplate()
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
var req Request
err = ctx.Bind(&req)
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
req.url = *ctx.Request().URL
data, err := c.Manager.GetHistoryData(ctx.Request().Context(), &req)
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
return index.Execute(ctx.Response().Writer, data)
}
// APIHistories returns run histories as json.
func (c *ServerController) APIHistories(ctx echo.Context) error {
var req Request
err := ctx.Bind(&req)
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
req.url = *ctx.Request().URL
data, err := c.Manager.GetHistoryData(ctx.Request().Context(), &req)
if err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]string{
"error": err.Error(),
})
}
return ctx.JSON(http.StatusOK, data)
}