-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.go
238 lines (197 loc) · 6.88 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
package pbg
import (
"fmt"
"log"
"github.com/buaazp/fasthttprouter"
"github.com/valyala/fasthttp"
"os"
)
type (
// Rappresenta un server HTTP del framework pbg
// Include tutti i metodi per registrare RequestHandlers e
// creare un REST API
//
// GET -> Leggi risorse
// PUT -> Aggiorna risorse
// POST -> Crea risorse
// DELETE -> Cancella risorse
ServerHTTP interface {
GET(path string, handle fasthttp.RequestHandler)
PUT(path string, handle fasthttp.RequestHandler)
POST(path string, handle fasthttp.RequestHandler)
DELETE(path string, handle fasthttp.RequestHandler)
API_GET(path string, handle fasthttp.RequestHandler)
API_PUT(path string, handle fasthttp.RequestHandler)
API_POST(path string, handle fasthttp.RequestHandler)
API_DELETE(path string, handle fasthttp.RequestHandler)
}
// Rappresenta tutti gli Adapter messi a disposizione dal Server
// Forniscono accesso a particolari entità protette del software mediante
// RequestCtx
//
// Per richiederli, usare nei RequestHandler:
//
// func(ctx *fasthttp.RequestCtx) {
// // Type assertion qui, ctx.UserValue() restituisce interface{}
// ent, ok := ctx.UserValue(ENTITY_KEY).(Entity)
// if !ok {
// // Errore!
// ...
// }
//
// // Usa il valore ent
// ...
// }
//
ServerAdapters interface {
// Fornisce interfaccia al DB delle mosse mediante RequestCtx
// L'interfaccia è disponibile con la chiave pbg.MoveDBInterfaceKey
WithMoveDBAccess(fasthttp.RequestHandler) fasthttp.RequestHandler
// Fornisce interfaccia al DB dei Pokèmon mediante RequestCtx
// L'interfaccia è disponibile con la chiave pbg.PokèmonDBInterfaceKey
WithPokèmonDBAccess(fasthttp.RequestHandler) fasthttp.RequestHandler
// Fornisce interfaccia al DB degli allenatori mediante RequestCtx
// L'interfaccia è disponibile con la chiave pbg.TrainerDBInterfaceKey
WithTrainerDBAccess(fasthttp.RequestHandler) fasthttp.RequestHandler
// Fornisce un SessionInterface mediante RequestCtx
// L'interfaccia è disponibile con la chiave pbg.SessionDBInterfaceKey
WithSessionDBAccess(fasthttp.RequestHandler) fasthttp.RequestHandler
}
// Un Server del framework pbg ha la possibilità di utilizzare un Logger,
// le capacità di usare il protocollo HTTP (quindi registrare RequestHandlers)
// e degli Adapter per estendere a dovere i RequestHandler utente con l'accesso a risorse protette
Server interface {
fasthttp.Logger
ServerHTTP
ServerAdapters
// Avvia il server
Start()
}
server struct {
*fasthttp.Server
port int
router *fasthttprouter.Router
logger *log.Logger
apiEndpoint string // Endpoint dell'API server
apiResponser APIResponser // Traduttore per le richieste API
pokèmonDB PokèmonDBComponent // Riferimento al componente software del Models DB
moveDB MoveDBComponent //
trainerDB TrainerDBComponent //
sessionDB SessionComponent // Riferimento al componente software del Sessions DB
}
)
var (
defaultLogger = log.New(os.Stderr, "PBG Server: ", log.LstdFlags|log.Lshortfile)
checkValueWithLogger = func(logger *log.Logger, value interface{}, err error) {
if logger != nil && value == nil {
logger.Fatal(err)
}
}
checkErrorWithLogger = func(logger *log.Logger, err error) {
if logger != nil && err != nil {
logger.Fatal(err)
}
}
checkValue = func(value interface{}, err error) { checkValueWithLogger(defaultLogger, value, err) }
checkError = func(err error) { checkErrorWithLogger(defaultLogger, err) }
)
// Factory methods per oggetti pbg.Server
// Usare i Server functional options per utilizzare determinate proprietà
// sull'oggetto costruito
func NewServer(options ...ServerOption) Server {
srv := &server{
port: 80,
router: fasthttprouter.New(),
apiResponser: NewJSONResponser(),
apiEndpoint: "/api",
}
for _, option := range options {
checkError(option(srv))
}
if srv.logger == nil {
srv.logger = defaultLogger
}
// Check needed parameters
checkValue(srv.apiResponser, ErrInvalidAPIResponser)
checkValue(srv.moveDB, ErrInvalidMoveDBComponent)
checkValue(srv.pokèmonDB, ErrInvalidPokèmonDBComponent)
checkValue(srv.sessionDB, ErrInvalidSessionComponent)
// If server is not set up, use a standard server
if srv.Server == nil {
srv.Server = &fasthttp.Server{
Logger: srv.logger,
}
}
// Server handler from fasthttprouter
srv.Server.Handler = srv.router.Handler
return srv
}
func (srv *server) GET(path string, handle fasthttp.RequestHandler) {
srv.router.GET(path, handle)
}
func (srv *server) PUT(path string, handle fasthttp.RequestHandler) {
srv.router.PUT(path, handle)
}
func (srv *server) POST(path string, handle fasthttp.RequestHandler) {
srv.router.POST(path, handle)
}
func (srv *server) DELETE(path string, handle fasthttp.RequestHandler) {
srv.router.DELETE(path, handle)
}
func (srv *server) API_GET(path string, handle fasthttp.RequestHandler) {
srv.router.GET(srv.apiEndpoint+path, Adapt(handle, srv.apiWriter))
}
func (srv *server) API_PUT(path string, handle fasthttp.RequestHandler) {
srv.router.PUT(srv.apiEndpoint+path, Adapt(handle, srv.apiWriter))
}
func (srv *server) API_POST(path string, handle fasthttp.RequestHandler) {
srv.router.POST(srv.apiEndpoint+path, Adapt(handle, srv.apiWriter))
}
func (srv *server) API_DELETE(path string, handle fasthttp.RequestHandler) {
srv.router.DELETE(srv.apiEndpoint+path, Adapt(handle, srv.apiWriter))
}
func (srv *server) Start() {
address := fmt.Sprintf(":%d", srv.port)
srv.logger.Fatal(
srv.ListenAndServe(address),
)
}
func (srv *server) Printf(format string, v ...interface{}) {
srv.logger.Printf(format, v...)
}
/**************
Server
Adapters
**************/
func (srv *server) WithMoveDBAccess(handler fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
dataInterface := srv.moveDB.Supply()
defer srv.moveDB.Retrieve(dataInterface)
ctx.SetUserValue(MoveDBInterfaceKey, dataInterface)
handler(ctx)
}
}
func (srv *server) WithPokèmonDBAccess(handler fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
dataInterface := srv.pokèmonDB.Supply()
defer srv.pokèmonDB.Retrieve(dataInterface)
ctx.SetUserValue(PokèmonDBInterfaceKey, dataInterface)
handler(ctx)
}
}
func (srv *server) WithTrainerDBAccess(handler fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
dataInterface := srv.trainerDB.Supply()
defer srv.trainerDB.Retrieve(dataInterface)
ctx.SetUserValue(TrainerDBInterfaceKey, dataInterface)
handler(ctx)
}
}
func (srv *server) WithSessionDBAccess(handler fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
sessionInterface := srv.sessionDB.Supply()
defer srv.sessionDB.Retrieve(sessionInterface)
ctx.SetUserValue(SessionDBInterfaceKey, sessionInterface)
handler(ctx)
}
}