Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 273 lines (221 sloc) 5.635 kB
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
1 package couchbase
2
d4b0c22 @dustin Move PutDDoc into ddocs.go
dustin authored
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "io/ioutil"
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
8 "log"
d4b0c22 @dustin Move PutDDoc into ddocs.go
dustin authored
9 "net/http"
10 )
11
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
12 // ViewDefinition represents a single view within a design document.
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
13 type ViewDefinition struct {
14 Map string `json:"map"`
75c8dae @melkote Suppress empty reduce function.
melkote authored
15 Reduce string `json:"reduce,omitempty"`
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
16 }
17
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
18 // DDoc is the document body of a design document specifying a view.
19 type DDoc struct {
75c8dae @melkote Suppress empty reduce function.
melkote authored
20 Language string `json:"language,omitempty"`
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
21 Views map[string]ViewDefinition `json:"views"`
22 }
23
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
24 // DDocsResult represents the result from listing the design
25 // documents.
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
26 type DDocsResult struct {
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
27 Rows []struct {
28 DDoc struct {
29 Meta map[string]interface{}
98eaf35 @dustin More doc/golint cleanup
dustin authored
30 JSON DDoc
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
31 } `json:"doc"`
32 } `json:"rows"`
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
33 }
34
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
35 // GetDDocs lists all design documents
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
36 func (b *Bucket) GetDDocs() (DDocsResult, error) {
37 var ddocsResult DDocsResult
0632c53 @maniktaneja Add functions GetDDocWithRetry and GetDDocsWithRetry
maniktaneja authored
38
e1dffac @dustin Auth refactoring
dustin authored
39 err := b.pool.client.parseURLResponse(b.DDocs.URI, &ddocsResult)
bba4763 @mschoch REST discovery of buckets ddocs URI and method to get ddocs
mschoch authored
40 if err != nil {
41 return DDocsResult{}, err
42 }
43 return ddocsResult, nil
44 }
d4b0c22 @dustin Move PutDDoc into ddocs.go
dustin authored
45
0632c53 @maniktaneja Add functions GetDDocWithRetry and GetDDocsWithRetry
maniktaneja authored
46 func (b *Bucket) GetDDocWithRetry(docname string, into interface{}) error {
47
48 ddocURI := fmt.Sprintf("/%s/_design/%s", b.Name, docname)
49 err := b.parseAPIResponse(ddocURI, &into)
50 if err != nil {
51 return err
52 }
53 return nil
54 }
55
56 func (b *Bucket) GetDDocsWithRetry() (DDocsResult, error) {
57 var ddocsResult DDocsResult
58
59 err := b.parseURLResponse(b.DDocs.URI, &ddocsResult)
60 if err != nil {
61 return DDocsResult{}, err
62 }
63 return ddocsResult, nil
64 }
65
9d80792 @dustin Added ddoc get.
dustin authored
66 func (b *Bucket) ddocURL(docname string) (string, error) {
67 u, err := b.randomBaseURL()
68 if err != nil {
69 return "", err
70 }
71 u.Path = fmt.Sprintf("/%s/_design/%s", b.Name, docname)
72 return u.String(), nil
73 }
74
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
75 func (b *Bucket) ddocURLNext(nodeId int, docname string) (string, int, error) {
76 u, selected, err := b.randomNextURL(nodeId)
77 if err != nil {
78 return "", -1, err
79 }
80 u.Path = fmt.Sprintf("/%s/_design/%s", b.Name, docname)
81 return u.String(), selected, nil
82 }
83
84 const ABS_MAX_RETRIES = 10
85 const ABS_MIN_RETRIES = 3
86
87 func (b *Bucket) getMaxRetries() (int, error) {
88
89 maxRetries := len(b.Nodes())
90
91 if maxRetries == 0 {
92 return 0, fmt.Errorf("No available Couch rest URLs")
93 }
94
95 if maxRetries > ABS_MAX_RETRIES {
96 maxRetries = ABS_MAX_RETRIES
97 } else if maxRetries < ABS_MIN_RETRIES {
98 maxRetries = ABS_MIN_RETRIES
99 }
100
101 return maxRetries, nil
102 }
103
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
104 // PutDDoc installs a design document.
d4b0c22 @dustin Move PutDDoc into ddocs.go
dustin authored
105 func (b *Bucket) PutDDoc(docname string, value interface{}) error {
106
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
107 var Err error
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
108
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
109 maxRetries, err := b.getMaxRetries()
110 if err != nil {
111 return err
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
112 }
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
113
114 lastNode := START_NODE_ID
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
115
116 for retryCount := 0; retryCount < maxRetries; retryCount++ {
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
117
118 Err = nil
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
119
120 ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
121 if err != nil {
122 return err
123 }
124
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
125 lastNode = selectedNode
126
127 log.Printf(" Trying with selected node %d", selectedNode)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
128 j, err := json.Marshal(value)
129 if err != nil {
130 return err
131 }
132
133 req, err := http.NewRequest("PUT", ddocU, bytes.NewReader(j))
134 if err != nil {
135 return err
136 }
137 req.Header.Set("Content-Type", "application/json")
138 err = maybeAddAuth(req, b.authHandler())
139 if err != nil {
140 return err
141 }
142
8d2533e @maniktaneja MB-13738 & MB-13878 : Retry http requests due to network failure
maniktaneja authored
143 res, err := doHTTPRequest(req)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
144 if err != nil {
145 return err
146 }
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
147
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
148 if res.StatusCode != 201 {
149 body, _ := ioutil.ReadAll(res.Body)
150 Err = fmt.Errorf("error installing view: %v / %s",
151 res.Status, body)
152 log.Printf(" Error in PutDDOC %v. Retrying...", Err)
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
153 res.Body.Close()
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
154 b.Refresh()
155 continue
156 }
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
157
158 res.Body.Close()
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
159 break
160 }
161
162 return Err
d4b0c22 @dustin Move PutDDoc into ddocs.go
dustin authored
163 }
9d80792 @dustin Added ddoc get.
dustin authored
164
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
165 // GetDDoc retrieves a specific a design doc.
9d80792 @dustin Added ddoc get.
dustin authored
166 func (b *Bucket) GetDDoc(docname string, into interface{}) error {
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
167 var Err error
168 var res *http.Response
169
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
170 maxRetries, err := b.getMaxRetries()
171 if err != nil {
172 return err
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
173 }
174
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
175 lastNode := START_NODE_ID
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
176 for retryCount := 0; retryCount < maxRetries; retryCount++ {
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
177
178 Err = nil
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
179 ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
180 if err != nil {
181 return err
182 }
183
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
184 lastNode = selectedNode
185 log.Printf(" Trying with selected node %d", selectedNode)
186
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
187 req, err := http.NewRequest("GET", ddocU, nil)
188 if err != nil {
189 return err
190 }
191 req.Header.Set("Content-Type", "application/json")
192 err = maybeAddAuth(req, b.authHandler())
193 if err != nil {
194 return err
195 }
196
8d2533e @maniktaneja MB-13738 & MB-13878 : Retry http requests due to network failure
maniktaneja authored
197 res, err = doHTTPRequest(req)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
198 if err != nil {
199 return err
200 }
201 if res.StatusCode != 200 {
202 body, _ := ioutil.ReadAll(res.Body)
203 Err = fmt.Errorf("error reading view: %v / %s",
204 res.Status, body)
205 log.Printf(" Error in GetDDOC %v Retrying...", Err)
206 b.Refresh()
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
207 res.Body.Close()
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
208 continue
209 }
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
210 res.Body.Close()
211 break
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
212 }
213
214 if Err != nil {
215 return Err
9d80792 @dustin Added ddoc get.
dustin authored
216 }
217
218 d := json.NewDecoder(res.Body)
219 return d.Decode(into)
220 }
ff7195c @melkote Add ability delete design docs
melkote authored
221
88b6e00 @dustin Removed some unnecessarily exported types in ddoc list
dustin authored
222 // DeleteDDoc removes a design document.
ff7195c @melkote Add ability delete design docs
melkote authored
223 func (b *Bucket) DeleteDDoc(docname string) error {
224
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
225 var Err error
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
226
227 maxRetries, err := b.getMaxRetries()
228 if err != nil {
229 return err
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
230 }
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
231
232 lastNode := START_NODE_ID
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
233
234 for retryCount := 0; retryCount < maxRetries; retryCount++ {
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
235
236 Err = nil
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
237 ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
238 if err != nil {
239 return err
240 }
241
cb6ff56 @maniktaneja Cycle through the list of available servers while retryingi.
maniktaneja authored
242 lastNode = selectedNode
243 log.Printf(" Trying with selected node %d", selectedNode)
244
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
245 req, err := http.NewRequest("DELETE", ddocU, nil)
246 if err != nil {
247 return err
248 }
249 req.Header.Set("Content-Type", "application/json")
250 err = maybeAddAuth(req, b.authHandler())
251 if err != nil {
252 return err
253 }
254
8d2533e @maniktaneja MB-13738 & MB-13878 : Retry http requests due to network failure
maniktaneja authored
255 res, err := doHTTPRequest(req)
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
256 if err != nil {
257 return err
258 }
259 if res.StatusCode != 200 {
260 body, _ := ioutil.ReadAll(res.Body)
261 Err = fmt.Errorf("error deleting view : %v / %s", res.Status, body)
262 log.Printf(" Error in DeleteDDOC %v. Retrying ... ", Err)
263 b.Refresh()
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
264 res.Body.Close()
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
265 continue
266 }
267
5c9406c @maniktaneja Handle response body close on retry and match
maniktaneja authored
268 res.Body.Close()
c6f2b95 @maniktaneja MB-13109. Add retry logic to views APIs
maniktaneja authored
269 break
270 }
271 return Err
ff7195c @melkote Add ability delete design docs
melkote authored
272 }
Something went wrong with that request. Please try again.