1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.zookeeper;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map.Entry;
26 import java.util.Properties;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.conf.Configuration;
32 import org.apache.hadoop.hbase.HConstants;
33
34
35
36
37
38
39
40
41
42 @InterfaceAudience.Private
43 public class ZKConfig {
44 private static final Log LOG = LogFactory.getLog(ZKConfig.class);
45
46 private static final String VARIABLE_START = "${";
47 private static final int VARIABLE_START_LENGTH = VARIABLE_START.length();
48 private static final String VARIABLE_END = "}";
49 private static final int VARIABLE_END_LENGTH = VARIABLE_END.length();
50
51
52
53
54
55
56
57
58 public static Properties makeZKProps(Configuration conf) {
59 Properties zkProperties = makeZKPropsFromZooCfg(conf);
60
61 if (zkProperties == null) {
62
63 zkProperties = makeZKPropsFromHbaseConfig(conf);
64 }
65 return zkProperties;
66 }
67
68
69
70
71
72
73
74
75
76 private static Properties makeZKPropsFromZooCfg(Configuration conf) {
77 if (conf.getBoolean(HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG, false)) {
78 LOG.warn(
79 "Parsing ZooKeeper's " + HConstants.ZOOKEEPER_CONFIG_NAME +
80 " file for ZK properties " +
81 "has been deprecated. Please instead place all ZK related HBase " +
82 "configuration under the hbase-site.xml, using prefixes " +
83 "of the form '" + HConstants.ZK_CFG_PROPERTY_PREFIX + "', and " +
84 "set property '" + HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG +
85 "' to false");
86
87
88 ClassLoader cl = HQuorumPeer.class.getClassLoader();
89 final InputStream inputStream =
90 cl.getResourceAsStream(HConstants.ZOOKEEPER_CONFIG_NAME);
91 if (inputStream != null) {
92 try {
93 return parseZooCfg(conf, inputStream);
94 } catch (IOException e) {
95 LOG.warn("Cannot read " + HConstants.ZOOKEEPER_CONFIG_NAME +
96 ", loading from XML files", e);
97 }
98 }
99 } else {
100 if (LOG.isTraceEnabled()) {
101 LOG.trace("Skipped reading ZK properties file '" + HConstants.ZOOKEEPER_CONFIG_NAME +
102 "' since '" + HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG + "' was not set to true");
103 }
104 }
105
106 return null;
107 }
108
109
110
111
112
113
114
115
116
117 private static Properties makeZKPropsFromHbaseConfig(Configuration conf) {
118 Properties zkProperties = new Properties();
119
120
121
122 synchronized (conf) {
123 for (Entry<String, String> entry : conf) {
124 String key = entry.getKey();
125 if (key.startsWith(HConstants.ZK_CFG_PROPERTY_PREFIX)) {
126 String zkKey = key.substring(HConstants.ZK_CFG_PROPERTY_PREFIX_LEN);
127 String value = entry.getValue();
128
129 if (value.contains(VARIABLE_START)) {
130 value = conf.get(key);
131 }
132 zkProperties.put(zkKey, value);
133 }
134 }
135 }
136
137
138 if (zkProperties.getProperty(HConstants.CLIENT_PORT_STR) == null) {
139 zkProperties.put(HConstants.CLIENT_PORT_STR,
140 HConstants.DEFAULT_ZOOKEPER_CLIENT_PORT);
141 }
142
143
144 int peerPort = conf.getInt("hbase.zookeeper.peerport", 2888);
145 int leaderPort = conf.getInt("hbase.zookeeper.leaderport", 3888);
146
147 final String[] serverHosts = conf.getStrings(HConstants.ZOOKEEPER_QUORUM,
148 HConstants.LOCALHOST);
149 String serverHost;
150 String address;
151 String key;
152 for (int i = 0; i < serverHosts.length; ++i) {
153 if (serverHosts[i].contains(":")) {
154 serverHost = serverHosts[i].substring(0, serverHosts[i].indexOf(':'));
155 } else {
156 serverHost = serverHosts[i];
157 }
158 address = serverHost + ":" + peerPort + ":" + leaderPort;
159 key = "server." + i;
160 zkProperties.put(key, address);
161 }
162
163 return zkProperties;
164 }
165
166
167
168
169
170
171
172
173
174
175
176 @Deprecated
177 public static Properties parseZooCfg(Configuration conf,
178 InputStream inputStream) throws IOException {
179 Properties properties = new Properties();
180 try {
181 properties.load(inputStream);
182 } catch (IOException e) {
183 final String msg = "fail to read properties from "
184 + HConstants.ZOOKEEPER_CONFIG_NAME;
185 LOG.fatal(msg);
186 throw new IOException(msg, e);
187 }
188 for (Entry<Object, Object> entry : properties.entrySet()) {
189 String value = entry.getValue().toString().trim();
190 String key = entry.getKey().toString().trim();
191 StringBuilder newValue = new StringBuilder();
192 int varStart = value.indexOf(VARIABLE_START);
193 int varEnd = 0;
194 while (varStart != -1) {
195 varEnd = value.indexOf(VARIABLE_END, varStart);
196 if (varEnd == -1) {
197 String msg = "variable at " + varStart + " has no end marker";
198 LOG.fatal(msg);
199 throw new IOException(msg);
200 }
201 String variable = value.substring(varStart + VARIABLE_START_LENGTH, varEnd);
202
203 String substituteValue = System.getProperty(variable);
204 if (substituteValue == null) {
205 substituteValue = conf.get(variable);
206 }
207 if (substituteValue == null) {
208 String msg = "variable " + variable + " not set in system property "
209 + "or hbase configs";
210 LOG.fatal(msg);
211 throw new IOException(msg);
212 }
213
214 newValue.append(substituteValue);
215
216 varEnd += VARIABLE_END_LENGTH;
217 varStart = value.indexOf(VARIABLE_START, varEnd);
218 }
219
220 if (key.startsWith("server.")) {
221 boolean mode =
222 conf.getBoolean(HConstants.CLUSTER_DISTRIBUTED, HConstants.DEFAULT_CLUSTER_DISTRIBUTED);
223 if (mode == HConstants.CLUSTER_IS_DISTRIBUTED && value.startsWith(HConstants.LOCALHOST)) {
224 String msg = "The server in zoo.cfg cannot be set to localhost " +
225 "in a fully-distributed setup because it won't be reachable. " +
226 "See \"Getting Started\" for more information.";
227 LOG.fatal(msg);
228 throw new IOException(msg);
229 }
230 }
231 newValue.append(value.substring(varEnd));
232 properties.setProperty(key, newValue.toString());
233 }
234 return properties;
235 }
236
237
238
239
240
241
242
243 private static String getZKQuorumServersString(Properties properties) {
244 String clientPort = null;
245 List<String> servers = new ArrayList<String>();
246
247
248
249 boolean anyValid = false;
250 for (Entry<Object,Object> property : properties.entrySet()) {
251 String key = property.getKey().toString().trim();
252 String value = property.getValue().toString().trim();
253 if (key.equals("clientPort")) {
254 clientPort = value;
255 }
256 else if (key.startsWith("server.")) {
257 String host = value.substring(0, value.indexOf(':'));
258 servers.add(host);
259 anyValid = true;
260 }
261 }
262
263 if (!anyValid) {
264 LOG.error("no valid quorum servers found in " + HConstants.ZOOKEEPER_CONFIG_NAME);
265 return null;
266 }
267
268 if (clientPort == null) {
269 LOG.error("no clientPort found in " + HConstants.ZOOKEEPER_CONFIG_NAME);
270 return null;
271 }
272
273 if (servers.isEmpty()) {
274 LOG.fatal("No servers were found in provided ZooKeeper configuration. " +
275 "HBase must have a ZooKeeper cluster configured for its " +
276 "operation. Ensure that you've configured '" +
277 HConstants.ZOOKEEPER_QUORUM + "' properly.");
278 return null;
279 }
280
281 StringBuilder hostPortBuilder = new StringBuilder();
282 for (int i = 0; i < servers.size(); ++i) {
283 String host = servers.get(i);
284 if (i > 0) {
285 hostPortBuilder.append(',');
286 }
287 hostPortBuilder.append(host);
288 hostPortBuilder.append(':');
289 hostPortBuilder.append(clientPort);
290 }
291
292 return hostPortBuilder.toString();
293 }
294
295
296
297
298
299
300
301 private static String getZKQuorumServersStringFromHbaseConfig(Configuration conf) {
302 String defaultClientPort = Integer.toString(
303 conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, HConstants.DEFAULT_ZOOKEPER_CLIENT_PORT));
304
305
306 final String[] serverHosts =
307 conf.getStrings(HConstants.ZOOKEEPER_QUORUM, HConstants.LOCALHOST);
308 return buildQuorumServerString(serverHosts, defaultClientPort);
309 }
310
311
312
313
314
315
316
317
318 public static String buildQuorumServerString(String[] serverHosts, String clientPort) {
319 StringBuilder quorumStringBuilder = new StringBuilder();
320 String serverHost;
321 for (int i = 0; i < serverHosts.length; ++i) {
322 if (serverHosts[i].contains(":")) {
323 serverHost = serverHosts[i];
324 } else {
325 serverHost = serverHosts[i] + ":" + clientPort;
326 }
327 if (i > 0) {
328 quorumStringBuilder.append(',');
329 }
330 quorumStringBuilder.append(serverHost);
331 }
332 return quorumStringBuilder.toString();
333 }
334
335
336
337
338
339
340 public static String getZKQuorumServersString(Configuration conf) {
341
342 Properties zkProperties = makeZKPropsFromZooCfg(conf);
343
344 if (zkProperties != null) {
345 return getZKQuorumServersString(zkProperties);
346 }
347
348 return getZKQuorumServersStringFromHbaseConfig(conf);
349 }
350 }