Beispiel #1
0
        void SendAsync <T>(HttpRequestMessage request, ServiceRequest serviceRequest, Action <ServiceRequest.Response <T> > completedhandler)
        {
            // Send async
            SdkLogger.Instance.Info($"http request[{request.Method}]: {request.RequestUri}");
            var task = Client.SendAsync(request);

            // Process Response and Callback
            task.ContinueWith(t =>
            {
                // parse the response
                var response = t.Result;
                SdkLogger.Instance.Info($"http response[{response.StatusCode}]: {response.ReasonPhrase}");

                var outputResponse = new ServiceRequest.Response <T>
                {
                    StatusCode        = (int)response.StatusCode,
                    StatusDescription = response.ReasonPhrase,
                    Headers           = new List <KeyValuePair <string, object> >(),
                };

                // parse response headers
                ParseResponseHeaders <T>(response, ref outputResponse);

                // parse response content
                ParseResponseContent <T>(serviceRequest, response, ref outputResponse);

                // call back
                completedhandler.Invoke(outputResponse);
            });
        }
        private void HandleResponse429TooManyRequests <T>(bool isAuthProcess, ServiceRequest.Response <T> resp, Action <WebexApiEventArgs <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 WebexApiEventArgs <T>(false, new WebexError(WebexErrorCode.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.");
            TimerHelper.StartTimer(retryAfter * 1000, (o, e) =>
            {
                m429RetryCount++;
                SdkLogger.Instance.Debug("429 retry began.");
                if (isAuthProcess)
                {
                    ExecuteAuth <T>(completedhandler);
                }
                else
                {
                    Execute <T>(completedhandler);
                }
            });
        }
Beispiel #3
0
 void ParseResponseHeaders <T>(HttpResponseMessage response, ref ServiceRequest.Response <T> outputResponse)
 {
     if (response.Headers != null && response.Headers.Any())
     {
         foreach (var item in response.Headers.ToList())
         {
             if (item.Value != null)
             {
                 foreach (var v in item.Value)
                 {
                     outputResponse.Headers.Add(new KeyValuePair <string, object>(item.Key, v));
                 }
             }
         }
     }
 }
 private void HandleAuthResponse <T>(ServiceRequest.Response <T> resp, Action <WebexApiEventArgs <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 WebexApiEventArgs <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 WebexApiEventArgs <T>(false, new WebexError(WebexErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T)));
     }
 }
        private int GetRetryAfterValue <T>(ServiceRequest.Response <T> resp) where T : new()
        {
            int retryAfter;

            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 <WebexApiEventArgs <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 WebexApiEventArgs <T>(false, new WebexError(WebexErrorCode.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 WebexApiEventArgs <T>(false, new WebexError(WebexErrorCode.ServiceFailed, resp.StatusCode.ToString()), default(T)));
                }
            });
        }
Beispiel #7
0
        void ParseResponseContent <T>(ServiceRequest serviceRequest, HttpResponseMessage response, ref ServiceRequest.Response <T> outputResponse)
        {
            if (!response.IsSuccessStatusCode)
            {
                SdkLogger.Instance.Error($"http response[{response.StatusCode}]: {response.ReasonPhrase}");
                return;
            }
            if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
            {
                return;
            }
            var result = response.Content.ReadAsStringAsync().Result;

            if (result != null && result.Length > 0)
            {
                var ser = new JavaScriptSerializer();
                if (serviceRequest.RootElement != null && serviceRequest.RootElement.Length > 0)
                {
                    try
                    {
                        dynamic parsedResult = ser.Deserialize <object>(result);
                        outputResponse.Data = ser.ConvertToType <T>(parsedResult[serviceRequest.RootElement]);
                    }
                    catch (Exception e)
                    {
                        SdkLogger.Instance.Error($"deserialize with root element exception: {e.GetType()}");
                    }
                }
                else
                {
                    try
                    {
                        outputResponse.Data = ser.Deserialize <T>(result);
                    }
                    catch (Exception e)
                    {
                        SdkLogger.Instance.Error($"deserialize without element exception: {e.GetType()}");
                    }
                }
            }
        }
        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 Webex 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>
                {
                    StatusCode        = (int)response.StatusCode,
                    StatusDescription = response.StatusDescription,
                    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);
            });
        }