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