Test Setup Failed
Push — main ( 0c166d...77ea26 )
by Acho
02:38
created

client.go   A

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 97
dl 0
loc 158
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A mtnmomo.*Client.do 0 19 5
A mtnmomo.*Client.addDisbursementAccessToken 0 2 1
A mtnmomo.*Client.addBasicAuth 0 2 1
A mtnmomo.*Client.newResponse 0 11 2
A mtnmomo.*Client.addCallbackURL 0 2 1
A mtnmomo.*Client.addTargetEnvironment 0 2 1
A mtnmomo.*Client.addReferenceID 0 2 1
A mtnmomo.*Client.addCollectionAccessToken 0 2 1
A mtnmomo.*Client.newRequest 0 22 4
A mtnmomo.New 0 23 2
1
package mtnmomo
2
3
import (
4
	"bytes"
5
	"context"
6
	"encoding/json"
7
	"io"
8
	"io/ioutil"
9
	"net/http"
10
	"sync"
11
)
12
13
const (
14
	headerKeySubscriptionKey   = "Ocp-Apim-Subscription-Key"
15
	headerKeyTargetEnvironment = "X-Target-Environment"
16
	headerKeyReferenceID       = "X-Reference-Id"
17
	headerKeyCallbackURL       = "X-Callback-Url"
18
)
19
20
type service struct {
21
	client *Client
22
}
23
24
// Client is the campay API client.
25
// Do not instantiate this client with Client{}. Use the New method instead.
26
type Client struct {
27
	httpClient          *http.Client
28
	common              service
29
	baseURL             string
30
	subscriptionKey     string
31
	collectionAccount   *apiAccount
32
	disbursementAccount *apiAccount
33
	targetEnvironment   string
34
35
	collectionLock                 sync.Mutex
36
	collectionAccessToken          string
37
	collectionAccessTokenExpiresAt int64
38
39
	disbursementLock                 sync.Mutex
40
	disbursementAccessToken          string
41
	disbursementAccessTokenExpiresAt int64
42
43
	APIUser      *apiUserService
44
	Collection   *collectionService
45
	Disbursement *disbursementsService
46
}
47
48
// New creates and returns a new campay.Client from a slice of campay.ClientOption.
49
func New(options ...Option) *Client {
50
	config := defaultClientConfig()
51
52
	for _, option := range options {
53
		option.apply(config)
54
	}
55
56
	client := &Client{
57
		httpClient:          config.httpClient,
58
		subscriptionKey:     config.subscriptionKey,
59
		baseURL:             config.baseURL,
60
		collectionAccount:   config.collectionAccount,
61
		disbursementAccount: config.disbursementAccount,
62
		targetEnvironment:   config.targetEnvironment,
63
		collectionLock:      sync.Mutex{},
64
	}
65
66
	client.common.client = client
67
	client.APIUser = (*apiUserService)(&client.common)
68
	client.Collection = (*collectionService)(&client.common)
69
	client.Disbursement = (*disbursementsService)(&client.common)
70
71
	return client
72
}
73
74
// newRequest creates an API request. A relative URL can be provided in uri,
75
// in which case it is resolved relative to the BaseURL of the Client.
76
// URI's should always be specified without a preceding slash.
77
func (client *Client) newRequest(ctx context.Context, method, uri string, body interface{}) (*http.Request, error) {
78
	var buf io.ReadWriter
79
	if body != nil {
80
		buf = &bytes.Buffer{}
81
		enc := json.NewEncoder(buf)
82
		enc.SetEscapeHTML(false)
83
		err := enc.Encode(body)
84
		if err != nil {
85
			return nil, err
86
		}
87
	}
88
89
	req, err := http.NewRequestWithContext(ctx, method, client.baseURL+uri, buf)
90
	if err != nil {
91
		return nil, err
92
	}
93
94
	req.Header.Set("Content-Type", "application/json")
95
	req.Header.Set("Accept", "application/json")
96
	req.Header.Set(headerKeySubscriptionKey, client.subscriptionKey)
97
98
	return req, nil
99
}
100
101
func (client *Client) addCollectionAccessToken(request *http.Request) {
102
	request.Header.Add("Authorization", "Bearer "+client.collectionAccessToken)
103
}
104
105
func (client *Client) addDisbursementAccessToken(request *http.Request) {
106
	request.Header.Add("Authorization", "Bearer "+client.disbursementAccessToken)
107
}
108
109
func (client *Client) addBasicAuth(account *apiAccount, request *http.Request) {
110
	request.SetBasicAuth(account.apiUser, account.apiKey)
111
}
112
113
func (client *Client) addReferenceID(request *http.Request, reference string) {
114
	request.Header.Set(headerKeyReferenceID, reference)
115
}
116
117
func (client *Client) addCallbackURL(request *http.Request, url string) {
118
	request.Header.Set(headerKeyCallbackURL, url)
119
}
120
121
func (client *Client) addTargetEnvironment(request *http.Request) {
122
	request.Header.Set(headerKeyTargetEnvironment, client.targetEnvironment)
123
}
124
125
// do carries out an HTTP request and returns a Response
126
func (client *Client) do(req *http.Request) (*Response, error) {
127
	httpResponse, err := client.httpClient.Do(req)
128
	if err != nil {
129
		return nil, err
130
	}
131
132
	defer func() { _ = httpResponse.Body.Close() }()
133
134
	resp, err := client.newResponse(httpResponse)
135
	if err != nil {
136
		return resp, err
137
	}
138
139
	_, err = io.Copy(ioutil.Discard, httpResponse.Body)
140
	if err != nil {
141
		return resp, err
142
	}
143
144
	return resp, nil
145
}
146
147
// newResponse converts an *http.Response to *Response
148
func (client *Client) newResponse(httpResponse *http.Response) (*Response, error) {
149
	response := new(Response)
150
	response.HTTPResponse = httpResponse
151
152
	buf, err := ioutil.ReadAll(response.HTTPResponse.Body)
153
	if err != nil {
154
		return nil, err
155
	}
156
	response.Body = &buf
157
158
	return response, response.Error()
159
}
160