Skip to content

Commit bf26a31

Browse files
authored
Enhancement: HTTP and WS (#27)
1 parent e3b65a7 commit bf26a31

File tree

27 files changed

+818
-199
lines changed

27 files changed

+818
-199
lines changed

.github/workflows/greetings.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ jobs:
99
- uses: actions/first-interaction@v1
1010
with:
1111
repo-token: ${{ secrets.GITHUB_TOKEN }}
12-
pr-message: 'Congrats, you just opened your first pull request on libsv/go-bc! Thank you for contributing!'
12+
pr-message: 'Congrats, you just opened your first pull request on libsv/go-spvchannels! Thank you for contributing!'

.make/go.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ install-go: ## Install the application (Using Native Go)
4242

4343
lint: ## Run the golangci-lint application (install if not found)
4444
@echo "downloading golangci-lint..."
45-
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- v1.42.0
45+
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- v1.44.0
4646
@echo "running golangci-lint..."
4747
@GOGC=20 ./bin/golangci-lint run
4848

channel.go

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,39 @@ import (
66
"encoding/json"
77
"fmt"
88
"net/http"
9+
"net/url"
10+
"path"
911
)
1012

1113
func (c *Client) getChanelBaseEndpoint() string {
12-
return fmt.Sprintf("https://%s/api/%s/account", c.cfg.baseURL, c.cfg.version)
14+
u := url.URL{
15+
Scheme: c.cfg.httpScheme(),
16+
Host: c.cfg.baseURL,
17+
Path: path.Join("/api", c.cfg.version, "/account"),
18+
}
19+
return u.String()
1320
}
1421

15-
func (c *Client) getTokenBaseEndpoint(accountid, channelid string) string {
16-
return fmt.Sprintf("%s/%s/channel/%s/api-token", c.getChanelBaseEndpoint(), accountid, channelid)
22+
func (c *Client) getTokenBaseEndpoint(accountid int64, channelid string) string {
23+
return fmt.Sprintf("%s/%d/channel/%s/api-token", c.getChanelBaseEndpoint(), accountid, channelid)
1724
}
1825

1926
// ChannelsRequest hold data for get channels request for a particular account
2027
type ChannelsRequest struct {
21-
AccountID string `json:"accountid"`
28+
AccountID int64 `json:"accountid"`
2229
}
2330

2431
// ChannelsReply hold data for get channels reply. It is a list of channel's detail
2532
type ChannelsReply struct {
2633
Channels []struct {
27-
ID string `json:"id"`
28-
Href string `json:"href"`
29-
PublicRead bool `json:"public_read"`
30-
PublicWrite bool `json:"public_write"`
31-
Sequenced bool `json:"sequenced"`
32-
Locked bool `json:"locked"`
33-
Head int `json:"head"`
34-
Retention struct {
35-
MinAgeDays int `json:"min_age_days"`
36-
MaxAgeDays int `json:"max_age_days"`
37-
AutoPrune bool `json:"auto_prune"`
38-
} `json:"retention"`
34+
ID string `json:"id"`
35+
Href string `json:"href"`
36+
PublicRead bool `json:"public_read"`
37+
PublicWrite bool `json:"public_write"`
38+
Sequenced bool `json:"sequenced"`
39+
Locked bool `json:"locked"`
40+
Head int `json:"head"`
41+
Retention Retention `json:"retention"`
3942
AccessTokens []struct {
4043
ID string `json:"id"`
4144
Token string `json:"token"`
@@ -48,7 +51,7 @@ type ChannelsReply struct {
4851

4952
// ChannelRequest hold data for get channel request
5053
type ChannelRequest struct {
51-
AccountID string `json:"accountid"`
54+
AccountID int64 `json:"accountid"`
5255
ChannelID string `json:"channelid"`
5356
}
5457

@@ -80,7 +83,7 @@ type ChannelReply struct {
8083
// And the properties values to be updated. These properties defines
8184
// common permission for the channel
8285
type ChannelUpdateRequest struct {
83-
AccountID string `json:"accountid"`
86+
AccountID int64 `json:"accountid"`
8487
ChannelID string `json:"channelid"`
8588
PublicRead bool `json:"public_read"`
8689
PublicWrite bool `json:"public_write"`
@@ -98,42 +101,41 @@ type ChannelUpdateReply struct {
98101
// ChannelDeleteRequest hold data for delete channel request
99102
// The request contains the account and channel identification
100103
type ChannelDeleteRequest struct {
101-
AccountID string `json:"accountid"`
104+
AccountID int64 `json:"accountid"`
102105
ChannelID string `json:"channelid"`
103106
}
104107

105108
// ChannelCreateRequest hold data for create channel request
106109
// The request should contain the account id, and optionally some
107110
// channel properties to be initialised.
108111
type ChannelCreateRequest struct {
109-
AccountID string `json:"accountid"`
110-
PublicRead bool `json:"public_read"`
111-
PublicWrite bool `json:"public_write"`
112-
Sequenced bool `json:"sequenced"`
113-
Retention struct {
114-
MinAgeDays int `json:"min_age_days"`
115-
MaxAgeDays int `json:"max_age_days"`
116-
AutoPrune bool `json:"auto_prune"`
117-
} `json:"retention"`
112+
AccountID int64 `json:"accountid"`
113+
PublicRead bool `json:"public_read"`
114+
PublicWrite bool `json:"public_write"`
115+
Sequenced bool `json:"sequenced"`
116+
Retention Retention `json:"retention"`
117+
}
118+
119+
// Retention the data retention policy of a channel.
120+
type Retention struct {
121+
MinAgeDays int `json:"min_age_days"`
122+
MaxAgeDays int `json:"max_age_days"`
123+
AutoPrune bool `json:"auto_prune"`
118124
}
119125

120126
// ChannelCreateReply hold data for create channel reply
121127
// It contains the new channel id, it's properties and the first
122128
// default created token to allow authentification the communication
123129
// on this channel
124130
type ChannelCreateReply struct {
125-
ID string `json:"id"`
126-
Href string `json:"href"`
127-
PublicRead bool `json:"public_read"`
128-
PublicWrite bool `json:"public_write"`
129-
Sequenced bool `json:"sequenced"`
130-
Locked bool `json:"locked"`
131-
Head int `json:"head"`
132-
Retention struct {
133-
MinAgeDays int `json:"min_age_days"`
134-
MaxAgeDays int `json:"max_age_days"`
135-
AutoPrune bool `json:"auto_prune"`
136-
} `json:"retention"`
131+
ID string `json:"id"`
132+
Href string `json:"href"`
133+
PublicRead bool `json:"public_read"`
134+
PublicWrite bool `json:"public_write"`
135+
Sequenced bool `json:"sequenced"`
136+
Locked bool `json:"locked"`
137+
Head int `json:"head"`
138+
Retention Retention `json:"retention"`
137139
AccessTokens []struct {
138140
ID string `json:"id"`
139141
Token string `json:"token"`
@@ -147,7 +149,7 @@ type ChannelCreateReply struct {
147149
// A token belong to a particular channel, which again belong to a particular account.
148150
// To identify a token, it needs to provide account id, channel id, and token id
149151
type TokenRequest struct {
150-
AccountID string `json:"accountid"`
152+
AccountID int64 `json:"accountid"`
151153
ChannelID string `json:"channelid"`
152154
TokenID string `json:"tokenid"`
153155
}
@@ -170,15 +172,15 @@ type TokenReply struct {
170172
// A token belong to a particular channel, which again belong to a particular account.
171173
// To identify a token, it needs to provide account id, channel id, and token id
172174
type TokenDeleteRequest struct {
173-
AccountID string `json:"accountid"`
175+
AccountID int64 `json:"accountid"`
174176
ChannelID string `json:"channelid"`
175177
TokenID string `json:"tokenid"`
176178
}
177179

178180
// TokensRequest hold data for get tokens request
179181
// The request contains the account id and channel id.
180182
type TokensRequest struct {
181-
AccountID string `json:"accountid"`
183+
AccountID int64 `json:"accountid"`
182184
ChannelID string `json:"channelid"`
183185
}
184186

@@ -189,7 +191,7 @@ type TokensReply []TokenReply
189191
// The request should contains existing account and channel id,
190192
// with optionally some description and permission properties attached to the token
191193
type TokenCreateRequest struct {
192-
AccountID string `json:"accountid"`
194+
AccountID int64 `json:"accountid"`
193195
ChannelID string `json:"channelid"`
194196
Description string `json:"description"`
195197
CanRead bool `json:"can_read"`
@@ -211,7 +213,7 @@ func (c *Client) Channels(ctx context.Context, r ChannelsRequest) (*ChannelsRepl
211213
req, err := http.NewRequestWithContext(
212214
ctx,
213215
http.MethodGet,
214-
fmt.Sprintf("%s/%s/channel/list", c.getChanelBaseEndpoint(), r.AccountID),
216+
fmt.Sprintf("%s/%d/channel/list", c.getChanelBaseEndpoint(), r.AccountID),
215217
nil,
216218
)
217219
if err != nil {
@@ -231,7 +233,7 @@ func (c *Client) Channel(ctx context.Context, r ChannelRequest) (*ChannelReply,
231233
req, err := http.NewRequestWithContext(
232234
ctx,
233235
http.MethodGet,
234-
fmt.Sprintf("%s/%s/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
236+
fmt.Sprintf("%s/%d/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
235237
nil,
236238
)
237239

@@ -257,7 +259,7 @@ func (c *Client) ChannelUpdate(ctx context.Context, r ChannelUpdateRequest) (*Ch
257259
req, err := http.NewRequestWithContext(
258260
ctx,
259261
http.MethodPost,
260-
fmt.Sprintf("%s/%s/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
262+
fmt.Sprintf("%s/%d/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
261263
bytes.NewBuffer(payload),
262264
)
263265

@@ -278,7 +280,7 @@ func (c *Client) ChannelDelete(ctx context.Context, r ChannelDeleteRequest) erro
278280
req, err := http.NewRequestWithContext(
279281
ctx,
280282
http.MethodDelete,
281-
fmt.Sprintf("%s/%s/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
283+
fmt.Sprintf("%s/%d/channel/%s", c.getChanelBaseEndpoint(), r.AccountID, r.ChannelID),
282284
nil,
283285
)
284286

@@ -299,7 +301,7 @@ func (c *Client) ChannelCreate(ctx context.Context, r ChannelCreateRequest) (*Ch
299301
req, err := http.NewRequestWithContext(
300302
ctx,
301303
http.MethodPost,
302-
fmt.Sprintf("%s/%s/channel", c.getChanelBaseEndpoint(), r.AccountID),
304+
fmt.Sprintf("%s/%d/channel", c.getChanelBaseEndpoint(), r.AccountID),
303305
bytes.NewBuffer(payload),
304306
)
305307

channel_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestUnitChannels(t *testing.T) {
2626
}{
2727
"Mock Channels": {
2828
request: `{
29-
"accountid": "1"
29+
"accountid": 1
3030
}`,
3131
reply: `{
3232
"channels": [
@@ -100,7 +100,7 @@ func TestUnitChannel(t *testing.T) {
100100
}{
101101
"Mock Channel": {
102102
request: `{
103-
"accountid": "1",
103+
"accountid": 1,
104104
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA"
105105
}`,
106106
reply: `{
@@ -171,7 +171,7 @@ func TestUnitChannelUpdate(t *testing.T) {
171171
}{
172172
"Mock ChannelUpdate": {
173173
request: `{
174-
"accountid": "1",
174+
"accountid": 1,
175175
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA",
176176
"PublicRead": true,
177177
"PublicWrite": true,
@@ -227,7 +227,7 @@ func TestUnitChannelDelete(t *testing.T) {
227227
}{
228228
"Mock ChannelDelete": {
229229
request: `{
230-
"accountid": "1",
230+
"accountid": 1,
231231
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA"
232232
}`,
233233
reply: "{}",
@@ -270,7 +270,7 @@ func TestUnitChannelCreate(t *testing.T) {
270270
}{
271271
"Mock ChannelCreate": {
272272
request: `{
273-
"accountid": "1",
273+
"accountid": 1,
274274
"public_read": true,
275275
"public_write": true,
276276
"sequenced": true,
@@ -348,7 +348,7 @@ func TestUnitToken(t *testing.T) {
348348
}{
349349
"Mock Token": {
350350
request: `{
351-
"accountid": "1",
351+
"accountid": 1,
352352
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA",
353353
"tokenid": "1"
354354
}`,
@@ -404,7 +404,7 @@ func TestUnitTokenDelete(t *testing.T) {
404404
}{
405405
"Mock TokenDelete": {
406406
request: `{
407-
"accountid": "1",
407+
"accountid": 1,
408408
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA",
409409
"tokenid": "1"
410410
}`,
@@ -448,7 +448,7 @@ func TestUnitTokens(t *testing.T) {
448448
}{
449449
"Mock Tokens": {
450450
request: `{
451-
"accountid": "1",
451+
"accountid": 1,
452452
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA"
453453
}`,
454454
reply: `[
@@ -505,7 +505,7 @@ func TestUnitTokenCreate(t *testing.T) {
505505
}{
506506
"Mock TokenCreate": {
507507
request: `{
508-
"accountid": "1",
508+
"accountid": 1,
509509
"channelid": "H3mNdK-IL_-5OdLG4jymMwlJCW7NlhsNhxd_XrnKlv7J4hyR6EH2NIOaPmWlU7Rs0Zkgv_1yD0qcW7h29BGxbA",
510510
"description": "Owner",
511511
"can_read": true,

client.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"fmt"
4040
"net/http"
4141
"net/url"
42+
"path"
4243
"sync"
4344
"time"
4445

@@ -68,6 +69,7 @@ type ErrorHandlerFunc func(err error)
6869
// spvConfig hold configuration for rest api connection
6970
type spvConfig struct {
7071
insecure bool // equivalent curl -k
72+
tls bool
7173
baseURL string
7274
version string
7375
user string
@@ -78,16 +80,37 @@ type spvConfig struct {
7880
errHandler ErrorHandlerFunc
7981
}
8082

83+
func (s spvConfig) httpScheme() string {
84+
if s.tls {
85+
return "https"
86+
}
87+
return "http"
88+
}
89+
90+
func (s spvConfig) wsScheme() string {
91+
if s.tls {
92+
return "wss"
93+
}
94+
return "ws"
95+
}
96+
8197
// SPVConfigFunc set the rest api configuration
8298
type SPVConfigFunc func(c *spvConfig)
8399

84-
// WithInsecure skip the TSL check (for dev only)
100+
// WithInsecure skip the TLS check (for dev only)
85101
func WithInsecure() SPVConfigFunc {
86102
return func(c *spvConfig) {
87103
c.insecure = true
88104
}
89105
}
90106

107+
// WithNoTLS use http and ws in place of https and wss (for dev only)
108+
func WithNoTLS() SPVConfigFunc {
109+
return func(c *spvConfig) {
110+
c.tls = false
111+
}
112+
}
113+
91114
// WithBaseURL provide base url (domain:port) for the rest api
92115
func WithBaseURL(url string) SPVConfigFunc {
93116
return func(c *spvConfig) {
@@ -151,6 +174,7 @@ func defaultSPVConfig() *spvConfig {
151174
// Set the default options
152175
cfg := &spvConfig{
153176
insecure: false,
177+
tls: true,
154178
baseURL: "localhost:5010",
155179
version: "v1",
156180
user: "dev",
@@ -375,14 +399,14 @@ func NewWSClient(opts ...SPVConfigFunc) (*WSClient, error) {
375399

376400
// urlPath return the path part of the connection URL
377401
func (c *WSClient) urlPath() string {
378-
return fmt.Sprintf("/api/%s/channel/%s/notify", c.cfg.version, c.cfg.channelID)
402+
return path.Join("/api", c.cfg.version, "/channel", c.cfg.channelID, "/notify")
379403
}
380404

381405
// connectServer establish the connection to the server
382406
// Return error if any
383407
func (c *WSClient) connectServer() error {
384408
u := url.URL{
385-
Scheme: "wss",
409+
Scheme: c.cfg.wsScheme(),
386410
Host: c.cfg.baseURL,
387411
Path: c.urlPath(),
388412
}

0 commit comments

Comments
 (0)