-
Notifications
You must be signed in to change notification settings - Fork 3
/
client.go
116 lines (93 loc) · 2.78 KB
/
client.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
package http
import (
"net/http"
"github.com/alexfalkowski/go-service/transport/http/breaker"
lzap "github.com/alexfalkowski/go-service/transport/http/logger/zap"
"github.com/alexfalkowski/go-service/transport/http/meta"
"github.com/alexfalkowski/go-service/transport/http/metrics/prometheus"
"github.com/alexfalkowski/go-service/transport/http/retry"
"github.com/alexfalkowski/go-service/transport/http/trace/opentracing"
otr "github.com/opentracing/opentracing-go"
"go.uber.org/zap"
)
// ClientOption for HTTP.
type ClientOption interface{ apply(*clientOptions) }
type clientOptions struct {
logger *zap.Logger
tracer opentracing.Tracer
metrics *prometheus.ClientMetrics
retry bool
breaker bool
roundTripper http.RoundTripper
}
type clientOptionFunc func(*clientOptions)
func (f clientOptionFunc) apply(o *clientOptions) { f(o) }
// WithClientRoundTripper for HTTP.
func WithClientRoundTripper(rt http.RoundTripper) ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.roundTripper = rt
})
}
// WithClientRetry for HTTP.
func WithClientRetry() ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.retry = true
})
}
// WithClientBreaker for HTTP.
func WithClientBreaker() ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.breaker = true
})
}
// WithClientLogger for HTTP.
func WithClientLogger(logger *zap.Logger) ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.logger = logger
})
}
// WithClientTracer for HTTP.
func WithClientTracer(tracer opentracing.Tracer) ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.tracer = tracer
})
}
// WithClientMetrics for HTTP.
func WithClientMetrics(metrics *prometheus.ClientMetrics) ClientOption {
return clientOptionFunc(func(o *clientOptions) {
o.metrics = metrics
})
}
// ClientParams for HTTP.
type ClientParams struct {
Config *Config
}
// NewClient for HTTP.
func NewClient(params ClientParams, opts ...ClientOption) *http.Client {
defaultOptions := &clientOptions{tracer: otr.NoopTracer{}}
for _, o := range opts {
o.apply(defaultOptions)
}
return &http.Client{Transport: newRoundTripper(params, defaultOptions)}
}
func newRoundTripper(params ClientParams, opts *clientOptions) http.RoundTripper {
hrt := opts.roundTripper
if hrt == nil {
hrt = http.DefaultTransport
}
if opts.logger != nil {
hrt = lzap.NewRoundTripper(lzap.RoundTripperParams{Logger: opts.logger, RoundTripper: hrt})
}
if opts.metrics != nil {
hrt = opts.metrics.RoundTripper(hrt)
}
hrt = opentracing.NewRoundTripper(opts.tracer, hrt)
if opts.retry {
hrt = retry.NewRoundTripper(¶ms.Config.Retry, hrt)
}
if opts.breaker {
hrt = breaker.NewRoundTripper(hrt)
}
hrt = meta.NewRoundTripper(params.Config.UserAgent, hrt)
return hrt
}