-
Notifications
You must be signed in to change notification settings - Fork 3
/
handler.go
124 lines (109 loc) · 3.96 KB
/
handler.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
/*
Copyright 2021 Adevinta
*/
package transport
import (
"net/http"
kitendpoint "github.com/go-kit/kit/endpoint"
kithttp "github.com/go-kit/kit/transport/http"
kitlog "github.com/go-kit/log"
"github.com/goadesign/goa/uuid"
"github.com/adevinta/vulcan-scan-engine/pkg/api/endpoint"
"context"
)
// CustomCtxKey represents a custom
// key type for API requests context.
type CustomCtxKey int
const (
// ContextKeyEndpoint is the context key
// for the requested API endpoint.
ContextKeyEndpoint CustomCtxKey = iota
)
// Handlers contains all available handlers for this api
type Handlers struct {
Healthcheck http.Handler
CreateScan http.Handler
ListScans http.Handler
GetScan http.Handler
GetScanChecks http.Handler
GetScanStats http.Handler
GetCheck http.Handler
AbortScan http.Handler
}
// MakeHandlers returns initialized handlers
func MakeHandlers(e *endpoint.Endpoints, logger kitlog.Logger) *Handlers {
options := func(endpoint string) []kithttp.ServerOption {
return []kithttp.ServerOption{
kithttp.ServerBefore(
HTTPGenerateXRequestID(),
kithttp.PopulateRequestContext,
HTTPRequestLogger(logger, "/v1/healthcheck"),
HTTPRequestEndpoint(endpoint),
),
kithttp.ServerAfter(
HTTPReturnXRequestID(),
),
kithttp.ServerErrorEncoder(
func(ctx context.Context, err error, w http.ResponseWriter) {
w.Header().Set("X-Request-ID", ctx.Value(kithttp.ContextKeyRequestXRequestID).(string))
kithttp.DefaultErrorEncoder(ctx, err, w)
},
),
}
}
newServer := func(e kitendpoint.Endpoint,
decodeRequestFunc kithttp.DecodeRequestFunc, endpoint string) http.Handler {
return kithttp.NewServer(
e,
decodeRequestFunc,
kithttp.EncodeJSONResponse,
options(endpoint)...,
)
}
return &Handlers{
Healthcheck: newServer(e.Healthcheck, makeDecodeRequestFunc(struct{}{}), "Healthcheck"),
CreateScan: newServer(e.CreateScan, makeDecodeRequestFunc(endpoint.ScanRequest{}), "CreateScan"),
ListScans: newServer(e.ListScans, makeDecodeRequestFunc(endpoint.ScanRequest{}), "ListScans"),
GetScan: newServer(e.GetScan, makeDecodeRequestFunc(endpoint.ScanRequest{}), "GetScan"),
GetScanChecks: newServer(e.GetScanChecks, makeDecodeRequestFunc(endpoint.ScanChecksRequest{}), "GetScanChecks"),
GetScanStats: newServer(e.GetScanStats, makeDecodeRequestFunc(endpoint.ScanRequest{}), "GetScanStats"),
GetCheck: newServer(e.GetCheck, makeDecodeRequestFunc(endpoint.CheckRequest{}), "GetCheck"),
AbortScan: newServer(e.AbortScan, makeDecodeRequestFunc(endpoint.ScanRequest{}), "AbortScan"),
}
}
// HTTPGenerateXRequestID gets or create a request id token.
func HTTPGenerateXRequestID() kithttp.RequestFunc {
return func(ctx context.Context, r *http.Request) context.Context {
if r.Header.Get("X-Request-ID") == "" {
XRequestID := uuid.NewV4()
r.Header.Set("X-Request-ID", XRequestID.String())
}
return ctx
}
}
func HTTPReturnXRequestID() kithttp.ServerResponseFunc {
return func(ctx context.Context, w http.ResponseWriter) context.Context {
w.Header().Set("X-Request-ID", ctx.Value(kithttp.ContextKeyRequestXRequestID).(string))
return ctx
}
}
func HTTPRequestLogger(logger kitlog.Logger, exclude string) kithttp.RequestFunc {
return func(ctx context.Context, r *http.Request) context.Context {
path := ctx.Value(kithttp.ContextKeyRequestPath).(string)
if path != exclude {
_ = logger.Log(
"X-Request-ID", ctx.Value(kithttp.ContextKeyRequestXRequestID).(string),
"transport", ctx.Value(kithttp.ContextKeyRequestPath).(string),
"Method", ctx.Value(kithttp.ContextKeyRequestMethod).(string),
"RequestURI", ctx.Value(kithttp.ContextKeyRequestURI).(string))
}
return ctx
}
}
// HTTPRequestEndpoint includes a new request ctx entry
// indicating which endpoint was requested.
func HTTPRequestEndpoint(endpoint string) kithttp.RequestFunc {
return func(ctx context.Context, r *http.Request) context.Context {
return context.WithValue(ctx, ContextKeyEndpoint, endpoint)
}
}