@@ -112,7 +112,7 @@ func NewRequest(method string, endpoint string, body interface{}, arguments ...i
112112
113113// RestService represents a REST client
114114type RestService struct {
115- url * url.URL
115+ urls [] * url.URL
116116 headers http.Header
117117 maxRetries int
118118 retriesWaitMs int
@@ -124,21 +124,22 @@ type RestService struct {
124124// NewRestService returns a new REST client for the Confluent Schema Registry
125125func NewRestService (conf * ClientConfig ) (* RestService , error ) {
126126 urlConf := conf .SchemaRegistryURL
127- u , err := url .Parse (urlConf )
128-
129- if err != nil {
130- return nil , err
127+ urlStrs := strings .Split (urlConf , "," )
128+ urls := make ([]* url.URL , len (urlStrs ))
129+ for i , urlStr := range urlStrs {
130+ u , err := url .Parse (strings .TrimSpace (urlStr ))
131+ if err != nil {
132+ return nil , err
133+ }
134+ urls [i ] = u
131135 }
132136
133- headers , err := NewAuthHeader (u , conf )
137+ headers , err := NewAuthHeader (urls [ 0 ] , conf )
134138 if err != nil {
135139 return nil , err
136140 }
137141
138142 headers .Add ("Content-Type" , "application/vnd.schemaregistry.v1+json" )
139- if err != nil {
140- return nil , err
141- }
142143
143144 if conf .HTTPClient == nil {
144145 transport , err := configureTransport (conf )
@@ -155,7 +156,7 @@ func NewRestService(conf *ClientConfig) (*RestService, error) {
155156 }
156157
157158 return & RestService {
158- url : u ,
159+ urls : urls ,
159160 headers : headers ,
160161 maxRetries : conf .MaxRetries ,
161162 retriesWaitMs : conf .RetriesWaitMs ,
@@ -337,19 +338,51 @@ func NewAuthHeader(service *url.URL, conf *ClientConfig) (http.Header, error) {
337338 return header , err
338339}
339340
340- // HandleRequest sends a HTTP(S) request to the Schema Registry, placing results into the response object
341+ // HandleRequest sends a request to the Schema Registry, iterating over the list of URLs
341342func (rs * RestService ) HandleRequest (request * API , response interface {}) error {
342- urlPath := path .Join (rs .url .Path , fmt .Sprintf (request .endpoint , request .arguments ... ))
343- endpoint , err := rs .url .Parse (urlPath )
344- if err != nil {
343+ var resp * http.Response
344+ var err error
345+ for i , u := range rs .urls {
346+ resp , err = rs .HandleHTTPRequest (u , request )
347+ if err != nil {
348+ if i == len (rs .urls )- 1 {
349+ return err
350+ }
351+ continue
352+ }
353+ if isSuccess (resp .StatusCode ) || ! isRetriable (resp .StatusCode ) || i >= rs .maxRetries {
354+ break
355+ }
356+ }
357+ defer resp .Body .Close ()
358+ if isSuccess (resp .StatusCode ) {
359+ if err = json .NewDecoder (resp .Body ).Decode (response ); err != nil {
360+ return err
361+ }
362+ return nil
363+ }
364+
365+ var failure rest.Error
366+ if err = json .NewDecoder (resp .Body ).Decode (& failure ); err != nil {
345367 return err
346368 }
347369
370+ return & failure
371+ }
372+
373+ // HandleHTTPRequest sends a HTTP(S) request to the Schema Registry, placing results into the response object
374+ func (rs * RestService ) HandleHTTPRequest (url * url.URL , request * API ) (* http.Response , error ) {
375+ urlPath := path .Join (url .Path , fmt .Sprintf (request .endpoint , request .arguments ... ))
376+ endpoint , err := url .Parse (urlPath )
377+ if err != nil {
378+ return nil , err
379+ }
380+
348381 var readCloser io.ReadCloser
349382 if request .body != nil {
350383 outbuf , err := json .Marshal (request .body )
351384 if err != nil {
352- return err
385+ return nil , err
353386 }
354387 readCloser = ioutil .NopCloser (bytes .NewBuffer (outbuf ))
355388 }
@@ -365,30 +398,16 @@ func (rs *RestService) HandleRequest(request *API, response interface{}) error {
365398 for i := 0 ; i < rs .maxRetries + 1 ; i ++ {
366399 resp , err = rs .Do (req )
367400 if err != nil {
368- return err
401+ return nil , err
369402 }
370403
371404 if isSuccess (resp .StatusCode ) || ! isRetriable (resp .StatusCode ) || i >= rs .maxRetries {
372- break
405+ return resp , nil
373406 }
374407
375408 time .Sleep (rs .fullJitter (i ))
376409 }
377-
378- defer resp .Body .Close ()
379- if resp .StatusCode == 200 {
380- if err = json .NewDecoder (resp .Body ).Decode (response ); err != nil {
381- return err
382- }
383- return nil
384- }
385-
386- var failure rest.Error
387- if err := json .NewDecoder (resp .Body ).Decode (& failure ); err != nil {
388- return err
389- }
390-
391- return & failure
410+ return nil , fmt .Errorf ("failed to send request after %d retries" , rs .maxRetries )
392411}
393412
394413func (rs * RestService ) fullJitter (retriesAttempted int ) time.Duration {
0 commit comments