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 org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.classification.InterfaceStability;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.HConstants;
27 import org.apache.hadoop.util.StringUtils;
28
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.net.InetAddress;
32 import java.net.UnknownHostException;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Map.Entry;
36 import java.util.Properties;
37
38
39
40
41 @InterfaceAudience.Public
42 @InterfaceStability.Evolving
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 if (conf.getBoolean(HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG,
60 false)) {
61 LOG.warn(
62 "Parsing ZooKeeper's " + HConstants.ZOOKEEPER_CONFIG_NAME +
63 " file for ZK properties " +
64 "has been deprecated. Please instead place all ZK related HBase " +
65 "configuration under the hbase-site.xml, using prefixes " +
66 "of the form '" + HConstants.ZK_CFG_PROPERTY_PREFIX + "', and " +
67 "set property '" + HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG +
68 "' to false");
69
70
71 ClassLoader cl = HQuorumPeer.class.getClassLoader();
72 final InputStream inputStream =
73 cl.getResourceAsStream(HConstants.ZOOKEEPER_CONFIG_NAME);
74 if (inputStream != null) {
75 try {
76 return parseZooCfg(conf, inputStream);
77 } catch (IOException e) {
78 LOG.warn("Cannot read " + HConstants.ZOOKEEPER_CONFIG_NAME +
79 ", loading from XML files", e);
80 }
81 }
82 } else {
83 if (LOG.isDebugEnabled()) {
84 LOG.debug(
85 "Skipped reading ZK properties file '" +
86 HConstants.ZOOKEEPER_CONFIG_NAME +
87 "' since '" + HConstants.HBASE_CONFIG_READ_ZOOKEEPER_CONFIG +
88 "' was not set to true");
89 }
90 }
91
92
93 Properties zkProperties = new Properties();
94
95
96 for (Entry<String, String> entry : conf) {
97 String key = entry.getKey();
98 if (key.startsWith(HConstants.ZK_CFG_PROPERTY_PREFIX)) {
99 String zkKey = key.substring(HConstants.ZK_CFG_PROPERTY_PREFIX_LEN);
100 String value = entry.getValue();
101
102 if (value.contains(VARIABLE_START)) {
103 value = conf.get(key);
104 }
105 zkProperties.put(zkKey, value);
106 }
107 }
108
109
110 if (zkProperties.getProperty(HConstants.CLIENT_PORT_STR) == null) {
111 zkProperties.put(HConstants.CLIENT_PORT_STR,
112 HConstants.DEFAULT_ZOOKEPER_CLIENT_PORT);
113 }
114
115
116 int peerPort = conf.getInt("hbase.zookeeper.peerport", 2888);
117 int leaderPort = conf.getInt("hbase.zookeeper.leaderport", 3888);
118
119 final String[] serverHosts = conf.getStrings(HConstants.ZOOKEEPER_QUORUM,
120 HConstants.LOCALHOST);
121 for (int i = 0; i < serverHosts.length; ++i) {
122 String serverHost = serverHosts[i];
123 String address = serverHost + ":" + peerPort + ":" + leaderPort;
124 String key = "server." + i;
125 zkProperties.put(key, address);
126 }
127
128 return zkProperties;
129 }
130
131
132
133
134
135
136
137
138
139
140
141 @Deprecated
142 public static Properties parseZooCfg(Configuration conf,
143 InputStream inputStream) throws IOException {
144 Properties properties = new Properties();
145 try {
146 properties.load(inputStream);
147 } catch (IOException e) {
148 final String msg = "fail to read properties from "
149 + HConstants.ZOOKEEPER_CONFIG_NAME;
150 LOG.fatal(msg);
151 throw new IOException(msg, e);
152 }
153 for (Entry<Object, Object> entry : properties.entrySet()) {
154 String value = entry.getValue().toString().trim();
155 String key = entry.getKey().toString().trim();
156 StringBuilder newValue = new StringBuilder();
157 int varStart = value.indexOf(VARIABLE_START);
158 int varEnd = 0;
159 while (varStart != -1) {
160 varEnd = value.indexOf(VARIABLE_END, varStart);
161 if (varEnd == -1) {
162 String msg = "variable at " + varStart + " has no end marker";
163 LOG.fatal(msg);
164 throw new IOException(msg);
165 }
166 String variable = value.substring(varStart + VARIABLE_START_LENGTH, varEnd);
167
168 String substituteValue = System.getProperty(variable);
169 if (substituteValue == null) {
170 substituteValue = conf.get(variable);
171 }
172 if (substituteValue == null) {
173 String msg = "variable " + variable + " not set in system property "
174 + "or hbase configs";
175 LOG.fatal(msg);
176 throw new IOException(msg);
177 }
178
179 newValue.append(substituteValue);
180
181 varEnd += VARIABLE_END_LENGTH;
182 varStart = value.indexOf(VARIABLE_START, varEnd);
183 }
184
185 if (key.startsWith("server.")) {
186 boolean mode = conf.getBoolean(HConstants.CLUSTER_DISTRIBUTED, HConstants.DEFAULT_CLUSTER_DISTRIBUTED);
187 if (mode == HConstants.CLUSTER_IS_DISTRIBUTED && value.startsWith(HConstants.LOCALHOST)) {
188 String msg = "The server in zoo.cfg cannot be set to localhost " +
189 "in a fully-distributed setup because it won't be reachable. " +
190 "See \"Getting Started\" for more information.";
191 LOG.fatal(msg);
192 throw new IOException(msg);
193 }
194 }
195 newValue.append(value.substring(varEnd));
196 properties.setProperty(key, newValue.toString());
197 }
198 return properties;
199 }
200
201
202
203
204
205
206
207 public static String getZKQuorumServersString(Properties properties) {
208 String clientPort = null;
209 List<String> servers = new ArrayList<String>();
210
211
212
213 boolean anyValid = false;
214 for (Entry<Object,Object> property : properties.entrySet()) {
215 String key = property.getKey().toString().trim();
216 String value = property.getValue().toString().trim();
217 if (key.equals("clientPort")) {
218 clientPort = value;
219 }
220 else if (key.startsWith("server.")) {
221 String host = value.substring(0, value.indexOf(':'));
222 servers.add(host);
223 try {
224
225 InetAddress.getByName(host);
226 anyValid = true;
227 } catch (UnknownHostException e) {
228 LOG.warn(StringUtils.stringifyException(e));
229 }
230 }
231 }
232
233 if (!anyValid) {
234 LOG.error("no valid quorum servers found in " + HConstants.ZOOKEEPER_CONFIG_NAME);
235 return null;
236 }
237
238 if (clientPort == null) {
239 LOG.error("no clientPort found in " + HConstants.ZOOKEEPER_CONFIG_NAME);
240 return null;
241 }
242
243 if (servers.isEmpty()) {
244 LOG.fatal("No servers were found in provided ZooKeeper configuration. " +
245 "HBase must have a ZooKeeper cluster configured for its " +
246 "operation. Ensure that you've configured '" +
247 HConstants.ZOOKEEPER_QUORUM + "' properly.");
248 return null;
249 }
250
251 StringBuilder hostPortBuilder = new StringBuilder();
252 for (int i = 0; i < servers.size(); ++i) {
253 String host = servers.get(i);
254 if (i > 0) {
255 hostPortBuilder.append(',');
256 }
257 hostPortBuilder.append(host);
258 hostPortBuilder.append(':');
259 hostPortBuilder.append(clientPort);
260 }
261
262 return hostPortBuilder.toString();
263 }
264
265
266
267
268
269
270 public static String getZKQuorumServersString(Configuration conf) {
271 return getZKQuorumServersString(makeZKProps(conf));
272 }
273 }