-
Notifications
You must be signed in to change notification settings - Fork 3
/
service.go
111 lines (87 loc) · 3.32 KB
/
service.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
package cloud_accounts
import (
"context"
"fmt"
"net/http"
"github.com/RedisLabs/rediscloud-go-api/internal"
)
type Log interface {
Printf(format string, args ...interface{})
}
type HttpClient interface {
Get(ctx context.Context, name, path string, responseBody interface{}) error
Post(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error
Put(ctx context.Context, name, path string, requestBody interface{}, responseBody interface{}) error
Delete(ctx context.Context, name, path string, responseBody interface{}) error
}
type TaskWaiter interface {
WaitForResourceId(ctx context.Context, id string) (int, error)
Wait(ctx context.Context, id string) error
}
type API struct {
client HttpClient
taskWaiter TaskWaiter
logger Log
}
func NewAPI(client HttpClient, taskWaiter TaskWaiter, logger Log) *API {
return &API{client: client, taskWaiter: taskWaiter, logger: logger}
}
// Create will create a new Cloud Account and return the identifier of the new account.
func (a *API) Create(ctx context.Context, account CreateCloudAccount) (int, error) {
var response internal.TaskResponse
if err := a.client.Post(ctx, "cloud account", "/cloud-accounts", account, &response); err != nil {
return 0, err
}
a.logger.Printf("Waiting for task %s to finish creating the cloud account", response)
id, err := a.taskWaiter.WaitForResourceId(ctx, *response.ID)
if err != nil {
return 0, err
}
return id, nil
}
func (a API) List(ctx context.Context) ([]*CloudAccount, error) {
var response listCloudAccounts
if err := a.client.Get(ctx, "list cloud accounts", "/cloud-accounts", &response); err != nil {
return nil, err
}
return response.CloudAccounts, nil
}
// Get will retrieve an existing Cloud Account.
func (a *API) Get(ctx context.Context, id int) (*CloudAccount, error) {
var response CloudAccount
if err := a.client.Get(ctx, fmt.Sprintf("retrieve cloud account %d", id), fmt.Sprintf("/cloud-accounts/%d", id), &response); err != nil {
return nil, wrap404Error(id, err)
}
return &response, nil
}
// Update will update certain values of an existing Cloud Account.
func (a *API) Update(ctx context.Context, id int, account UpdateCloudAccount) error {
var response internal.TaskResponse
if err := a.client.Put(ctx, fmt.Sprintf("update cloud account %d", id), fmt.Sprintf("/cloud-accounts/%d", id), account, &response); err != nil {
return wrap404Error(id, err)
}
a.logger.Printf("Waiting for cloud account %d to finish being updated", id)
err := a.taskWaiter.Wait(ctx, *response.ID)
if err != nil {
return fmt.Errorf("failed when updating account %d: %w", id, err)
}
return nil
}
// Delete will delete an existing Cloud Account.
func (a *API) Delete(ctx context.Context, id int) error {
var response internal.TaskResponse
if err := a.client.Delete(ctx, fmt.Sprintf("delete cloud account %d", id), fmt.Sprintf("/cloud-accounts/%d", id), &response); err != nil {
return wrap404Error(id, err)
}
a.logger.Printf("Waiting for cloud account %d to finish being deleted", id)
if err := a.taskWaiter.Wait(ctx, *response.ID); err != nil {
return fmt.Errorf("failed when deleting account %d: %w", id, err)
}
return nil
}
func wrap404Error(id int, err error) error {
if v, ok := err.(*internal.HTTPError); ok && v.StatusCode == http.StatusNotFound {
return &NotFound{id: id}
}
return err
}