private void HandleResponse429TooManyRequests <T>(bool isAuthProcess, ServiceRequest.Response <T> resp, Action <SparkApiEventArgs <T> > completedhandler) where T : new() { if (MAX_429_RETRIES != 0 && m429RetryCount >= MAX_429_RETRIES) { SDKLogger.Instance.Warn($"429 retry exceed MAX_429_RETRIES[{MAX_429_RETRIES}] times."); completedhandler?.Invoke(new SparkApiEventArgs <T>(false, new SparkError(SparkErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T))); return; } int retryAfter = GetRetryAfterValue(resp); // start timer after retryAfter seconds and retry request SDKLogger.Instance.Debug($"start timer: {retryAfter} seconds."); m429RetryAfterTimer = TimerHelper.StartTimer(retryAfter * 1000, (o, e) => { m429RetryCount++; SDKLogger.Instance.Debug("429 retry began."); if (isAuthProcess) { ExecuteAuth <T>(completedhandler); } else { Execute <T>(completedhandler); } }); }
private void HandleAuthResponse <T>(ServiceRequest.Response <T> resp, Action <SparkApiEventArgs <T> > completedhandler) where T : new() { SDKLogger.Instance.Debug($"http response: {resp.StatusCode}"); if (resp.StatusCode >= 200 && resp.StatusCode < 300) { SDKLogger.Instance.Info("http response success"); completedhandler?.Invoke(new SparkApiEventArgs <T>(true, null, resp.Data)); } else if (429 == resp.StatusCode && IsEligibleFor429Retry) { HandleResponse429TooManyRequests(true, resp, completedhandler); } else { SDKLogger.Instance.Error($"http response error: {resp.StatusCode}"); completedhandler?.Invoke(new SparkApiEventArgs <T>(false, new SparkError(SparkErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T))); } return; }
private int GetRetryAfterValue <T>(ServiceRequest.Response <T> resp) where T : new() { int retryAfter = DEFAULT_RETRYAFTER_SECONDS; try { var r = resp.Headers.Find(x => x.Key == "Retry-After"); SDKLogger.Instance.Debug($"RCV 429, retry_after value: {(int)r.Value} seconds."); retryAfter = (int)r.Value > MAX_RETRYAFTER_SECONDS ? MAX_RETRYAFTER_SECONDS : (int)r.Value; retryAfter = retryAfter <= 0 ? DEFAULT_RETRYAFTER_SECONDS : retryAfter; } catch { SDKLogger.Instance.Debug($"In 429 response, there is no Retry-After header. Set default value[{DEFAULT_RETRYAFTER_SECONDS}] seconds."); retryAfter = DEFAULT_RETRYAFTER_SECONDS; } return(retryAfter); }
private void HandleResponse401UnAuthorized <T>(ServiceRequest.Response <T> resp, Action <SparkApiEventArgs <T> > completedhandler) where T : new() { if (m401RetryCount >= MAX_401_RETRIES) { SDKLogger.Instance.Warn($"401 refresh retry exceed MAX_401_RETRIES[{MAX_401_RETRIES}] times."); completedhandler?.Invoke(new SparkApiEventArgs <T>(false, new SparkError(SparkErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T))); return; } m401RetryCount++; Authenticator?.RefreshToken(r => { if (r.IsSuccess) { SDKLogger.Instance.Debug("401 refresh token success and began to retry."); Execute <T>(completedhandler); } else { SDKLogger.Instance.Error("401 refresh token fail."); completedhandler?.Invoke(new SparkApiEventArgs <T>(false, new SparkError(SparkErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T))); } }); }
public void Execute <T>(ServiceRequest serviceRequest, Action <ServiceRequest.Response <T> > completedhandler) where T : new() { if (serviceRequest == null) { SDKLogger.Instance.Error("serviceRequest is null."); completedhandler?.Invoke(new ServiceRequest.Response <T>() { StatusCode = 0 }); return; } RestRequest request = new RestRequest(serviceRequest.Resource, (Method)serviceRequest.Method); if (serviceRequest.AccessToken != null) { request.AddHeader("Authorization", "Bearer " + serviceRequest.AccessToken); } foreach (var pair in serviceRequest.Headers) { request.AddHeader(pair.Key, pair.Value); } foreach (var pair in serviceRequest.QueryParameters) { request.AddParameter(pair.Key, pair.Value, ParameterType.GetOrPost); } foreach (var pair in serviceRequest.BodyParameters) { request.AddParameter(pair.Key, pair.Value, ParameterType.GetOrPost); } if (serviceRequest.RootElement.Length != 0) { request.RootElement = serviceRequest.RootElement; } //Cisco Spark platform is dropping support for TLS 1.0 as of March 16, 2018 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11; var client = new RestClient() { BaseUrl = new System.Uri(serviceRequest.BaseUri) }; SDKLogger.Instance.Info($"http request[{serviceRequest.Method.ToString()}]: {serviceRequest.BaseUri + request.Resource}"); client.ExecuteAsync <T>(request, response => { var r = new ServiceRequest.Response <T>(); r.StatusCode = (int)response.StatusCode; r.StatusDescription = response.StatusDescription; r.Headers = new List <KeyValuePair <string, object> >(); foreach (var i in response.Headers) { r.Headers.Add(new KeyValuePair <string, object>(i.Name, i.Value)); } r.Data = response.Data; completedhandler?.Invoke(r); }); }