@@ -34,32 +34,37 @@ import (
3434 "github.com/g42cloud-sdk/g42cloud-sdk-go/core/response"
3535 "github.com/g42cloud-sdk/g42cloud-sdk-go/core/sdkerr"
3636 jsoniter "github.com/json-iterator/go"
37+ "go.mongodb.org/mongo-driver/bson"
3738 "io/ioutil"
39+ "net"
3840 "net/url"
3941 "reflect"
4042 "strings"
43+ "sync/atomic"
4144)
4245
4346const (
44- userAgent = "User-Agent"
45- xRequestId = "X-Request-Id"
46- contentType = "Content-Type"
47- applicationXml = "application/xml"
47+ userAgent = "User-Agent"
48+ xRequestId = "X-Request-Id"
49+ contentType = "Content-Type"
50+ applicationXml = "application/xml"
51+ applicationBson = "application/bson"
4852)
4953
5054type HcHttpClient struct {
51- endpoint string
52- credential auth.ICredential
53- extraHeader map [string ]string
54- httpClient * impl.DefaultHttpClient
55+ endpoints []string
56+ endpointIndex int32
57+ credential auth.ICredential
58+ extraHeader map [string ]string
59+ httpClient * impl.DefaultHttpClient
5560}
5661
5762func NewHcHttpClient (httpClient * impl.DefaultHttpClient ) * HcHttpClient {
5863 return & HcHttpClient {httpClient : httpClient }
5964}
6065
61- func (hc * HcHttpClient ) WithEndpoint ( endpoint string ) * HcHttpClient {
62- hc .endpoint = endpoint
66+ func (hc * HcHttpClient ) WithEndpoints ( endpoints [] string ) * HcHttpClient {
67+ hc .endpoints = endpoints
6368 return hc
6469}
6570
@@ -87,14 +92,23 @@ func (hc *HcHttpClient) Sync(req interface{}, reqDef *def.HttpRequestDef) (inter
8792
8893func (hc * HcHttpClient ) SyncInvoke (req interface {}, reqDef * def.HttpRequestDef ,
8994 exchange * exchange.SdkExchange ) (interface {}, error ) {
90- httpRequest , err := hc .buildRequest (req , reqDef )
91- if err != nil {
92- return nil , err
93- }
95+ var resp * response.DefaultHttpResponse
96+ for {
97+ httpRequest , err := hc .buildRequest (req , reqDef )
98+ if err != nil {
99+ return nil , err
100+ }
94101
95- resp , err := hc .httpClient .SyncInvokeHttpWithExchange (httpRequest , exchange )
96- if err != nil {
97- return nil , err
102+ resp , err = hc .httpClient .SyncInvokeHttpWithExchange (httpRequest , exchange )
103+ if err == nil {
104+ break
105+ }
106+
107+ if isNoSuchHostErr (err ) && atomic .LoadInt32 (& hc .endpointIndex ) < int32 (len (hc .endpoints )- 1 ) {
108+ atomic .AddInt32 (& hc .endpointIndex , 1 )
109+ } else {
110+ return nil , err
111+ }
98112 }
99113
100114 return hc .extractResponse (resp , reqDef )
@@ -104,7 +118,7 @@ func (hc *HcHttpClient) extractEndpoint(req interface{}, reqDef *def.HttpRequest
104118 var endpoint string
105119 for _ , v := range reqDef .RequestFields {
106120 if v .LocationType == def .Cname {
107- u , err := url .Parse (hc .endpoint )
121+ u , err := url .Parse (hc .endpoints [ atomic . LoadInt32 ( & hc . endpointIndex )] )
108122 if err != nil {
109123 return "" , err
110124 }
@@ -117,7 +131,7 @@ func (hc *HcHttpClient) extractEndpoint(req interface{}, reqDef *def.HttpRequest
117131 }
118132
119133 if endpoint == "" {
120- endpoint = hc .endpoint
134+ endpoint = hc .endpoints [ hc . endpointIndex ]
121135 }
122136
123137 return endpoint , nil
@@ -342,14 +356,16 @@ func (hc *HcHttpClient) deserializeResponseFields(resp *response.DefaultHttpResp
342356
343357 bodyErr := hc .deserializeResponseBody (reqDef , data )
344358 if bodyErr != nil {
345- return processError (err )
359+ return processError (bodyErr )
346360 }
347361 }
348362 }
349363
350364 if len (data ) != 0 && ! hasBody {
351365 if strings .Contains (resp .Response .Header .Get (contentType ), applicationXml ) {
352366 err = xml .Unmarshal (data , & reqDef .Response )
367+ } else if strings .Contains (resp .Response .Header .Get (contentType ), applicationBson ) {
368+ err = bson .Unmarshal (data , reqDef .Response )
353369 } else {
354370 err = jsoniter .Unmarshal (data , & reqDef .Response )
355371 }
@@ -387,8 +403,12 @@ func (hc *HcHttpClient) deserializeResponseBody(reqDef *def.HttpRequestDef, data
387403 } else {
388404 bodyIns = reflect .New (body .Type ).Interface ()
389405 }
390-
391- err := json .Unmarshal (data , bodyIns )
406+ var err error
407+ if reqDef .ContentType == applicationBson {
408+ err = bson .Unmarshal (data , bodyIns )
409+ } else {
410+ err = json .Unmarshal (data , bodyIns )
411+ }
392412 if err != nil {
393413 return err
394414 }
@@ -451,3 +471,27 @@ func (hc *HcHttpClient) getFieldInfo(reqDef *def.HttpRequestDef, item *def.Field
451471
452472 return isPtr , fieldKind
453473}
474+
475+ func isNoSuchHostErr (err error ) bool {
476+ if err == nil {
477+ return false
478+ }
479+ var errInterface interface {} = err
480+ if innerErr , ok := errInterface .(* url.Error ); ! ok {
481+ return false
482+ } else {
483+ errInterface = innerErr .Err
484+ }
485+
486+ if innerErr , ok := errInterface .(* net.OpError ); ! ok {
487+ return false
488+ } else {
489+ errInterface = innerErr .Err
490+ }
491+
492+ if innerErr , ok := errInterface .(* net.DNSError ); ! ok {
493+ return false
494+ } else {
495+ return innerErr .Err == "no such host"
496+ }
497+ }
0 commit comments