@@ -4,81 +4,210 @@ import (
4
4
"fmt"
5
5
"log"
6
6
"strconv"
7
+ "strings"
8
+ "time"
7
9
)
8
10
9
11
// CreateWebhook - create a webhook for a vhost and a specific qeueu
10
- func (api * API ) CreateWebhook (instanceID int , params map [string ]interface {}) (map [string ]interface {}, error ) {
11
- data := make (map [string ]interface {})
12
- failed := make (map [string ]interface {})
13
- log .Printf ("[DEBUG] go-api::webhook::create params: %v" , params )
14
- path := fmt .Sprintf ("/api/instances/%d/webhooks" , instanceID )
12
+ func (api * API ) CreateWebhook (instanceID int , params map [string ]interface {},
13
+ sleep , timeout int ) (map [string ]interface {}, error ) {
14
+
15
+ return api .createWebhookWithRetry (instanceID , params , 1 , sleep , timeout )
16
+ }
17
+
18
+ // createWebhookWithRetry: create webhook with retry if backend is busy.
19
+ func (api * API ) createWebhookWithRetry (instanceID int , params map [string ]interface {},
20
+ attempt , sleep , timeout int ) (map [string ]interface {}, error ) {
21
+
22
+ var (
23
+ data = make (map [string ]interface {})
24
+ failed map [string ]interface {}
25
+ path = fmt .Sprintf ("/api/instances/%d/webhooks" , instanceID )
26
+ )
27
+
28
+ log .Printf ("[DEBUG] go-api::webhook#create path: %s, params: %v" , path , params )
15
29
response , err := api .sling .New ().Post (path ).BodyJSON (params ).Receive (& data , & failed )
16
- log .Printf ("[DEBUG] go-api::webhook:: create response data: %v" , data )
30
+ log .Printf ("[DEBUG] go-api::webhook# create response data: %v" , data )
17
31
18
32
if err != nil {
19
33
return nil , err
20
- }
21
- if response .StatusCode != 201 {
22
- return nil , fmt .Errorf (fmt .Sprintf ("CreateWebhook failed, status: %v, message: %s" , response .StatusCode , failed ))
34
+ } else if attempt * sleep > timeout {
35
+ return nil , fmt .Errorf ("create webhook reached timeout of %d seconds" , timeout )
23
36
}
24
37
25
- if v , ok := data ["id" ]; ok {
26
- data ["id" ] = strconv .FormatFloat (v .(float64 ), 'f' , 0 , 64 )
27
- } else {
28
- msg := fmt .Sprintf ("go-api::webhook::create Invalid webhook identifier: %v" , data ["id" ])
29
- log .Printf ("[ERROR] %s" , msg )
30
- return nil , fmt .Errorf (msg )
38
+ switch response .StatusCode {
39
+ case 201 :
40
+ if v , ok := data ["id" ]; ok {
41
+ data ["id" ] = strconv .FormatFloat (v .(float64 ), 'f' , 0 , 64 )
42
+ } else {
43
+ msg := fmt .Sprintf ("go-api::webhook#create Invalid webhook identifier: %v" , data ["id" ])
44
+ log .Printf ("[ERROR] %s" , msg )
45
+ return nil , fmt .Errorf (msg )
46
+ }
47
+ return data , nil
48
+ case 400 :
49
+ if strings .Compare (failed ["error" ].(string ), "Timeout talking to backend" ) == 0 {
50
+ log .Printf ("[INFO] go-api::webhook#create Timeout talking to backend " +
51
+ "attempt: %d, until timeout: %d" , attempt , (timeout - (attempt * sleep )))
52
+ attempt ++
53
+ time .Sleep (time .Duration (sleep ) * time .Second )
54
+ return api .createWebhookWithRetry (instanceID , params , attempt , sleep , timeout )
55
+ }
56
+ return nil , fmt .Errorf ("create webhook failed, status: %v, message: %s" , 400 , failed )
57
+ default :
58
+ return nil ,
59
+ fmt .Errorf ("create webhook with retry failed, status: %v, message: %s" ,
60
+ response .StatusCode , failed )
31
61
}
32
-
33
- return data , err
34
62
}
35
63
36
64
// ReadWebhook - retrieves a specific webhook for an instance
37
- func (api * API ) ReadWebhook (instanceID int , webhookID string ) (map [string ]interface {}, error ) {
38
- data := make (map [string ]interface {})
39
- failed := make (map [string ]interface {})
40
- log .Printf ("[DEBUG] go-api::webhook::read instance ID: %d, webhookID: %s" , instanceID , webhookID )
65
+ func (api * API ) ReadWebhook (instanceID int , webhookID string , sleep , timeout int ) (
66
+ map [string ]interface {}, error ) {
67
+
41
68
path := fmt .Sprintf ("/api/instances/%d/webhooks/%s" , instanceID , webhookID )
42
- response , err := api .sling .New ().Path (path ).Receive (& data , & failed )
69
+ return api .readWebhookWithRetry (path , 1 , sleep , timeout )
70
+ }
71
+
72
+ // readWebhookWithRetry: read webhook with retry if backend is busy.
73
+ func (api * API ) readWebhookWithRetry (path string , attempt , sleep , timeout int ) (
74
+ map [string ]interface {}, error ) {
75
+
76
+ var (
77
+ data map [string ]interface {}
78
+ failed map [string ]interface {}
79
+ )
80
+
81
+ log .Printf ("[DEBUG] go-api::webhook#read path: %s" , path )
82
+ response , err := api .sling .New ().Get (path ).Receive (& data , & failed )
83
+ log .Printf ("[DEBUG] go-api::webhook#read response data: %v" , data )
43
84
44
85
if err != nil {
45
86
return nil , err
46
- }
47
- if response .StatusCode != 200 {
48
- return nil , fmt .Errorf ("ReadWebhook failed, status: %v, message: %s" , response .StatusCode , failed )
87
+ } else if attempt * sleep > timeout {
88
+ return nil , fmt .Errorf ("read webhook reached timeout of %d seconds" , timeout )
49
89
}
50
90
51
- return data , err
91
+ switch response .StatusCode {
92
+ case 200 :
93
+ return data , nil
94
+ case 400 :
95
+ if strings .Compare (failed ["error" ].(string ), "Timeout talking to backend" ) == 0 {
96
+ log .Printf ("[INFO] go-api::webhook#read Timeout talking to backend " +
97
+ "attempt: %d, until timeout: %d" , attempt , (timeout - (attempt * sleep )))
98
+ attempt ++
99
+ time .Sleep (time .Duration (sleep ) * time .Second )
100
+ return api .readWebhookWithRetry (path , attempt , sleep , timeout )
101
+ }
102
+ return nil , fmt .Errorf ("read webhook failed, status: %v, message: %s" , 400 , failed )
103
+ default :
104
+ return nil , fmt .Errorf ("read webhook with retry failed, status: %v, message: %s" ,
105
+ response .StatusCode , failed )
106
+ }
52
107
}
53
108
54
- // ReadWebhooks - retrieves all webhooks for an instance.
55
- func (api * API ) ReadWebhooks (instanceID int ) (map [string ]interface {}, error ) {
56
- data := make (map [string ]interface {})
57
- failed := make (map [string ]interface {})
58
- log .Printf ("[DEBUG] go-api::webhook::read instance ID: %d" , instanceID )
59
- path := fmt .Sprintf ("/api/instances/%d/webhooks" , instanceID )
109
+ // ListWebhooks - list all webhooks for an instance.
110
+ func (api * API ) ListWebhooks (instanceID int ) (map [string ]interface {}, error ) {
111
+ var (
112
+ data map [string ]interface {}
113
+ failed map [string ]interface {}
114
+ path = fmt .Sprintf ("/api/instances/%d/webhooks" , instanceID )
115
+ )
116
+
117
+ log .Printf ("[DEBUG] go-api::webhook#list path: %s" , path )
60
118
response , err := api .sling .New ().Path (path ).Receive (& data , & failed )
61
119
62
120
if err != nil {
63
121
return nil , err
64
122
}
65
123
if response .StatusCode != 200 {
66
- return nil , fmt .Errorf ("ReadWebhooks failed, status: %v, message: %s" , response .StatusCode , failed )
124
+ return nil , fmt .Errorf ("list webhooks failed, status: %v, message: %s" ,
125
+ response .StatusCode , failed )
67
126
}
68
127
69
128
return data , err
70
129
}
71
130
131
+ // UpdateWebhook - updates a specific webhook for an instance
132
+ func (api * API ) UpdateWebhook (instanceID int , webhookID string , params map [string ]interface {},
133
+ sleep , timeout int ) error {
134
+
135
+ path := fmt .Sprintf ("/api/instances/%d/webhooks/%s" , instanceID , webhookID )
136
+ return api .updateWebhookWithRetry (path , params , 1 , sleep , timeout )
137
+ }
138
+
139
+ // updateWebhookWithRetry: update webhook with retry if backend is busy.
140
+ func (api * API ) updateWebhookWithRetry (path string , params map [string ]interface {},
141
+ attempt , sleep , timeout int ) error {
142
+
143
+ var (
144
+ data = make (map [string ]interface {})
145
+ failed map [string ]interface {}
146
+ )
147
+
148
+ log .Printf ("[DEBUG] go-api::webhook#update path: %s, params: %v" , path , params )
149
+ response , err := api .sling .New ().Put (path ).BodyJSON (params ).Receive (& data , & failed )
150
+ log .Printf ("[DEBUG] go-api::webhook#update response data: %v" , data )
151
+
152
+ if err != nil {
153
+ return err
154
+ } else if attempt * sleep > timeout {
155
+ return fmt .Errorf ("update webhook reached timeout of %d seconds" , timeout )
156
+ }
157
+
158
+ switch response .StatusCode {
159
+ case 201 :
160
+ return nil
161
+ case 400 :
162
+ if strings .Compare (failed ["error" ].(string ), "Timeout talking to backend" ) == 0 {
163
+ log .Printf ("[INFO] go-api::webhook#update Timeout talking to backend " +
164
+ "attempt: %d, until timeout: %d" , attempt , (timeout - (attempt * sleep )))
165
+ attempt ++
166
+ time .Sleep (time .Duration (sleep ) * time .Second )
167
+ return api .updateWebhookWithRetry (path , params , attempt , sleep , timeout )
168
+ }
169
+ return fmt .Errorf ("update webhook failed, status: %v, message: %s" , 400 , failed )
170
+ default :
171
+ return fmt .Errorf ("update webhook with retry failed, status: %v, message: %s" ,
172
+ response .StatusCode , failed )
173
+ }
174
+ }
175
+
72
176
// DeleteWebhook - removes a specific webhook for an instance
73
- func (api * API ) DeleteWebhook (instanceID int , webhookID string ) error {
74
- failed := make (map [string ]interface {})
75
- log .Printf ("[DEBUG] go-api::webhook::delete instance ID: %d, webhookID: %s" , instanceID , webhookID )
177
+ func (api * API ) DeleteWebhook (instanceID int , webhookID string , sleep , timeout int ) error {
76
178
path := fmt .Sprintf ("/api/instances/%d/webhooks/%s" , instanceID , webhookID )
179
+ return api .deleteWebhookWithRetry (path , 1 , sleep , timeout )
180
+ }
181
+
182
+ // deleteWebhookWithRetry: delete webhook with retry if backend is busy.
183
+ func (api * API ) deleteWebhookWithRetry (path string , attempt , sleep , timeout int ) error {
184
+ var (
185
+ failed map [string ]interface {}
186
+ )
187
+
188
+ log .Printf ("[DEBUG] go-api::webhook#delete path: %s" , path )
77
189
response , err := api .sling .New ().Delete (path ).Receive (nil , & failed )
78
190
79
- if response .StatusCode != 204 {
80
- return fmt .Errorf ("DeleteWebhook failed, status: %v, message: %s" , response .StatusCode , failed )
191
+ if err != nil {
192
+ return err
193
+ } else if attempt * sleep > timeout {
194
+ return fmt .Errorf ("delete webhook reached timeout of %d seconds" , timeout )
81
195
}
82
196
83
- return err
197
+ switch response .StatusCode {
198
+ case 204 :
199
+ return nil
200
+ case 400 :
201
+ if strings .Compare (failed ["error" ].(string ), "Timeout talking to backend" ) == 0 {
202
+ log .Printf ("[INFO] go-api::webhook#delete Timeout talking to backend " +
203
+ "attempt: %d, until timeout: %d" , attempt , (timeout - (attempt * sleep )))
204
+ attempt ++
205
+ time .Sleep (time .Duration (sleep ) * time .Second )
206
+ return api .deleteWebhookWithRetry (path , attempt , sleep , timeout )
207
+ }
208
+ return fmt .Errorf ("delete webhook failed, status: %v, message: %s" , 400 , failed )
209
+ default :
210
+ return fmt .Errorf ("delete webhook with retry failed, status: %v, message: %s" ,
211
+ response .StatusCode , failed )
212
+ }
84
213
}
0 commit comments