public static void Execute(Action method, IRetryPolicy retryPolicy, IBackOffScheme backOffScheme, int numRetries = Constants.LoadBalancingHelperNumRetriesDefault)
        {
            int retryCount = 0;
            bool requestSuccess = false;
            while ((!requestSuccess) && (retryCount < numRetries))
            {
                try
                {
                    method();
                    requestSuccess = true;
                }
                catch (Exception ex)
                {
                    Trace.TraceError("\tAttempt {0} failed with exception {1} - {2}", retryCount, ex.GetType(), ex.Message);

                    retryCount++;
                    if ((retryCount < numRetries) && (retryPolicy.ShouldRetryAttempt(ex)))
                    {
                        var sleepInterval = backOffScheme.GetRetryInterval(retryCount);
                        if (sleepInterval != default (TimeSpan))
                        {
                            Trace.TraceInformation("\tWill retry after {0} milliseconds......", sleepInterval.TotalMilliseconds);
                            Thread.Sleep(sleepInterval);
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        public static void Execute(Action method, IRetryPolicy retryPolicy, IBackOffScheme backOffScheme, int numRetries = Constants.LoadBalancingHelperNumRetriesDefault)
        {
            int  retryCount     = 0;
            bool requestSuccess = false;

            while ((!requestSuccess) && (retryCount < numRetries))
            {
                try
                {
                    method();
                    requestSuccess = true;
                }
                catch (Exception ex)
                {
                    Trace.TraceError("\tAttempt {0} failed with exception {1} - {2}", retryCount, ex.GetType(), ex.Message);

                    retryCount++;
                    if ((retryCount < numRetries) && (retryPolicy.ShouldRetryAttempt(ex)))
                    {
                        var sleepInterval = backOffScheme.GetRetryInterval(retryCount);
                        if (sleepInterval != default(TimeSpan))
                        {
                            Trace.TraceInformation("\tWill retry after {0} milliseconds......", sleepInterval.TotalMilliseconds);
                            Thread.Sleep(sleepInterval);
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <CellSet> ScannerGetNextAsyncInternal(ScannerInformation scannerInfo, string alternativeEndpointBase = null)
        {
            scannerInfo.ArgumentNotNull("scannerInfo");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    using (
                        HttpWebResponse webResponse =
                            await GetRequestAsync(scannerInfo.TableName + "/scanner/" + scannerInfo.ScannerId, alternativeEndpointBase ?? Constants.RestEndpointBaseZero))
                    {
                        if (webResponse.StatusCode == HttpStatusCode.OK)
                        {
                            return(Serializer.Deserialize <CellSet>(webResponse.GetResponseStream()));
                        }

                        return(null);
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <bool> CreateTableAsyncInternal(TableSchema schema, string alternativeEndpointBase = null)
        {
            schema.ArgumentNotNull("schema");

            if (string.IsNullOrEmpty(schema.name))
            {
                throw new ArgumentException("schema.name was either null or empty!", "schema");
            }

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    using (HttpWebResponse webResponse = await PutRequestAsync(schema.name + "/schema", schema, alternativeEndpointBase))
                    {
                        if (webResponse.StatusCode == HttpStatusCode.Created)
                        {
                            return(true);
                        }

                        // table already exits
                        if (webResponse.StatusCode == HttpStatusCode.OK)
                        {
                            return(false);
                        }

                        // throw the exception otherwise
                        using (var output = new StreamReader(webResponse.GetResponseStream()))
                        {
                            string message = output.ReadToEnd();
                            throw new WebException(
                                      string.Format(
                                          "Couldn't create table {0}! Response code was: {1}, expected either 200 or 201! Response body was: {2}",
                                          schema.name,
                                          webResponse.StatusCode,
                                          message));
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
 private async Task <org.apache.hadoop.hbase.rest.protobuf.generated.Version> GetVersionAsyncInternal(string alternativeEndpointBase = null)
 {
     while (true)
     {
         IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
         try
         {
             return(await GetRequestAndDeserializeAsync <org.apache.hadoop.hbase.rest.protobuf.generated.Version>("version", alternativeEndpointBase));
         }
         catch (Exception e)
         {
             if (!retryPolicy.ShouldRetryAttempt(e))
             {
                 throw;
             }
         }
     }
 }
 private async Task <StorageClusterStatus> GetStorageClusterStatusAsyncInternal(string alternativeEndpointBase = null)
 {
     while (true)
     {
         IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
         try
         {
             return(await GetRequestAndDeserializeAsync <StorageClusterStatus>("/status/cluster", alternativeEndpointBase));
         }
         catch (Exception e)
         {
             if (!retryPolicy.ShouldRetryAttempt(e))
             {
                 throw;
             }
         }
     }
 }
        private async Task <TableList> ListTablesAsyncInternal(string alternativeEndpointBase = null)
        {
            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    return(await GetRequestAndDeserializeAsync <TableList>("", alternativeEndpointBase : alternativeEndpointBase));
                }

                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <ScannerInformation> CreateScannerAsyncInternal(string tableName, Scanner scannerSettings, string alternativeEndpointBase = null)
        {
            tableName.ArgumentNotNullNorEmpty("tableName");
            scannerSettings.ArgumentNotNull("scannerSettings");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    using (HttpWebResponse response = await PostRequestAsync(tableName + "/scanner", scannerSettings, alternativeEndpointBase ?? Constants.RestEndpointBaseZero))
                    {
                        if (response.StatusCode != HttpStatusCode.Created)
                        {
                            using (var output = new StreamReader(response.GetResponseStream()))
                            {
                                string message = output.ReadToEnd();
                                throw new WebException(
                                          string.Format(
                                              "Couldn't create a scanner for table {0}! Response code was: {1}, expected 201! Response body was: {2}",
                                              tableName,
                                              response.StatusCode,
                                              message));
                            }
                        }
                        string location = response.Headers.Get("Location");
                        if (location == null)
                        {
                            throw new ArgumentException("Couldn't find header 'Location' in the response!");
                        }
                        return(new ScannerInformation(new Uri(location), tableName));
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <TableSchema> GetTableSchemaAsyncInternal(string table, string alternativeEndpointBase = null)
        {
            table.ArgumentNotNullNorEmpty("table");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    return(await GetRequestAndDeserializeAsync <TableSchema>(table + "/schema", alternativeEndpointBase));
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task StoreCellsAsyncInternal(string table, CellSet cells, string alternativeEndpointBase = null)
        {
            table.ArgumentNotNullNorEmpty("table");
            cells.ArgumentNotNull("cells");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    // note the fake row key to insert a set of cells
                    using (HttpWebResponse webResponse = await PutRequestAsync(table + "/somefalsekey", cells, alternativeEndpointBase))
                    {
                        if (webResponse.StatusCode != HttpStatusCode.OK)
                        {
                            using (var output = new StreamReader(webResponse.GetResponseStream()))
                            {
                                string message = output.ReadToEnd();
                                throw new WebException(
                                          string.Format(
                                              "Couldn't insert into table {0}! Response code was: {1}, expected 200! Response body was: {2}",
                                              table,
                                              webResponse.StatusCode,
                                              message));
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task ModifyTableSchemaAsyncInternal(string table, TableSchema schema, string alternativeEndpointBase = null)
        {
            table.ArgumentNotNullNorEmpty("table");
            schema.ArgumentNotNull("schema");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    using (HttpWebResponse webResponse = await PostRequestAsync(table + "/schema", schema, alternativeEndpointBase))
                    {
                        if (webResponse.StatusCode != HttpStatusCode.OK || webResponse.StatusCode != HttpStatusCode.Created)
                        {
                            using (var output = new StreamReader(webResponse.GetResponseStream()))
                            {
                                string message = output.ReadToEnd();
                                throw new WebException(
                                          string.Format(
                                              "Couldn't modify table {0}! Response code was: {1}, expected either 200 or 201! Response body was: {2}",
                                              table,
                                              webResponse.StatusCode,
                                              message));
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        private async Task <CellSet> GetCellsAsyncInternal(string tableName, string rowKey, string alternativeEndpointBase = null)
        {
            // TODO add timestamp, versions and column queries
            tableName.ArgumentNotNullNorEmpty("tableName");
            rowKey.ArgumentNotNull("rowKey");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    return(await GetRequestAndDeserializeAsync <CellSet>(tableName + "/" + rowKey, alternativeEndpointBase));
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }
        public async Task DeleteTableAsyncInternal(string table, string alternativeEndpointBase = null)
        {
            table.ArgumentNotNullNorEmpty("table");

            while (true)
            {
                IRetryPolicy retryPolicy = _retryPolicyFactory.Create();
                try
                {
                    using (HttpWebResponse webResponse = await DeleteRequestAsync <TableSchema>(table + "/schema", null, alternativeEndpointBase))
                    {
                        if (webResponse.StatusCode != HttpStatusCode.OK)
                        {
                            using (var output = new StreamReader(webResponse.GetResponseStream()))
                            {
                                string message = output.ReadToEnd();
                                throw new WebException(
                                          string.Format(
                                              "Couldn't delete table {0}! Response code was: {1}, expected 200! Response body was: {2}",
                                              table,
                                              webResponse.StatusCode,
                                              message));
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (!retryPolicy.ShouldRetryAttempt(e))
                    {
                        throw;
                    }
                }
            }
        }