|
7 | 7 | "net/http"
|
8 | 8 | "strings"
|
9 | 9 | texttemplate "text/template"
|
| 10 | + "time" |
| 11 | + |
| 12 | + "github.com/hashicorp/go-retryablehttp" |
10 | 13 |
|
11 | 14 | log "github.com/sirupsen/logrus"
|
12 | 15 |
|
@@ -77,13 +80,26 @@ type BasicAuth struct {
|
77 | 80 | }
|
78 | 81 |
|
79 | 82 | type WebhookOptions struct {
|
80 |
| - URL string `json:"url"` |
81 |
| - Headers []Header `json:"headers"` |
82 |
| - BasicAuth *BasicAuth `json:"basicAuth"` |
83 |
| - InsecureSkipVerify bool `json:"insecureSkipVerify"` |
| 83 | + URL string `json:"url"` |
| 84 | + Headers []Header `json:"headers"` |
| 85 | + BasicAuth *BasicAuth `json:"basicAuth"` |
| 86 | + InsecureSkipVerify bool `json:"insecureSkipVerify"` |
| 87 | + RetryWaitMin time.Duration `json:"retryWaitMin"` |
| 88 | + RetryWaitMax time.Duration `json:"retryWaitMax"` |
| 89 | + RetryMax int `json:"retryMax"` |
84 | 90 | }
|
85 | 91 |
|
86 | 92 | func NewWebhookService(opts WebhookOptions) NotificationService {
|
| 93 | + // Set default values if fields are zero |
| 94 | + if opts.RetryWaitMin == 0 { |
| 95 | + opts.RetryWaitMin = 1 * time.Second |
| 96 | + } |
| 97 | + if opts.RetryWaitMax == 0 { |
| 98 | + opts.RetryWaitMax = 5 * time.Second |
| 99 | + } |
| 100 | + if opts.RetryMax == 0 { |
| 101 | + opts.RetryMax = 3 |
| 102 | + } |
87 | 103 | return &webhookService{opts: opts}
|
88 | 104 | }
|
89 | 105 |
|
@@ -133,31 +149,37 @@ func (r *request) applyOverridesFrom(notification WebhookNotification) {
|
133 | 149 | }
|
134 | 150 | }
|
135 | 151 |
|
136 |
| -func (r *request) intoHttpRequest(service *webhookService) (*http.Request, error) { |
137 |
| - req, err := http.NewRequest(r.method, r.url, bytes.NewBufferString(r.body)) |
| 152 | +func (r *request) intoRetryableHttpRequest(service *webhookService) (*retryablehttp.Request, error) { |
| 153 | + retryReq, err := retryablehttp.NewRequest(r.method, r.url, bytes.NewBufferString(r.body)) |
138 | 154 | if err != nil {
|
139 | 155 | return nil, err
|
140 | 156 | }
|
141 | 157 | for _, header := range service.opts.Headers {
|
142 |
| - req.Header.Set(header.Name, header.Value) |
| 158 | + retryReq.Header.Set(header.Name, header.Value) |
143 | 159 | }
|
144 | 160 | if service.opts.BasicAuth != nil {
|
145 |
| - req.SetBasicAuth(service.opts.BasicAuth.Username, service.opts.BasicAuth.Password) |
| 161 | + retryReq.SetBasicAuth(service.opts.BasicAuth.Username, service.opts.BasicAuth.Password) |
146 | 162 | }
|
147 |
| - return req, nil |
| 163 | + return retryReq, nil |
148 | 164 | }
|
149 | 165 |
|
150 | 166 | func (r *request) execute(service *webhookService) (*http.Response, error) {
|
151 |
| - req, err := r.intoHttpRequest(service) |
| 167 | + req, err := r.intoRetryableHttpRequest(service) |
152 | 168 | if err != nil {
|
153 | 169 | return nil, err
|
154 | 170 | }
|
155 | 171 |
|
156 |
| - client := http.Client{ |
157 |
| - Transport: httputil.NewLoggingRoundTripper( |
158 |
| - httputil.NewTransport(r.url, service.opts.InsecureSkipVerify), |
159 |
| - log.WithField("service", r.destService)), |
| 172 | + transport := httputil.NewLoggingRoundTripper( |
| 173 | + httputil.NewTransport(r.url, service.opts.InsecureSkipVerify), |
| 174 | + log.WithField("service", r.destService)) |
| 175 | + |
| 176 | + client := retryablehttp.NewClient() |
| 177 | + client.HTTPClient = &http.Client{ |
| 178 | + Transport: transport, |
160 | 179 | }
|
| 180 | + client.RetryWaitMin = service.opts.RetryWaitMin |
| 181 | + client.RetryWaitMax = service.opts.RetryWaitMax |
| 182 | + client.RetryMax = service.opts.RetryMax |
161 | 183 |
|
162 | 184 | return client.Do(req)
|
163 | 185 | }
|
0 commit comments