generated from go-masonry/mortar-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
exchange_client.go
101 lines (89 loc) · 2.68 KB
/
exchange_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
package clients
import (
"context"
"encoding/json"
"fmt"
"github.com/bevgene/go-currency-rate/app/model"
"github.com/go-masonry/mortar/interfaces/cfg"
"github.com/go-masonry/mortar/interfaces/http/client"
"github.com/go-masonry/mortar/interfaces/log"
"go.uber.org/fx"
"io/ioutil"
"net/http"
)
//go:generate mockgen -source=exchange_client.go -destination=mock/exchange_client_mock.go
type (
ExchangeClient interface {
GetRates(context.Context) (*model.ExchangeRatesModel, error)
}
exchangeClientImplDeps struct {
fx.In
Logger log.Logger
Config cfg.Config
Lifecycle fx.Lifecycle
HTTPClientBuilder client.NewHTTPClientBuilder
}
exchangeClientImpl struct {
deps exchangeClientImplDeps
client *http.Client
url string
}
)
const (
exchangeAPIKeyKey = "exchangerate.exchange.apiKey"
exchangeUrlKey = "exchangerate.exchange.url"
exchangeTimeoutKey = "exchangerate.exchange.timeout"
)
func CreateExchangeClient(deps exchangeClientImplDeps) (result ExchangeClient, err error) {
url := deps.Config.Get(exchangeUrlKey).String()
apiKey := deps.Config.Get(exchangeAPIKeyKey).String()
timeout := deps.Config.Get(exchangeTimeoutKey).Duration()
authUrl := fmt.Sprintf("%s?access_key=%s", url, apiKey)
httpClient := deps.HTTPClientBuilder().WithPreconfiguredClient(&http.Client{Timeout: timeout}).Build()
deps.Lifecycle.Append(fx.Hook{
OnStart: func(ctx context.Context) (err error) {
var req *http.Request
if req, err = http.NewRequest("GET", authUrl, nil); err != nil {
return
}
_, err = httpClient.Do(req)
return
},
})
result = &exchangeClientImpl{
deps: deps,
client: httpClient,
url: authUrl,
}
return
}
func (impl *exchangeClientImpl) GetRates(ctx context.Context) (result *model.ExchangeRatesModel, err error) {
var req *http.Request
if req, err = http.NewRequest("GET", impl.url, nil); err != nil {
impl.deps.Logger.WithError(err).Error(ctx, "failed to create a new request")
return
}
var res *http.Response
if res, err = impl.client.Do(req); err != nil {
impl.deps.Logger.WithError(err).Error(ctx, "failed to execute request")
return
}
defer func() {
var closeErr error
if closeErr = res.Body.Close(); closeErr != nil {
impl.deps.Logger.WithError(closeErr).Error(ctx, "failed to close response body")
}
}()
var body []byte
if body, err = ioutil.ReadAll(res.Body); err != nil {
impl.deps.Logger.WithError(err).Error(ctx, "failed to read response body")
return
}
var parsedRates model.ExchangeRatesModel
if err = json.Unmarshal(body, &parsedRates); err != nil {
impl.deps.Logger.WithError(err).Error(ctx, "failed to parse response body")
return
}
result = &parsedRates
return
}