-
Notifications
You must be signed in to change notification settings - Fork 3
/
censuses.go
173 lines (167 loc) · 6.12 KB
/
censuses.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
package apiclient
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"github.com/vocdoni/census3/api"
"go.vocdoni.io/dvote/log"
)
// Census method returns a census by its ID from the API, it receives the
// censusID and returns a pointer to a GetCensusResponse and an error if something
// went wrong.
func (c *HTTPclient) Census(censusID uint64) (*api.Census, error) {
if censusID == 0 {
return nil, fmt.Errorf("%w: censusID is required", ErrBadInputs)
}
// construct the URL to the API with the censusID
endpoint := fmt.Sprintf(GetCensusURI, censusID)
u, err := c.constructURL(endpoint)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrConstructingURL, err)
}
// create the request and send it, if there is an error or the status code
// is not 200, return an error
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrCreatingRequest, err)
}
res, err := c.c.Do(req)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrMakingRequest, err)
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Errorf("error closing response body: %v", err)
}
}()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%w: %w", ErrNoStatusOk, fmt.Errorf("%d %s", res.StatusCode, http.StatusText(res.StatusCode)))
}
// decode the response and return it
response := api.Census{}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("%w: %w", ErrDecodingResponse, err)
}
return &response, nil
}
// CreateCensus method creates a new census from the API, it receives a
// CreateCensusRequest and returns a queueID and an error if something went wrong.
// The queueID is used to check the status of the census creation process, it
// can be checked with the CreateCensusQueue method.
func (c *HTTPclient) CreateCensus(request *api.Census) (string, error) {
if request == nil || request.StrategyID == 0 {
return "", fmt.Errorf("%w: strategyID is required", ErrBadInputs)
}
// construct the URL to the API
url, err := c.constructURL(CreateCensusURI)
if err != nil {
return "", fmt.Errorf("%w: %w", ErrConstructingURL, err)
}
// encode the input token to JSON to be sent in the request body
requestBody, err := json.Marshal(request)
if err != nil {
return "", fmt.Errorf("%w: %w", ErrEncodingRequest, err)
}
// create the request and send it with the encoded body, if there is an
// error or the status code is not 200, return an error
req, err := http.NewRequest(HTTPPOST, url, bytes.NewBuffer(requestBody))
if err != nil {
return "", fmt.Errorf("%w: %w", ErrCreatingRequest, err)
}
req.Header.Set("Content-Type", "application/json")
res, err := c.c.Do(req)
if err != nil {
return "", fmt.Errorf("%w: %w", ErrMakingRequest, err)
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Errorf("error closing response body: %v", err)
}
}()
if res.StatusCode != http.StatusOK {
return "", fmt.Errorf("%w: %w", ErrNoStatusOk, fmt.Errorf("%d %s", res.StatusCode, http.StatusText(res.StatusCode)))
}
// decode the response and return the queueID
queueResponse := &api.QueueResponse{}
if err := json.NewDecoder(res.Body).Decode(queueResponse); err != nil {
return "", fmt.Errorf("%w: %w", ErrDecodingResponse, err)
}
return queueResponse.QueueID, nil
}
// CreateCensusQueue method checks the status of a census creation process from
// the API, it receives a queueID and returns a pointer to a CensusQueueResponse
// and an error if something went wrong.
func (c *HTTPclient) CreateCensusQueue(queueID string) (*api.CensusQueue, error) {
if queueID == "" {
return nil, fmt.Errorf("%w: queueID is required", ErrBadInputs)
}
// construct the URL to the API with the queueID
endpoint := fmt.Sprintf(CreateCensusQueueURI, queueID)
u, err := c.constructURL(endpoint)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrConstructingURL, err)
}
// create the request and send it, if there is an error or the status code
// is not 200, return an error
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrCreatingRequest, err)
}
res, err := c.c.Do(req)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrMakingRequest, err)
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Errorf("error closing response body: %v", err)
}
}()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%w: %w", ErrNoStatusOk, fmt.Errorf("%d %s", res.StatusCode, http.StatusText(res.StatusCode)))
}
// decode the response and return it
response := &api.CensusQueue{}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("%w: %w", ErrDecodingResponse, err)
}
return response, nil
}
// CensusesByStrategy method returns the censuses of a strategy from the API,
// it receives the strategyID and returns a slice of GetCensusResponse pointers
// and an error if something went wrong.
func (c *HTTPclient) CensusesByStrategy(strategyID uint64) ([]*api.Census, error) {
if strategyID == 0 {
return nil, fmt.Errorf("%w: strategyID is required", ErrBadInputs)
}
// construct the URL to the API with the strategyID
endpoint := fmt.Sprintf(GetCensusesByStrategyURI, strategyID)
u, err := c.constructURL(endpoint)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrConstructingURL, err)
}
// create the request and send it, if there is an error or the status code
// is not 200, return an error
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrCreatingRequest, err)
}
res, err := c.c.Do(req)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrMakingRequest, err)
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Errorf("error closing response body: %v", err)
}
}()
if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%w: %w", ErrNoStatusOk, fmt.Errorf("%d %s", res.StatusCode, http.StatusText(res.StatusCode)))
}
// decode the response and return the censuses
response := &api.Censuses{}
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("%w: %w", ErrDecodingResponse, err)
}
return response.Censuses, nil
}