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 ThreadLocal<Integer> rpcTimeout = new ThreadLocal<Integer>() {
88 @Override
89 protected Integer initialValue() {
90 return HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
91 }
92 };
93
94
95
96
97 public static synchronized RpcEngine getProtocolEngine(Configuration conf) {
98
99 Class<?> impl =
100 conf.getClass(RPC_ENGINE_PROP, WritableRpcEngine.class);
101
102 LOG.debug("Using RpcEngine: "+impl.getName());
103 RpcEngine engine = (RpcEngine) ReflectionUtils.newInstance(impl, conf);
104 return engine;
105 }
106
107
108
109
110 @SuppressWarnings("serial")
111 public static class VersionMismatch extends IOException {
112 private static final long serialVersionUID = 0;
113 private String interfaceName;
114 private long clientVersion;
115 private long serverVersion;
116
117
118
119
120
121
122
123 public VersionMismatch(String interfaceName, long clientVersion,
124 long serverVersion) {
125 super("Protocol " + interfaceName + " version mismatch. (client = " +
126 clientVersion + ", server = " + serverVersion + ")");
127 this.interfaceName = interfaceName;
128 this.clientVersion = clientVersion;
129 this.serverVersion = serverVersion;
130 }
131
132
133
134
135
136
137 public String getInterfaceName() {
138 return interfaceName;
139 }
140
141
142
143
144 public long getClientVersion() {
145 return clientVersion;
146 }
147
148
149
150
151 public long getServerVersion() {
152 return serverVersion;
153 }
154 }
155
156
157
158
159 public static class UnknownProtocolException extends DoNotRetryIOException {
160 private Class<?> protocol;
161
162 public UnknownProtocolException(String mesg) {
163
164 super(mesg);
165 }
166
167 public UnknownProtocolException(Class<?> protocol) {
168 this(protocol, "Server is not handling protocol "+protocol.getName());
169 }
170
171 public UnknownProtocolException(Class<?> protocol, String mesg) {
172 super(mesg);
173 this.protocol = protocol;
174 }
175
176 public Class getProtocol() {
177 return protocol;
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192 @SuppressWarnings("unchecked")
193 public static <T extends VersionedProtocol> T waitForProxy(RpcEngine rpcClient,
194 Class<T> protocol,
195 long clientVersion,
196 InetSocketAddress addr,
197 Configuration conf,
198 int maxAttempts,
199 int rpcTimeout,
200 long timeout
201 ) throws IOException {
202
203 long startTime = System.currentTimeMillis();
204 IOException ioe;
205 int reconnectAttempts = 0;
206 while (true) {
207 try {
208 return rpcClient.getProxy(protocol, clientVersion, addr, conf, rpcTimeout);
209 } catch(SocketTimeoutException te) {
210 LOG.info("Problem connecting to server: " + addr);
211 ioe = te;
212 } catch (IOException ioex) {
213
214 ConnectException ce = null;
215 if (ioex instanceof ConnectException) {
216 ce = (ConnectException) ioex;
217 ioe = ce;
218 } else if (ioex.getCause() != null
219 && ioex.getCause() instanceof ConnectException) {
220 ce = (ConnectException) ioex.getCause();
221 ioe = ce;
222 } else if (ioex.getMessage().toLowerCase()
223 .contains("connection refused")) {
224 ce = new ConnectException(ioex.getMessage());
225 ioe = ce;
226 } else {
227
228 ioe = ioex;
229 }
230 if (ce != null) {
231 handleConnectionException(++reconnectAttempts, maxAttempts, protocol,
232 addr, ce);
233 }
234 }
235
236 if (System.currentTimeMillis() - timeout >= startTime) {
237 throw ioe;
238 }
239
240
241 try {
242 Thread.sleep(1000);
243 } catch (InterruptedException ie) {
244
245 }
246 }
247 }
248
249
250
251
252
253
254
255
256
257 private static void handleConnectionException(int retries, int maxAttmpts,
258 Class<?> protocol, InetSocketAddress addr, ConnectException ce)
259 throws RetriesExhaustedException {
260 if (maxAttmpts >= 0 && retries >= maxAttmpts) {
261 LOG.info("Server at " + addr + " could not be reached after "
262 + maxAttmpts + " tries, giving up.");
263 throw new RetriesExhaustedException("Failed setting up proxy " + protocol
264 + " to " + addr.toString() + " after attempts=" + maxAttmpts, ce);
265 }
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 @Deprecated
283 public static Object[] call(Method method, Object[][] params,
284 InetSocketAddress[] addrs,
285 Class<? extends VersionedProtocol> protocol,
286 User ticket,
287 Configuration conf)
288 throws IOException, InterruptedException {
289 Object[] result = null;
290 RpcEngine engine = null;
291 try {
292 engine = getProtocolEngine(conf);
293 result = engine.call(method, params, addrs, protocol, ticket, conf);
294 } finally {
295 engine.close();
296 }
297 return result;
298 }
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 public static RpcServer getServer(final Object instance,
314 final Class<?>[] ifaces,
315 final String bindAddress, final int port,
316 final int numHandlers,
317 int metaHandlerCount, final boolean verbose, Configuration conf, int highPriorityLevel)
318 throws IOException {
319 return getServer(instance.getClass(), instance, ifaces, bindAddress, port, numHandlers, metaHandlerCount, verbose, conf, highPriorityLevel);
320 }
321
322
323 public static RpcServer getServer(Class protocol,
324 final Object instance,
325 final Class<?>[] ifaces, String bindAddress,
326 int port,
327 final int numHandlers,
328 int metaHandlerCount, final boolean verbose, Configuration conf, int highPriorityLevel)
329 throws IOException {
330 return getProtocolEngine(conf)
331 .getServer(protocol, instance, ifaces, bindAddress, port, numHandlers, metaHandlerCount, verbose, conf, highPriorityLevel);
332 }
333
334 public static void setRpcTimeout(int rpcTimeout) {
335 HBaseRPC.rpcTimeout.set(rpcTimeout);
336 }
337
338 public static int getRpcTimeout() {
339 return HBaseRPC.rpcTimeout.get();
340 }
341
342 public static void resetRpcTimeout() {
343 HBaseRPC.rpcTimeout.remove();
344 }
345
346
347
348
349
350 public static int getRpcTimeout(int defaultTimeout) {
351 return Math.min(defaultTimeout, HBaseRPC.rpcTimeout.get());
352 }
353 }