public void SetUp()
 {
     _loggerMock = new Mock <ILogger>();
     _retryHandlerOptionsMock = new Mock <IRetryHandlerOptions>();
     _sut   = new DefaultRetryHandler(_retryHandlerOptionsMock.Object, _loggerMock.Object);
     _count = 0;
 }
Example #2
0
 public LoadBalancerCommand(ILoadBalancer loadBalancer, IServerStatusCollector collector, IRetryHandler retryHandler, Server server)
 {
     RetryHandler = retryHandler;
     LoadBalancer = loadBalancer;
     Collector    = collector ?? new DefaultServerStatusCollector();
     _server      = server;
 }
Example #3
0
        public AlopeykClient(
            Uri remoteServiceUri,
            string token,
            HttpClient httpClient,
            IJsonSerializer jsonSerializer,
            IRetryHandler retryHandler
            )
        {
            if (remoteServiceUri is null)
            {
                throw new ArgumentNullException(nameof(remoteServiceUri));
            }
            if (httpClient is null)
            {
                throw new ArgumentNullException(nameof(httpClient));
            }
            if (jsonSerializer is null)
            {
                throw new ArgumentNullException(nameof(jsonSerializer));
            }

            RemoteServiceUri = remoteServiceUri;
            Token            = token;
            HttpClient       = httpClient;
            JsonSerializer   = jsonSerializer;
            RetryHandler     = retryHandler ?? Alopeyk.Net.RetryHandler.NoRetry.Value;
        }
Example #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SessionPool"/> class.
 /// </summary>
 /// <param name="sessionCreator">The method to create a new underlying QLDB session. The operation can be cancelled.</param>
 /// <param name="retryHandler">Handling the retry logic of the execute call.</param>
 /// <param name="maxConcurrentTransactions">The maximum number of sessions that can be created from the pool at any one time.</param>
 /// <param name="logger">Logger to be used by this.</param>
 public SessionPool(Func <CancellationToken, Task <Session> > sessionCreator, IRetryHandler retryHandler, int maxConcurrentTransactions, ILogger logger)
 {
     this.sessionPool    = new BlockingCollection <QldbSession>(maxConcurrentTransactions);
     this.poolPermits    = new SemaphoreSlim(maxConcurrentTransactions, maxConcurrentTransactions);
     this.sessionCreator = sessionCreator;
     this.retryHandler   = retryHandler;
     this.logger         = logger;
 }
Example #5
0
 public SpotifyClientConfig WithRetryHandler(IRetryHandler retryHandler)
 {
     return(new SpotifyClientConfig(
                BaseAddress,
                Authenticator,
                JSONSerializer,
                HTTPClient,
                retryHandler,
                HTTPLogger,
                DefaultPaginator
                ));
 }
Example #6
0
        /// <summary>
        ///     Determine whether the feed is public or private.
        /// </summary>
        /// <param name="feedUrl">Feed url to test</param>
        /// <returns>True if the feed is public, false if it is private, and null if it was not possible to determine.</returns>
        /// <remarks>
        /// Do an unauthenticated GET on the feed URL. If it succeeds, the feed is not public.
        /// If it fails with a 4* error, assume it is internal.
        /// </remarks>
        public static async Task <bool?> IsFeedPublicAsync(
            string feedUrl,
            HttpClient httpClient,
            TaskLoggingHelper log,
            IRetryHandler retryHandler)
        {
            bool?isPublic = null;

            bool success = await retryHandler.RunAsync(async attempt =>
            {
                try
                {
                    HttpResponseMessage response = await httpClient.GetAsync(feedUrl);
                    if (response.IsSuccessStatusCode)
                    {
                        isPublic = true;
                        return(true);
                    }
                    else if (response.StatusCode >= (System.Net.HttpStatusCode) 400 &&
                             response.StatusCode < (System.Net.HttpStatusCode) 500)
                    {
                        isPublic = false;
                        return(true);
                    }
                    else
                    {
                        // Don't know for certain, retry
                        return(false);
                    }
                }
                catch (Exception e)
                {
                    log.LogMessage(MessageImportance.Low, $"Unexpected exception {e.Message} when attempting to determine whether feed is internal.");
                    return(false);
                }
            });

            if (!success)
            {
                // We couldn't determine anything.  We'd be unlikely to be able to push to this feed either,
                // since it's 5xx'ing.
                log.LogError($"Unable to determine whether '{feedUrl}' is public or internal.");
            }

            return(isPublic);
        }
Example #7
0
 public LoadBalancerContext(ILoadBalancer loadBalancer, IRetryHandler retryHandler, string vipAddress)
     : this(loadBalancer, vipAddress)
 {
     RetryHandler = retryHandler;
 }
Example #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SessionPool"/> class.
 /// </summary>
 /// <param name="sessionCreator">The method to create a new underlying QLDB session.</param>
 /// <param name="retryHandler">Handling the retry logic of the execute call.</param>
 /// <param name="maxConcurrentTransactions">The maximum number of sessions that can be created from the pool at any one time.</param>
 /// <param name="logger">Logger to be used by this.</param>
 public SessionPool(Func <Task <Session> > sessionCreator, IRetryHandler retryHandler, int maxConcurrentTransactions, ILogger logger)
     : this(ct => sessionCreator(), retryHandler, maxConcurrentTransactions, logger)
 {
 }
Example #9
0
 public SubmitCompletionAsyncJob(ILogger <SubmitCompletionAsyncJob> logger, IRetryHandler retryHandler)
 {
     _logger       = logger;
     _retryHandler = retryHandler;
 }
Example #10
0
        /// <summary>
        ///     Determine whether a local package is the same as a package on an AzDO feed.
        /// </summary>
        /// <param name="localPackageFullPath"></param>
        /// <param name="packageContentUrl"></param>
        /// <param name="client"></param>
        /// <param name="log"></param>
        /// <param name="retryHandler"></param>
        /// <returns></returns>
        /// <remarks>
        ///     Open a stream to the local file and an http request to the package. There are a couple possibilities:
        ///     - The returned headers include a content MD5 header, in which case we can
        ///       hash the local file and just compare those.
        ///     - No content MD5 hash, and the streams must be compared in blocks. This is a bit trickier to do efficiently,
        ///       since we do not necessarily want to read all bytes if we can help it. Thus, we should compare in blocks.  However,
        ///       the streams make no guarantee that they will return a full block each time when read operations are performed, so we
        ///       must be sure to only compare the minimum number of bytes returned.
        /// </remarks>
        public static async Task <PackageFeedStatus> CompareLocalPackageToFeedPackage(
            string localPackageFullPath,
            string packageContentUrl,
            HttpClient client,
            TaskLoggingHelper log,
            IRetryHandler retryHandler)
        {
            log.LogMessage($"Getting package content from {packageContentUrl} and comparing to {localPackageFullPath}");

            PackageFeedStatus result = PackageFeedStatus.Unknown;

            bool success = await retryHandler.RunAsync(async attempt =>
            {
                try
                {
                    using (Stream localFileStream = File.OpenRead(localPackageFullPath))
                        using (HttpResponseMessage response = await client.GetAsync(packageContentUrl))
                        {
                            response.EnsureSuccessStatusCode();

                            // Check the headers for content length and md5
                            bool md5HeaderAvailable    = response.Headers.TryGetValues("Content-MD5", out var md5);
                            bool lengthHeaderAvailable = response.Headers.TryGetValues("Content-Length", out var contentLength);

                            if (lengthHeaderAvailable && long.Parse(contentLength.Single()) != localFileStream.Length)
                            {
                                log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different length than remote package '{packageContentUrl}'.");
                                result = PackageFeedStatus.ExistsAndDifferent;
                                return(true);
                            }

                            if (md5HeaderAvailable)
                            {
                                var localMD5 = AzureStorageUtils.CalculateMD5(localPackageFullPath);
                                if (!localMD5.Equals(md5.Single(), StringComparison.OrdinalIgnoreCase))
                                {
                                    log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different MD5 hash than remote package '{packageContentUrl}'.");
                                }

                                result = PackageFeedStatus.ExistsAndDifferent;
                                return(true);
                            }

                            const int BufferSize = 64 * 1024;

                            // Otherwise, compare the streams
                            var remoteStream = await response.Content.ReadAsStreamAsync();
                            var streamsMatch = await GeneralUtils.CompareStreamsAsync(localFileStream, remoteStream, BufferSize);
                            result           = streamsMatch ? PackageFeedStatus.ExistsAndIdenticalToLocal : PackageFeedStatus.ExistsAndDifferent;
                            return(true);
                        }
                }
                // String based comparison because the status code isn't exposed in HttpRequestException
                // see here: https://github.com/dotnet/runtime/issues/23648
                catch (HttpRequestException e)
                {
                    if (e.Message.Contains("404 (Not Found)"))
                    {
                        result = PackageFeedStatus.DoesNotExist;
                        return(true);
                    }

                    // Retry this. Could be an http client timeout, 500, etc.
                    return(false);
                }
            });

            return(result);
        }
 public DefaultFileSystemService(ILogger <IFileService> logger, IRetryHandler retryHandler, IRetryHandlerOptions retryHandlerOptions)
 {
     _logger              = logger;
     _retryHandler        = retryHandler;
     _retryHandlerOptions = retryHandlerOptions;
 }