/// <param name="exhibitors">
 ///     the current set of exhibitor instances (can be changed later via
 ///     <seealso cref="#setExhibitors(Exhibitors)" />)
 /// </param>
 /// <param name="restClient"> the rest client to use (use <seealso cref="DefaultExhibitorRestClient" /> for most cases) </param>
 /// <param name="restUriPath">
 ///     the path of the REST call used to get the server set. Usually:
 ///     <code>/exhibitor/v1/cluster/list</code>
 /// </param>
 /// <param name="pollingMs"> how ofter to poll the exhibitors for the list </param>
 /// <param name="retryPolicy"> retry policy to use when connecting to the exhibitors </param>
 public ExhibitorEnsembleProvider(Exhibitors exhibitors, ExhibitorRestClient restClient, string restUriPath,
     int pollingMs, RetryPolicy retryPolicy)
 {
     this.exhibitors.set(exhibitors);
     masterExhibitors.set(exhibitors);
     this.restClient = restClient;
     this.restUriPath = restUriPath;
     this.pollingMs = pollingMs;
     this.retryPolicy = retryPolicy;
 }
        private IDictionary<string, string> useBackup(Exhibitors localExhibitors)
        {
            var values = newValues();

            try
            {
                var backupConnectionString = localExhibitors.getBackupConnectionString();

                var thePort = -1;
                var count = 0;
                foreach (var spec in backupConnectionString.Split(",", true))
                {
                    spec = spec.Trim();
                    var parts = spec.Split(":", true);
                    if (parts.Length == 2)
                    {
                        var hostname = parts[0];
                        var port = int.Parse(parts[1]);
                        if (thePort < 0)
                        {
                            thePort = port;
                        }
                        else if (port != thePort)
                        {
                            log.warn("Inconsistent port in connection component: " + spec);
                        }
                        values[VALUE_SERVER_PREFIX + count] = hostname;
                        ++count;
                    }
                    else
                    {
                        log.warn("Bad backup connection component: " + spec);
                    }
                }
                values[VALUE_COUNT] = Convert.ToString(count);
                values[VALUE_PORT] = Convert.ToString(thePort);
            }
            catch (Exception e)
            {
                log.error("Couldn't get backup connection string", e);
            }
            return values;
        }
        //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
        //ORIGINAL LINE: @VisibleForTesting protected void poll()
        protected internal virtual void poll()
        {
            Exhibitors localExhibitors = exhibitors.get();
            var values = queryExhibitors(localExhibitors);

            var count = getCountFromValues(values);
            if (count == 0)
            {
                log.warn("0 count returned from Exhibitors. Using backup connection values.");
                values = useBackup(localExhibitors);
                count = getCountFromValues(values);
            }

            if (count > 0)
            {
                var port = int.Parse(values[VALUE_PORT]);
                var newConnectionString = new StringBuilder();
                IList<string> newHostnames = Lists.newArrayList();

                for (var i = 0; i < count; ++i)
                {
                    if (newConnectionString.Length > 0)
                    {
                        newConnectionString.Append(",");
                    }
                    var server = values[VALUE_SERVER_PREFIX + i];
                    newConnectionString.Append(server).Append(":").Append(port);
                    newHostnames.Add(server);
                }

                var newConnectionStringValue = newConnectionString.ToString();
                if (!newConnectionStringValue.Equals(connectionString.get()))
                {
                    log.info(string.Format("Connection string has changed. Old value ({0}), new value ({1})",
                        connectionString.get(), newConnectionStringValue));
                }
                var newExhibitors = new Exhibitors(newHostnames, localExhibitors.getRestPort(),
                    new BackupConnectionStringProviderAnonymousInnerClassHelper(this));
                connectionString.set(newConnectionStringValue);
                exhibitors.set(newExhibitors);
            }
        }
        private IDictionary<string, string> queryExhibitors(Exhibitors localExhibitors)
        {
            var values = newValues();

            var start = TimeHelper.ElapsedMiliseconds;
            var retries = 0;
            var done = false;
            while (!done)
            {
                IList<string> hostnames = Lists.newArrayList(localExhibitors.getHostnames());
                if (hostnames.Count == 0)
                {
                    done = true;
                }
                else
                {
                    var hostname = hostnames[random.Next(hostnames.Count)];
                    try
                    {
                        var encoded = restClient.getRaw(hostname, localExhibitors.getRestPort(), restUriPath, MIME_TYPE);
            //JAVA TO C# CONVERTER TODO TASK: There is no .NET Dictionary equivalent to the Java 'putAll' method:
                        values.putAll(decodeExhibitorList(encoded));
                        done = true;
                    }
                    catch (Exception e)
                    {
                        if (retryPolicy.allowRetry(retries++, TimeHelper.ElapsedMiliseconds - start,
                            RetryLoop.getDefaultRetrySleeper()))
                        {
                            log.warn("Couldn't get servers from Exhibitor. Retrying.", e);
                        }
                        else
                        {
                            log.error("Couldn't get servers from Exhibitor. Giving up.", e);
                            done = true;
                        }
                    }
                }
            }

            return values;
        }
 /// <summary>
 ///     Change the set of exhibitors to poll
 /// </summary>
 /// <param name="newExhibitors"> new set </param>
 public virtual void setExhibitors(Exhibitors newExhibitors)
 {
     exhibitors.set(newExhibitors);
     masterExhibitors.set(newExhibitors);
 }