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