1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.ipc;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.DoNotRetryIOException;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.client.RetriesExhaustedException;
29 import org.apache.hadoop.hbase.security.User;
30 import org.apache.hadoop.io.Writable;
31 import org.apache.hadoop.net.NetUtils;
32 import org.apache.hadoop.util.ReflectionUtils;
33 import javax.net.SocketFactory;
34 import java.io.IOException;
35 import java.lang.reflect.Method;
36 import java.lang.reflect.Proxy;
37 import java.net.ConnectException;
38 import java.net.InetSocketAddress;
39 import java.net.SocketTimeoutException;
40 import java.util.HashMap;
41 import java.util.Map;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public class HBaseRPC {
69
70
71
72 protected static final Log LOG =
73 LogFactory.getLog("org.apache.hadoop.ipc.HBaseRPC");
74
75 private HBaseRPC() {
76 super();
77 }
78
79
80
81
82
83
84 public static final String RPC_ENGINE_PROP = "hbase.rpc.engine";
85
86
87 private static final Map<Class,RpcEngine> PROTOCOL_ENGINES
88 = new HashMap<Class,RpcEngine>();
89
90
91 private static final Map<Class,RpcEngine> PROXY_ENGINES
92 = new HashMap<Class,RpcEngine>();
93
94
95 private static ThreadLocal<Integer> rpcTimeout = new ThreadLocal<Integer>() {
96 @Override
97 protected Integer initialValue() {
98 return HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
99 }
100 };
101
102
103 static void setProtocolEngine(Configuration conf,
104 Class protocol, Class engine) {
105 conf.setClass(RPC_ENGINE_PROP+"."+protocol.getName(), engine, RpcEngine.class);
106 }
107
108
109 private static synchronized RpcEngine getProtocolEngine(Class protocol,
110 Configuration conf) {
111 RpcEngine engine = PROTOCOL_ENGINES.get(protocol);
112 if (engine == null) {
113
114 Class<?> defaultEngine =
115 conf.getClass(RPC_ENGINE_PROP, WritableRpcEngine.class);
116
117
118 Class<?> impl = conf.getClass(RPC_ENGINE_PROP+"."+protocol.getName(),
119 defaultEngine);
120 LOG.debug("Using "+impl.getName()+" for "+protocol.getName());
121 engine = (RpcEngine) ReflectionUtils.newInstance(impl, conf);
122 if (protocol.isInterface())
123 PROXY_ENGINES.put(Proxy.getProxyClass(protocol.getClassLoader(),
124 protocol),
125 engine);
126 PROTOCOL_ENGINES.put(protocol, engine);
127 }
128 return engine;
129 }
130
131
132 private static synchronized RpcEngine getProxyEngine(Object proxy) {
133 return PROXY_ENGINES.get(proxy.getClass());
134 }
135
136
137
138
139 @SuppressWarnings("serial")
140 public static class VersionMismatch extends IOException {
141 private static final long serialVersionUID = 0;
142 private String interfaceName;
143 private long clientVersion;
144 private long serverVersion;
145
146
147
148
149
150
151
152 public VersionMismatch(String interfaceName, long clientVersion,
153 long serverVersion) {
154 super("Protocol " + interfaceName + " version mismatch. (client = " +
155 clientVersion + ", server = " + serverVersion + ")");
156 this.interfaceName = interfaceName;
157 this.clientVersion = clientVersion;
158 this.serverVersion = serverVersion;
159 }
160
161
162
163
164
165
166 public String getInterfaceName() {
167 return interfaceName;
168 }
169
170
171
172
173 public long getClientVersion() {
174 return clientVersion;
175 }
176
177
178
179
180 public long getServerVersion() {
181 return serverVersion;
182 }
183 }
184
185
186
187
188 public static class UnknownProtocolException extends DoNotRetryIOException {
189 private Class<?> protocol;
190
191 public UnknownProtocolException(String mesg) {
192
193 super(mesg);
194 }
195
196 public UnknownProtocolException(Class<?> protocol) {
197 this(protocol, "Server is not handling protocol "+protocol.getName());
198 }
199
200 public UnknownProtocolException(Class<?> protocol, String mesg) {
201 super(mesg);
202 this.protocol = protocol;
203 }
204
205 public Class getProtocol() {
206 return protocol;
207 }
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221 @SuppressWarnings("unchecked")
222 public static VersionedProtocol waitForProxy(Class protocol,
223 long clientVersion,
224 InetSocketAddress addr,
225 Configuration conf,
226 int maxAttempts,
227 int rpcTimeout,
228 long timeout
229 ) throws IOException {
230
231 long startTime = System.currentTimeMillis();
232 IOException ioe;
233 int reconnectAttempts = 0;
234 while (true) {
235 try {
236 return getProxy(protocol, clientVersion, addr, conf, rpcTimeout);
237 } catch(ConnectException se) {
238 ioe = se;
239 if (maxAttempts >= 0 && ++reconnectAttempts >= maxAttempts) {
240 LOG.info("Server at " + addr + " could not be reached after " +
241 reconnectAttempts + " tries, giving up.");
242 throw new RetriesExhaustedException("Failed setting up proxy " +
243 protocol + " to " + addr.toString() + " after attempts=" +
244 reconnectAttempts, se);
245 }
246 } catch(SocketTimeoutException te) {
247 LOG.info("Problem connecting to server: " + addr);
248 ioe = te;
249 }
250
251 if (System.currentTimeMillis()-timeout >= startTime) {
252 throw ioe;
253 }
254
255
256 try {
257 Thread.sleep(1000);
258 } catch (InterruptedException ie) {
259
260 }
261 }
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 public static VersionedProtocol getProxy(Class<? extends VersionedProtocol> protocol,
278 long clientVersion, InetSocketAddress addr, Configuration conf,
279 SocketFactory factory, int rpcTimeout) throws IOException {
280 return getProxy(protocol, clientVersion, addr,
281 User.getCurrent(), conf, factory, rpcTimeout);
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 public static VersionedProtocol getProxy(
299 Class<? extends VersionedProtocol> protocol,
300 long clientVersion, InetSocketAddress addr, User ticket,
301 Configuration conf, SocketFactory factory, int rpcTimeout)
302 throws IOException {
303 VersionedProtocol proxy =
304 getProtocolEngine(protocol,conf)
305 .getProxy(protocol, clientVersion, addr, ticket, conf, factory, Math.min(rpcTimeout, HBaseRPC.getRpcTimeout()));
306 long serverVersion = proxy.getProtocolVersion(protocol.getName(),
307 clientVersion);
308 if (serverVersion == clientVersion) {
309 return proxy;
310 }
311 throw new VersionMismatch(protocol.getName(), clientVersion,
312 serverVersion);
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326 public static VersionedProtocol getProxy(
327 Class<? extends VersionedProtocol> protocol,
328 long clientVersion, InetSocketAddress addr, Configuration conf,
329 int rpcTimeout)
330 throws IOException {
331
332 return getProxy(protocol, clientVersion, addr, conf, NetUtils
333 .getDefaultSocketFactory(conf), rpcTimeout);
334 }
335
336
337
338
339
340 public static void stopProxy(VersionedProtocol proxy) {
341 if (proxy!=null) {
342 getProxyEngine(proxy).stopProxy(proxy);
343 }
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 @Deprecated
361 public static Object[] call(Method method, Object[][] params,
362 InetSocketAddress[] addrs,
363 Class<? extends VersionedProtocol> protocol,
364 User ticket,
365 Configuration conf)
366 throws IOException, InterruptedException {
367 return getProtocolEngine(protocol, conf)
368 .call(method, params, addrs, protocol, ticket, conf);
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 public static RpcServer getServer(final Object instance,
385 final Class<?>[] ifaces,
386 final String bindAddress, final int port,
387 final int numHandlers,
388 int metaHandlerCount, final boolean verbose, Configuration conf, int highPriorityLevel)
389 throws IOException {
390 return getServer(instance.getClass(), instance, ifaces, bindAddress, port, numHandlers, metaHandlerCount, verbose, conf, highPriorityLevel);
391 }
392
393
394 public static RpcServer getServer(Class protocol,
395 final Object instance,
396 final Class<?>[] ifaces, String bindAddress,
397 int port,
398 final int numHandlers,
399 int metaHandlerCount, final boolean verbose, Configuration conf, int highPriorityLevel)
400 throws IOException {
401 return getProtocolEngine(protocol, conf)
402 .getServer(protocol, instance, ifaces, bindAddress, port, numHandlers, metaHandlerCount, verbose, conf, highPriorityLevel);
403 }
404
405 public static void setRpcTimeout(int rpcTimeout) {
406 HBaseRPC.rpcTimeout.set(rpcTimeout);
407 }
408
409 public static int getRpcTimeout() {
410 return HBaseRPC.rpcTimeout.get();
411 }
412
413 public static void resetRpcTimeout() {
414 HBaseRPC.rpcTimeout.remove();
415 }
416 }