0
# Ensemble Providers
1
2
Connection string providers for static and dynamic ZooKeeper cluster configuration. Ensemble providers abstract the source of ZooKeeper connection strings, enabling both fixed configurations and dynamic service discovery patterns.
3
4
## Capabilities
5
6
### EnsembleProvider Interface
7
8
Core interface for providing ZooKeeper connection strings, supporting both static and dynamic ensemble configurations.
9
10
```java { .api }
11
/**
12
* Interface for providing ZooKeeper connection strings
13
*/
14
public interface EnsembleProvider extends Closeable {
15
/**
16
* Start the ensemble provider
17
* @throws Exception if provider cannot be started
18
*/
19
void start() throws Exception;
20
21
/**
22
* Get current ZooKeeper connection string
23
* @return Connection string in format "host1:port1,host2:port2,..."
24
*/
25
String getConnectionString();
26
27
/**
28
* Close the ensemble provider and release resources
29
* @throws IOException if close operation fails
30
*/
31
void close() throws IOException;
32
33
/**
34
* Set a new connection string (for providers that support updates)
35
* @param connectionString New connection string to use
36
*/
37
void setConnectionString(String connectionString);
38
39
/**
40
* Check if this provider supports server list updates
41
* @return true if provider can update server list dynamically
42
*/
43
boolean updateServerListEnabled();
44
}
45
```
46
47
### Fixed Ensemble Provider
48
49
Static ensemble provider that uses a fixed connection string, ideal for stable cluster configurations.
50
51
```java { .api }
52
/**
53
* Ensemble provider with fixed connection string
54
*/
55
public class FixedEnsembleProvider implements EnsembleProvider {
56
/**
57
* Create fixed ensemble provider with connection string
58
* @param connectionString ZooKeeper connection string
59
*/
60
public FixedEnsembleProvider(String connectionString);
61
62
/**
63
* Create fixed ensemble provider with connection string and update flag
64
* @param connectionString ZooKeeper connection string
65
* @param updateServerListEnabled Whether server list updates are enabled
66
*/
67
public FixedEnsembleProvider(String connectionString, boolean updateServerListEnabled);
68
}
69
```
70
71
**Usage Examples:**
72
73
```java
74
import org.apache.curator.ensemble.fixed.FixedEnsembleProvider;
75
import org.apache.curator.CuratorZookeeperClient;
76
import org.apache.curator.retry.ExponentialBackoffRetry;
77
78
// Basic fixed ensemble
79
EnsembleProvider ensemble = new FixedEnsembleProvider("zk1:2181,zk2:2181,zk3:2181");
80
81
// Create client with ensemble provider
82
CuratorZookeeperClient client = new CuratorZookeeperClient(
83
ensemble,
84
5000, // session timeout
85
5000, // connection timeout
86
null, // watcher
87
new ExponentialBackoffRetry(1000, 3)
88
);
89
90
try {
91
ensemble.start();
92
client.start();
93
// ... use client ...
94
} finally {
95
client.close();
96
ensemble.close();
97
}
98
```
99
100
### Exhibitor Ensemble Provider
101
102
Dynamic ensemble provider that integrates with Netflix Exhibitor for automatic ZooKeeper cluster discovery and monitoring.
103
104
```java { .api }
105
/**
106
* Ensemble provider that uses Netflix Exhibitor for dynamic ensemble discovery
107
*/
108
public class ExhibitorEnsembleProvider implements EnsembleProvider {
109
/**
110
* Create Exhibitor-based ensemble provider
111
* @param exhibitors Collection of Exhibitor instances
112
* @param restClient REST client for Exhibitor communication
113
* @param pollingMs Polling interval in milliseconds for ensemble updates
114
*/
115
public ExhibitorEnsembleProvider(Exhibitors exhibitors, ExhibitorRestClient restClient, int pollingMs);
116
117
/**
118
* Create Exhibitor ensemble provider with backup connection string
119
* @param exhibitors Collection of Exhibitor instances
120
* @param restClient REST client for Exhibitor communication
121
* @param backup Backup connection string provider
122
* @param pollingMs Polling interval for ensemble updates
123
*/
124
public ExhibitorEnsembleProvider(Exhibitors exhibitors, ExhibitorRestClient restClient,
125
BackupConnectionStringProvider backup, int pollingMs);
126
}
127
```
128
129
### Exhibitor Configuration Classes
130
131
Supporting classes for configuring and managing Exhibitor-based ensemble discovery.
132
133
```java { .api }
134
/**
135
* Collection of Exhibitor instances for ensemble discovery
136
*/
137
public class Exhibitors {
138
/**
139
* Create Exhibitors collection
140
* @param hostnames Collection of Exhibitor hostnames
141
* @param restPort REST port for Exhibitor communication
142
* @param backupConnectionStringProvider Backup connection string provider
143
*/
144
public Exhibitors(Collection<String> hostnames, int restPort,
145
BackupConnectionStringProvider backupConnectionStringProvider);
146
147
/**
148
* Get backup connection string provider
149
* @return Backup connection string provider
150
*/
151
public BackupConnectionStringProvider getBackupConnectionStringProvider();
152
153
/**
154
* Get Exhibitor hostnames
155
* @return Collection of hostnames
156
*/
157
public Collection<String> getHostnames();
158
159
/**
160
* Get REST port for Exhibitor communication
161
* @return REST port number
162
*/
163
public int getRestPort();
164
}
165
166
/**
167
* Interface for REST client communication with Exhibitor
168
*/
169
public interface ExhibitorRestClient {
170
/**
171
* Make raw REST request to Exhibitor
172
* @param hostname Exhibitor hostname
173
* @param port Exhibitor port
174
* @param uriPath URI path for the request
175
* @param mimeType Expected MIME type of response
176
* @return Raw response string
177
* @throws Exception if request fails
178
*/
179
String getRaw(String hostname, int port, String uriPath, String mimeType) throws Exception;
180
}
181
182
/**
183
* Default implementation of ExhibitorRestClient
184
*/
185
public class DefaultExhibitorRestClient implements ExhibitorRestClient {
186
/**
187
* Create default REST client with connection timeout
188
* @param connectionTimeoutMs Connection timeout in milliseconds
189
*/
190
public DefaultExhibitorRestClient(int connectionTimeoutMs);
191
192
/**
193
* Create default REST client with custom socket timeout
194
* @param connectionTimeoutMs Connection timeout in milliseconds
195
* @param socketTimeoutMs Socket timeout in milliseconds
196
*/
197
public DefaultExhibitorRestClient(int connectionTimeoutMs, int socketTimeoutMs);
198
}
199
```
200
201
**Usage Examples:**
202
203
```java
204
import org.apache.curator.ensemble.exhibitor.*;
205
import java.util.Arrays;
206
207
// Configure Exhibitor instances
208
Exhibitors exhibitors = new Exhibitors(
209
Arrays.asList("exhibitor1.example.com", "exhibitor2.example.com"),
210
8080,
211
() -> "fallback1:2181,fallback2:2181" // Backup connection string
212
);
213
214
// Create REST client
215
ExhibitorRestClient restClient = new DefaultExhibitorRestClient(5000);
216
217
// Create dynamic ensemble provider
218
ExhibitorEnsembleProvider ensembleProvider = new ExhibitorEnsembleProvider(
219
exhibitors,
220
restClient,
221
10000 // Poll every 10 seconds
222
);
223
224
// Use with Curator client
225
CuratorZookeeperClient client = new CuratorZookeeperClient(
226
ensembleProvider,
227
5000, 5000, null,
228
new ExponentialBackoffRetry(1000, 3)
229
);
230
231
try {
232
ensembleProvider.start();
233
client.start();
234
235
// Ensemble provider will automatically update connection string
236
// as ZooKeeper cluster membership changes
237
238
} finally {
239
client.close();
240
ensembleProvider.close();
241
}
242
```
243
244
### Backup Connection String Provider
245
246
Functional interface for providing fallback connection strings when dynamic discovery fails.
247
248
```java { .api }
249
/**
250
* Functional interface for backup connection string provision
251
*/
252
@FunctionalInterface
253
public interface BackupConnectionStringProvider {
254
/**
255
* Get backup connection string when primary discovery fails
256
* @return Backup ZooKeeper connection string
257
* @throws Exception if backup cannot be provided
258
*/
259
String getBackupConnectionString() throws Exception;
260
}
261
```
262
263
**Usage Examples:**
264
265
```java
266
// Lambda expression for backup connection
267
BackupConnectionStringProvider backup = () -> "backup1:2181,backup2:2181,backup3:2181";
268
269
// Method reference
270
BackupConnectionStringProvider configBackup = this::getConfiguredBackupString;
271
272
// Anonymous class implementation
273
BackupConnectionStringProvider dynamicBackup = new BackupConnectionStringProvider() {
274
@Override
275
public String getBackupConnectionString() throws Exception {
276
// Query configuration service or database for backup servers
277
return configService.getZookeeperBackupServers();
278
}
279
};
280
```
281
282
## Ensemble Provider Selection Guide
283
284
### FixedEnsembleProvider
285
**Best for**:
286
- Stable ZooKeeper clusters with known, unchanging membership
287
- Development and testing environments
288
- Simple production deployments without dynamic scaling
289
290
**Use when**:
291
- ZooKeeper cluster membership is static
292
- You want minimal complexity and dependencies
293
- Service discovery infrastructure is not available
294
295
### ExhibitorEnsembleProvider
296
**Best for**:
297
- Dynamic ZooKeeper clusters managed by Netflix Exhibitor
298
- Cloud deployments where cluster membership changes
299
- Large-scale production environments with automated cluster management
300
301
**Use when**:
302
- Using Netflix Exhibitor for ZooKeeper cluster management
303
- ZooKeeper cluster membership changes dynamically
304
- You need automatic failover to backup connection strings
305
- High availability requirements with multiple ZooKeeper clusters
306
307
## Integration Patterns
308
309
### Client Configuration with Ensemble Providers
310
311
```java
312
// Pattern 1: Fixed ensemble for stable clusters
313
EnsembleProvider fixedEnsemble = new FixedEnsembleProvider("zk1:2181,zk2:2181,zk3:2181");
314
315
// Pattern 2: Dynamic ensemble with Exhibitor
316
Exhibitors exhibitors = new Exhibitors(
317
Arrays.asList("exhibitor1.com", "exhibitor2.com"), 8080,
318
() -> "backup1:2181,backup2:2181"
319
);
320
EnsembleProvider dynamicEnsemble = new ExhibitorEnsembleProvider(
321
exhibitors, new DefaultExhibitorRestClient(5000), 30000
322
);
323
324
// Both patterns work identically with CuratorZookeeperClient
325
CuratorZookeeperClient client = new CuratorZookeeperClient(
326
ensembleProvider, 5000, 5000, null, retryPolicy
327
);
328
```
329
330
### Resource Management
331
332
```java
333
// Always ensure proper resource cleanup
334
try (EnsembleProvider ensemble = new FixedEnsembleProvider("localhost:2181");
335
CuratorZookeeperClient client = new CuratorZookeeperClient(ensemble, 5000, 5000, null, retryPolicy)) {
336
337
ensemble.start();
338
client.start();
339
340
// Use client...
341
342
} // Resources automatically closed
343
```