/
provider.go
176 lines (155 loc) · 4.12 KB
/
provider.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
package otes
import (
"fmt"
"net/http"
"github.com/DoNewsCode/core/config"
"github.com/DoNewsCode/core/contract"
"github.com/DoNewsCode/core/di"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/olivere/elastic/v7"
"github.com/opentracing/opentracing-go"
"go.uber.org/dig"
)
/*
Providers returns a set of dependency providers. It includes the Maker, the
default *elastic.Client and exported configs.
Depends On:
log.Logger
contract.ConfigAccessor
EsConfigInterceptor `optional:"true"`
opentracing.Tracer `optional:"true"`
Provides:
Factory
Maker
*elastic.Client
*/
func Providers() di.Deps {
return []interface{}{provideEsFactory, provideDefaultClient, provideConfig}
}
// EsConfigInterceptor is an injector type hint that allows user to do
// last minute modification to es configurations.
type EsConfigInterceptor func(name string, opt *Config)
// Maker models Factory
type Maker interface {
Make(name string) (*elastic.Client, error)
}
// Factory is a *di.Factory that creates *elastic.Client using a specific
// configuration entry.
type Factory struct {
*di.Factory
}
// Make creates *elastic.Client using a specific configuration entry.
func (r Factory) Make(name string) (*elastic.Client, error) {
client, err := r.Factory.Make(name)
if err != nil {
return nil, err
}
return client.(*elastic.Client), nil
}
// in is the injection parameter for Provide.
type in struct {
dig.In
Logger log.Logger
Conf contract.ConfigAccessor
Interceptor EsConfigInterceptor `optional:"true"`
Tracer opentracing.Tracer `optional:"true"`
Options []elastic.ClientOptionFunc `optional:"true"`
}
// out is the result of Provide.
type out struct {
dig.Out
Factory Factory
Maker Maker
ExportedConfig []config.ExportedConfig `group:"config,flatten"`
}
// Provide creates Factory and *elastic.Client. It is a valid dependency for
// package core.
func provideEsFactory(p in) (out, func()) {
var err error
var esConfigs map[string]Config
err = p.Conf.Unmarshal("es", &esConfigs)
if err != nil {
level.Warn(p.Logger).Log("err", err)
}
factory := di.NewFactory(func(name string) (di.Pair, error) {
var (
ok bool
conf Config
options []elastic.ClientOptionFunc
)
if conf, ok = esConfigs[name]; !ok {
if name != "default" {
return di.Pair{}, fmt.Errorf("elastic configuration %s not valid", name)
}
conf.URL = []string{"http://localhost:9200"}
}
if p.Interceptor != nil {
p.Interceptor(name, &conf)
}
if p.Tracer != nil {
options = append(options,
elastic.SetHttpClient(
&http.Client{
Transport: NewTransport(WithTracer(p.Tracer)),
},
),
)
}
if conf.Healthcheck != nil {
options = append(options, elastic.SetHealthcheck(*conf.Healthcheck))
}
if conf.Sniff != nil {
options = append(options, elastic.SetSniff(*conf.Sniff))
}
logger := log.With(p.Logger, "tag", "es")
options = append(options,
elastic.SetURL(conf.URL...),
elastic.SetBasicAuth(conf.Username, conf.Password),
elastic.SetInfoLog(ElasticLogAdapter{level.Info(logger)}),
elastic.SetErrorLog(ElasticLogAdapter{level.Error(logger)}),
elastic.SetTraceLog(ElasticLogAdapter{level.Debug(logger)}),
)
options = append(options, p.Options...)
client, err := elastic.NewClient(options...)
if err != nil {
return di.Pair{}, err
}
return di.Pair{
Conn: client,
Closer: func() {
client.Stop()
},
}, nil
})
f := Factory{factory}
return out{
Factory: f,
Maker: f,
}, factory.Close
}
func provideDefaultClient(maker Maker) (*elastic.Client, error) {
return maker.Make("default")
}
type configOut struct {
di.Out
Config []config.ExportedConfig `group:"config,flatten"`
}
// provideConfig exports the default es configuration.
func provideConfig() configOut {
configs := []config.ExportedConfig{
{
Owner: "otes",
Data: map[string]interface{}{
"es": map[string]Config{
"default": {
URL: []string{"http://localhost:9200"},
Shards: 1,
},
},
},
Comment: "The configuration of elastic search clients",
},
}
return configOut{Config: configs}
}