2222using System ;
2323using System . Collections . Generic ;
2424using System . Linq ;
25+ using System . Net ;
2526using System . Net . Http ;
27+ using System . Runtime . CompilerServices ;
28+ using System . Threading ;
2629using System . Threading . Tasks ;
2730using G42Cloud . SDK . Core . Auth ;
2831using Microsoft . Extensions . Logging ;
@@ -34,7 +37,10 @@ public class Client
3437 {
3538 public class ClientBuilder < T > where T : Client
3639 {
37- private string [ ] CredentialType { get ; } = { nameof ( BasicCredentials ) } ;
40+ private string [ ] CredentialType { get ; } =
41+ {
42+ nameof ( BasicCredentials )
43+ } ;
3844
3945 public ClientBuilder ( )
4046 {
@@ -48,7 +54,7 @@ public ClientBuilder(string credentialType)
4854 private Credentials _credentials ;
4955 private HttpConfig _httpConfig ;
5056 private Region _region ;
51- private string _endPoint ;
57+ private List < string > _endpoints ;
5258 private bool _enableLogging ;
5359 private LogLevel _logLevel = LogLevel . Information ;
5460 private HttpHandler _httpHandler ;
@@ -74,10 +80,19 @@ public ClientBuilder<T> WithRegion(Region region)
7480 this . _region = region ;
7581 return this ;
7682 }
83+
84+ [ Obsolete ( "As of 3.1.26, because of the support of the multi-endpoint feature, use WithEndPoints instead" ) ]
85+ public ClientBuilder < T > WithEndPoint ( string endpoint )
86+ {
87+ return this . WithEndPoints ( new List < string >
88+ {
89+ endpoint
90+ } ) ;
91+ }
7792
78- public ClientBuilder < T > WithEndPoint ( string endPoint )
93+ public ClientBuilder < T > WithEndPoints ( List < string > endpoints )
7994 {
80- this . _endPoint = endPoint ;
95+ this . _endpoints = endpoints ;
8196 return this ;
8297 }
8398
@@ -120,24 +135,29 @@ public T Build()
120135
121136 if ( this . _region != null )
122137 {
123- this . _endPoint = _region . Endpoint ;
138+ this . _endpoints = this . _region . Endpoints ;
124139 this . _credentials = _credentials . ProcessAuthParams ( client . _sdkHttpClient , _region . Id ) ;
125140 this . _credentials . ProcessDerivedAuthParams ( _derivedAuthServiceName , _region . Id ) ;
126141 }
127142
128- if ( ! _endPoint . StartsWith ( HttpScheme ) )
143+ for ( var i = 0 ; i < _endpoints . Count ; i ++ )
129144 {
130- _endPoint = HttpsScheme + "://" + _endPoint ;
145+ var endpoint = _endpoints [ i ] ;
146+ if ( ! endpoint . StartsWith ( HttpScheme ) )
147+ {
148+ _endpoints [ i ] = HttpsScheme + "://" + endpoint ;
149+ }
131150 }
132151
133152 client . WithCredential ( this . _credentials )
134- . WithEndPoint ( this . _endPoint ) ;
153+ . WithEndPoints ( this . _endpoints ) ;
135154
136- return ( T ) client ;
155+ return ( T ) client ;
137156 }
138157 }
139158
140- private string _endpoint ;
159+ private List < string > _endpoints ;
160+ private volatile int _endpointIndex ;
141161 private HttpConfig _httpConfig ;
142162 private Credentials _credential ;
143163
@@ -158,12 +178,13 @@ private Client WithHttpConfig(HttpConfig httpConfig)
158178 return this ;
159179 }
160180
161- private Client WithEndPoint ( string endPoint )
181+ private Client WithEndPoints ( List < string > endpoints )
162182 {
163- this . _endpoint = endPoint ;
183+ this . _endpoints = endpoints ;
164184 return this ;
165185 }
166186
187+
167188 private void InitSdkHttpClient ( HttpHandler httpHandler , bool enableLogging , LogLevel logLevel )
168189 {
169190 this . _sdkHttpClient =
@@ -194,16 +215,33 @@ private async Task<HttpResponseMessage> _async_http(string url, string method, S
194215 }
195216 catch ( AggregateException aggregateException )
196217 {
197- throw new ConnectionException ( ExceptionUtils . GetMessageFromAggregateException ( aggregateException ) ) ;
218+ throw ExceptionUtils . HandleException ( aggregateException ) ;
198219 }
199220 }
200221
222+ [ MethodImpl ( MethodImplOptions . Synchronized ) ]
201223 protected HttpResponseMessage DoHttpRequestSync ( string methodType , SdkRequest request )
202224 {
203- var url = GetRealEndpoint ( request )
204- + HttpUtils . AddUrlPath ( request . Path , _credential . GetPathParamDictionary ( ) )
205- + ( IsNullOrEmpty ( request . QueryParams ) ? "" : "?" + request . QueryParams ) ;
206- return _sync_http ( url , methodType . ToUpper ( ) , request ) ;
225+ while ( true )
226+ {
227+ var url = GetRealEndpoint ( request ) + HttpUtils . AddUrlPath ( request . Path , _credential . GetPathParamDictionary ( ) )
228+ + ( IsNullOrEmpty ( request . QueryParams ) ? "" : "?" + request . QueryParams ) ;
229+ try
230+ {
231+ return _sync_http ( url , methodType . ToUpper ( ) , request ) ;
232+ }
233+ catch ( HostUnreachableException hostUnreachableException )
234+ {
235+ if ( this . _endpointIndex < this . _endpoints . Count - 1 )
236+ {
237+ Interlocked . Increment ( ref _endpointIndex ) ;
238+ }
239+ else
240+ {
241+ throw hostUnreachableException ;
242+ }
243+ }
244+ }
207245 }
208246
209247 private HttpResponseMessage _sync_http ( string url , string method , SdkRequest sdkRequest )
@@ -222,23 +260,24 @@ private HttpResponseMessage _sync_http(string url, string method, SdkRequest sdk
222260 }
223261 catch ( AggregateException aggregateException )
224262 {
225- throw new ConnectionException ( ExceptionUtils . GetMessageFromAggregateException ( aggregateException ) ) ;
263+ throw ExceptionUtils . HandleException ( aggregateException ) ;
226264 }
227265 }
228266
229267 private string GetRealEndpoint ( SdkRequest request )
230268 {
269+ var endpoint = this . _endpoints [ _endpointIndex ] ;
231270 if ( String . IsNullOrEmpty ( request . Cname ) )
232271 {
233- return _endpoint ;
272+ return endpoint ;
234273 }
235274
236- return _endpoint . Insert ( 8 , request . Cname + "." ) ;
237- }
275+ return endpoint . Insert ( 8 , request . Cname + "." ) ;
276+ }
238277
239278 private HttpResponseMessage GetResult ( HttpResponseMessage responseMessage )
240279 {
241- if ( ( int ) responseMessage . StatusCode < 400 )
280+ if ( ( int ) responseMessage . StatusCode < 400 )
242281 {
243282 return responseMessage ;
244283 }
@@ -274,4 +313,4 @@ private void UpdateHeaders(HttpRequest request, Dictionary<string, string> heade
274313 request . Headers . Add ( XRequestAgent , "g42cloud-usdk-net/3.0" ) ;
275314 }
276315 }
277- }
316+ }
0 commit comments