Update Curator to 5.3.0 (#12939)

* Update Curator to 5.3.0

* Update licenses.yaml

* Fix inspections + add tests.

* Fix checkstyle

* Another intellij inspection fix

* Update curator exclusions

* Cleanup new exhibitor references

* Remove unused dep and checkstyle fix
This commit is contained in:
Adam Peck 2022-08-26 19:23:40 -06:00 committed by GitHub
parent 4bdf9815c1
commit 21b73bde20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 60 additions and 364 deletions

View File

@ -151,23 +151,6 @@ The following path is used for service discovery. It is **not** affected by `dru
|--------|-----------|-------|
|`druid.discovery.curator.path`|Services announce themselves under this ZooKeeper path.|`/druid/discovery`|
### Exhibitor
[Exhibitor](https://github.com/Netflix/exhibitor/wiki) is a supervisor system for ZooKeeper.
Exhibitor can dynamically scale-up/down the cluster of ZooKeeper servers.
Druid can update self-owned list of ZooKeeper servers through Exhibitor without restarting.
That is, it allows Druid to keep the connections of Exhibitor-supervised ZooKeeper servers.
|Property|Description|Default|
|--------|-----------|-------|
|`druid.exhibitor.service.hosts`|A JSON array which contains the hostnames of Exhibitor instances. Please specify this property if you want to use Exhibitor-supervised cluster.|none|
|`druid.exhibitor.service.port`|The REST port used to connect to Exhibitor.|`8080`|
|`druid.exhibitor.service.restUriPath`|The path of the REST call used to get the server set.|`/exhibitor/v1/cluster/list`|
|`druid.exhibitor.service.useSsl`|Boolean flag for whether or not to use https protocol.|`false`|
|`druid.exhibitor.service.pollingMs`|How often to poll the exhibitors for the list|`10000`|
Note that `druid.zk.service.host` is used as a backup in case an Exhibitor instance can't be contacted and therefore should still be set.
### TLS
#### General Configuration

View File

@ -91,10 +91,6 @@
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>

View File

@ -19,11 +19,9 @@
package org.apache.druid.testsEx.cluster;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.framework.CuratorFramework;
import org.apache.druid.curator.CuratorConfig;
import org.apache.druid.curator.CuratorModule;
import org.apache.druid.curator.ExhibitorConfig;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.testsEx.config.ResolvedConfig;
import org.apache.druid.testsEx.config.ResolvedService.ResolvedZk;
@ -56,9 +54,7 @@ public class ZooKeeperClient
private void prepare()
{
CuratorConfig curatorConfig = clusterConfig.toCuratorConfig();
ExhibitorConfig exhibitorConfig = clusterConfig.toExhibitorConfig();
EnsembleProvider ensembleProvider = CuratorModule.createEnsembleProvider(curatorConfig, exhibitorConfig);
curatorFramework = CuratorModule.createCurator(curatorConfig, ensembleProvider);
curatorFramework = CuratorModule.createCurator(curatorConfig);
}
private void awaitReady()

View File

@ -22,7 +22,6 @@ package org.apache.druid.testsEx.config;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import org.apache.druid.curator.CuratorConfig;
import org.apache.druid.curator.ExhibitorConfig;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.testing.IntegrationTestingConfigProvider;
@ -37,7 +36,6 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@ -274,12 +272,6 @@ public class ResolvedConfig
return CuratorConfig.create(zk.clientHosts());
}
public ExhibitorConfig toExhibitorConfig()
{
// Does not yet support exhibitors
return ExhibitorConfig.create(Collections.emptyList());
}
/**
* Map from old-style config file (and settings) name to the
* corresponding property.

View File

@ -1662,7 +1662,7 @@ name: Apache Curator
license_category: binary
module: java-core
license_name: Apache License version 2.0
version: 4.3.0
version: 5.3.0
libraries:
- org.apache.curator: curator-client
- org.apache.curator: curator-framework
@ -1671,16 +1671,16 @@ libraries:
notices:
- curator-client: |
Curator Client
Copyright 2011-2018 The Apache Software Foundation
Copyright 2011-2022 The Apache Software Foundation
- curator-framework: |
Curator Framework
Copyright 2011-2018 The Apache Software Foundation
Copyright 2011-2022 The Apache Software Foundation
- curator-recipes: |
Curator Recipes
Copyright 2011-2018 The Apache Software Foundation
Copyright 2011-2022 The Apache Software Foundation
- curator-x-discovery: |
Curator Service Discovery
Copyright 2011-2018 The Apache Software Foundation
Copyright 2011-2022 The Apache Software Foundation
---

48
pom.xml
View File

@ -75,7 +75,7 @@
<java.version>8</java.version>
<project.build.resourceEncoding>UTF-8</project.build.resourceEncoding>
<aether.version>0.9.0.M2</aether.version>
<apache.curator.version>4.3.0</apache.curator.version>
<apache.curator.version>5.3.0</apache.curator.version>
<apache.kafka.version>3.2.0</apache.kafka.version>
<apache.ranger.version>2.0.0</apache.ranger.version>
<apache.ranger.gson.version>2.2.4</apache.ranger.gson.version>
@ -348,23 +348,15 @@
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${apache.curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${apache.curator.version}</version>
<exclusions>
<exclusion>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${apache.curator.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
@ -372,9 +364,25 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${apache.curator.version}</version>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${apache.curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${apache.curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${apache.curator.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.calcite</groupId>
@ -986,8 +994,8 @@
<version>${apache.curator.version}</version>
<exclusions>
<exclusion>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>

View File

@ -23,10 +23,6 @@ import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provides;
import org.apache.curator.RetryPolicy;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.ensemble.exhibitor.DefaultExhibitorRestClient;
import org.apache.curator.ensemble.exhibitor.ExhibitorEnsembleProvider;
import org.apache.curator.ensemble.exhibitor.Exhibitors;
import org.apache.curator.ensemble.fixed.FixedEnsembleProvider;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
@ -49,8 +45,8 @@ public class CuratorModule implements Module
{
private static final Logger log = new Logger(CuratorModule.class);
private static final int BASE_SLEEP_TIME_MS = 1000;
private static final int MAX_SLEEP_TIME_MS = 45000;
static final int BASE_SLEEP_TIME_MS = 1000;
static final int MAX_SLEEP_TIME_MS = 45000;
private static final int MAX_RETRIES = 29;
@Override
@ -58,14 +54,13 @@ public class CuratorModule implements Module
{
JsonConfigProvider.bind(binder, CuratorConfig.CONFIG_PREFIX, ZkEnablementConfig.class);
JsonConfigProvider.bind(binder, CuratorConfig.CONFIG_PREFIX, CuratorConfig.class);
JsonConfigProvider.bind(binder, ExhibitorConfig.CONFIG_PREFIX, ExhibitorConfig.class);
}
/**
* Create the Curator framework outside of Guice given the ZK config.
* Primarily for tests.
*/
public static CuratorFramework createCurator(CuratorConfig config, EnsembleProvider ensembleProvider)
public static CuratorFramework createCurator(CuratorConfig config)
{
final CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();
if (!Strings.isNullOrEmpty(config.getZkUser()) && !Strings.isNullOrEmpty(config.getZkPwd())) {
@ -78,7 +73,7 @@ public class CuratorModule implements Module
RetryPolicy retryPolicy = new BoundedExponentialBackoffRetry(BASE_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS, MAX_RETRIES);
return builder
.ensembleProvider(ensembleProvider)
.ensembleProvider(new FixedEnsembleProvider(config.getZkHosts()))
.sessionTimeoutMs(config.getZkSessionTimeoutMs())
.connectionTimeoutMs(config.getZkConnectionTimeoutMs())
.retryPolicy(retryPolicy)
@ -92,13 +87,13 @@ public class CuratorModule implements Module
*/
@Provides
@LazySingleton
public CuratorFramework makeCurator(ZkEnablementConfig zkEnablementConfig, CuratorConfig config, EnsembleProvider ensembleProvider, Lifecycle lifecycle)
public CuratorFramework makeCurator(ZkEnablementConfig zkEnablementConfig, CuratorConfig config, Lifecycle lifecycle)
{
if (!zkEnablementConfig.isEnabled()) {
throw new RuntimeException("Zookeeper is disabled, cannot create CuratorFramework.");
}
final CuratorFramework framework = createCurator(config, ensembleProvider);
final CuratorFramework framework = createCurator(config);
framework.getUnhandledErrorListenable().addListener((message, e) -> {
log.error(e, "Unhandled error in Curator, stopping server.");
@ -127,55 +122,6 @@ public class CuratorModule implements Module
return framework;
}
/**
* Create an EnsembleProvider given the related configurations. Primarily for tests
* which do not use Guice to do the work.
*/
public static EnsembleProvider createEnsembleProvider(CuratorConfig config, ExhibitorConfig exConfig)
{
if (exConfig.getHosts().isEmpty()) {
return new FixedEnsembleProvider(config.getZkHosts());
}
RetryPolicy retryPolicy = new BoundedExponentialBackoffRetry(BASE_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS, MAX_RETRIES);
return new ExhibitorEnsembleProvider(
new Exhibitors(
exConfig.getHosts(),
exConfig.getRestPort(),
newBackupProvider(config.getZkHosts())
),
new DefaultExhibitorRestClient(exConfig.getUseSsl()),
exConfig.getRestUriPath(),
exConfig.getPollingMs(),
retryPolicy
)
{
@Override
public void start() throws Exception
{
log.debug("Polling the list of ZooKeeper servers for the initial ensemble");
this.pollForInitialEnsemble();
super.start();
}
};
}
/**
* Provide an EnsembleProvider via Guice configuration.
*/
@Provides
@LazySingleton
public EnsembleProvider makeEnsembleProvider(CuratorConfig config, ExhibitorConfig exConfig)
{
return createEnsembleProvider(config, exConfig);
}
private static Exhibitors.BackupConnectionStringProvider newBackupProvider(final String zkHosts)
{
return () -> zkHosts;
}
static class SecuredACLProvider implements ACLProvider
{
@Override

View File

@ -1,86 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.druid.curator;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class ExhibitorConfig
{
static final String CONFIG_PREFIX = "druid.exhibitor.service";
@JsonProperty
private List<String> hosts = new ArrayList<>();
@JsonProperty("port")
@Min(0)
@Max(0xffff)
private int restPort = 8080;
@JsonProperty
private String restUriPath = "/exhibitor/v1/cluster/list";
@JsonProperty
private boolean useSsl = false;
@JsonProperty
@Min(0)
private int pollingMs = 10000;
public static ExhibitorConfig create(List<String> hosts)
{
ExhibitorConfig config = new ExhibitorConfig();
if (hosts != null) {
config.hosts = hosts;
}
return config;
}
public List<String> getHosts()
{
return hosts;
}
public int getRestPort()
{
return restPort;
}
public String getRestUriPath()
{
return restUriPath;
}
public boolean getUseSsl()
{
return useSsl;
}
public int getPollingMs()
{
return pollingMs;
}
}

View File

@ -31,7 +31,6 @@ import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.utils.CloseableExecutorService;
import org.apache.curator.utils.ZKPaths;
import org.apache.curator.x.discovery.DownInstancePolicy;
import org.apache.curator.x.discovery.InstanceFilter;
@ -69,6 +68,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
@ -416,12 +416,6 @@ public class DiscoveryModule implements Module
return this;
}
@Override
public ServiceCacheBuilder<T> executorService(CloseableExecutorService closeableExecutorService)
{
return this;
}
private static class NoopServiceCache<T> implements ServiceCache<T>
{
@Override
@ -436,6 +430,12 @@ public class DiscoveryModule implements Module
// nothing
}
@Override
public CountDownLatch startImmediate()
{
return null;
}
@Override
public void close()
{
@ -505,12 +505,6 @@ public class DiscoveryModule implements Module
{
return this;
}
@Override
public ServiceProviderBuilder<T> executorService(CloseableExecutorService closeableExecutorService)
{
return this;
}
}
private static class NoopServiceProvider<T> implements ServiceProvider<T>

View File

@ -278,7 +278,6 @@ public class CuratorInventoryManager<ContainerClass, InventoryClass>
// This close() call actually calls shutdownNow() on the executor registered with the Cache object, it
// better have its own executor or ignore shutdownNow() calls...
log.debug("Closing inventory cache for %s. Also removing listeners.", containerKey);
removed.getCache().getListenable().clear();
removed.getCache().close();
strategy.deadContainer(removed.getContainer());

View File

@ -23,8 +23,6 @@ import org.apache.druid.guice.JsonConfigTesterBase;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
public class CuratorConfigTest extends JsonConfigTesterBase<CuratorConfig>
{
@Test
@ -54,11 +52,4 @@ public class CuratorConfigTest extends JsonConfigTesterBase<CuratorConfig>
Assert.assertNull(config.getZkUser());
Assert.assertEquals("digest", config.getAuthScheme());
}
@Test
public void testExhibitorCreate()
{
ExhibitorConfig config = ExhibitorConfig.create(Arrays.asList("foo:2181", "bar:2181"));
Assert.assertEquals(2, config.getHosts().size());
}
}

View File

@ -20,10 +20,8 @@
package org.apache.druid.curator;
import com.google.inject.Injector;
import org.apache.curator.CuratorZookeeperClient;
import org.apache.curator.RetryPolicy;
import org.apache.curator.ensemble.EnsembleProvider;
import org.apache.curator.ensemble.exhibitor.ExhibitorEnsembleProvider;
import org.apache.curator.ensemble.fixed.FixedEnsembleProvider;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
import org.apache.curator.retry.ExponentialBackoffRetry;
@ -33,6 +31,8 @@ import org.apache.druid.testing.junit.LoggerCaptureRule;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
@ -44,10 +44,8 @@ import java.util.Properties;
public final class CuratorModuleTest
{
private static final String CURATOR_HOST_KEY = CuratorConfig.CONFIG_PREFIX + "." + CuratorConfig.HOST;
private static final String CURATOR_CONNECTION_TIMEOUT_MS_KEY =
CuratorConfig.CONFIG_PREFIX + "." + CuratorConfig.CONNECTION_TIMEOUT_MS;
private static final String EXHIBITOR_HOSTS_KEY = ExhibitorConfig.CONFIG_PREFIX + ".hosts";
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
@ -56,74 +54,19 @@ public final class CuratorModuleTest
public final LoggerCaptureRule logger = new LoggerCaptureRule(CuratorModule.class);
@Test
public void defaultEnsembleProvider()
public void createsCuratorFrameworkAsConfigured()
{
Injector injector = newInjector(new Properties());
injector.getInstance(CuratorFramework.class); // initialize related components
EnsembleProvider ensembleProvider = injector.getInstance(EnsembleProvider.class);
Assert.assertTrue(
"EnsembleProvider should be FixedEnsembleProvider",
ensembleProvider instanceof FixedEnsembleProvider
);
Assert.assertEquals(
"The connectionString should be 'localhost'",
"localhost", ensembleProvider.getConnectionString()
);
}
CuratorConfig config = CuratorConfig.create("myhost1:2888,myhost2:2888");
CuratorFramework curatorFramework = CuratorModule.createCurator(config);
CuratorZookeeperClient client = curatorFramework.getZookeeperClient();
@Test
public void fixedZkHosts()
{
Properties props = new Properties();
props.setProperty(CURATOR_HOST_KEY, "hostA");
Injector injector = newInjector(props);
Assert.assertEquals(config.getZkHosts(), client.getCurrentConnectionString());
Assert.assertEquals(config.getZkConnectionTimeoutMs(), client.getConnectionTimeoutMs());
injector.getInstance(CuratorFramework.class); // initialize related components
EnsembleProvider ensembleProvider = injector.getInstance(EnsembleProvider.class);
Assert.assertTrue(
"EnsembleProvider should be FixedEnsembleProvider",
ensembleProvider instanceof FixedEnsembleProvider
);
Assert.assertEquals(
"The connectionString should be 'hostA'",
"hostA", ensembleProvider.getConnectionString()
);
}
@Test
public void exhibitorEnsembleProvider()
{
Properties props = new Properties();
props.setProperty(CURATOR_HOST_KEY, "hostA");
props.setProperty(EXHIBITOR_HOSTS_KEY, "[\"hostB\"]");
Injector injector = newInjector(props);
injector.getInstance(CuratorFramework.class); // initialize related components
EnsembleProvider ensembleProvider = injector.getInstance(EnsembleProvider.class);
Assert.assertTrue(
"EnsembleProvider should be ExhibitorEnsembleProvider",
ensembleProvider instanceof ExhibitorEnsembleProvider
);
}
@Test
public void emptyExhibitorHosts()
{
Properties props = new Properties();
props.setProperty(CURATOR_HOST_KEY, "hostB");
props.setProperty(EXHIBITOR_HOSTS_KEY, "[]");
Injector injector = newInjector(props);
injector.getInstance(CuratorFramework.class); // initialize related components
EnsembleProvider ensembleProvider = injector.getInstance(EnsembleProvider.class);
Assert.assertTrue(
"EnsembleProvider should be FixedEnsembleProvider",
ensembleProvider instanceof FixedEnsembleProvider
);
Assert.assertEquals(
"The connectionString should be 'hostB'",
"hostB", ensembleProvider.getConnectionString()
);
MatcherAssert.assertThat(client.getRetryPolicy(), Matchers.instanceOf(BoundedExponentialBackoffRetry.class));
BoundedExponentialBackoffRetry retryPolicy = (BoundedExponentialBackoffRetry) client.getRetryPolicy();
Assert.assertEquals(CuratorModule.BASE_SLEEP_TIME_MS, retryPolicy.getBaseSleepTimeMs());
Assert.assertEquals(CuratorModule.MAX_SLEEP_TIME_MS, retryPolicy.getMaxSleepTimeMs());
}
@Test

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.druid.curator;
import org.apache.druid.guice.JsonConfigTesterBase;
import org.junit.Assert;
import org.junit.Test;
import java.util.List;
import java.util.Properties;
public class ExhibitorConfigTest extends JsonConfigTesterBase<ExhibitorConfig>
{
@Test
public void testSerde()
{
propertyValues.put(getPropertyKey("hosts"), "[\"hostA\",\"hostB\"]");
propertyValues.put(getPropertyKey("port"), "80");
propertyValues.put(getPropertyKey("restUriPath"), "/list");
propertyValues.put(getPropertyKey("useSsl"), "true");
propertyValues.put(getPropertyKey("pollingMs"), "1000");
testProperties.putAll(propertyValues);
configProvider.inject(testProperties, configurator);
ExhibitorConfig config = configProvider.get().get();
List<String> hosts = config.getHosts();
Assert.assertEquals(2, hosts.size());
Assert.assertTrue(hosts.contains("hostA"));
Assert.assertTrue(hosts.contains("hostB"));
Assert.assertEquals(80, config.getRestPort());
Assert.assertEquals("/list", config.getRestUriPath());
Assert.assertTrue(config.getUseSsl());
Assert.assertEquals(1000, config.getPollingMs());
}
@Test
public void defaultValues()
{
configProvider.inject(new Properties(), configurator);
ExhibitorConfig config = configProvider.get().get();
List<String> hosts = config.getHosts();
Assert.assertTrue(hosts.isEmpty());
Assert.assertEquals(8080, config.getRestPort());
Assert.assertEquals("/exhibitor/v1/cluster/list", config.getRestUriPath());
Assert.assertFalse(config.getUseSsl());
Assert.assertEquals(10000, config.getPollingMs());
}
}