1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.ipc;
20
21 import java.io.IOException;
22
23 import org.apache.hadoop.hbase.util.ByteStringer;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.client.HConnection;
30 import org.apache.hadoop.hbase.client.RegionServerCallable;
31 import org.apache.hadoop.hbase.client.RpcRetryingCallerFactory;
32 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
33 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
34 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceResponse;
35 import org.apache.hadoop.hbase.util.Bytes;
36
37 import com.google.protobuf.Descriptors;
38 import com.google.protobuf.Message;
39
40
41
42
43
44
45
46
47
48 @InterfaceAudience.Private
49 public class RegionCoprocessorRpcChannel extends CoprocessorRpcChannel{
50 private static Log LOG = LogFactory.getLog(RegionCoprocessorRpcChannel.class);
51
52 private final HConnection connection;
53 private final TableName table;
54 private final byte[] row;
55 private byte[] lastRegion;
56 private int operationTimeout;
57
58 private RpcRetryingCallerFactory rpcFactory;
59
60 public RegionCoprocessorRpcChannel(HConnection conn, TableName table, byte[] row) {
61 this.connection = conn;
62 this.table = table;
63 this.row = row;
64 this.rpcFactory = RpcRetryingCallerFactory.instantiate(conn.getConfiguration(), null);
65 this.operationTimeout = conn.getConfiguration().getInt(
66 HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
67 HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
68 }
69
70 @Override
71 protected Message callExecService(Descriptors.MethodDescriptor method,
72 Message request, Message responsePrototype)
73 throws IOException {
74 if (LOG.isTraceEnabled()) {
75 LOG.trace("Call: "+method.getName()+", "+request.toString());
76 }
77
78 if (row == null) {
79 throw new IllegalArgumentException("Missing row property for remote region location");
80 }
81
82 final ClientProtos.CoprocessorServiceCall call =
83 ClientProtos.CoprocessorServiceCall.newBuilder()
84 .setRow(ByteStringer.wrap(row))
85 .setServiceName(method.getService().getFullName())
86 .setMethodName(method.getName())
87 .setRequest(request.toByteString()).build();
88 RegionServerCallable<CoprocessorServiceResponse> callable =
89 new RegionServerCallable<CoprocessorServiceResponse>(connection, table, row) {
90 public CoprocessorServiceResponse call(int callTimeout) throws Exception {
91 byte[] regionName = getLocation().getRegionInfo().getRegionName();
92 return ProtobufUtil.execService(getStub(), call, regionName);
93 }
94 };
95 CoprocessorServiceResponse result = rpcFactory.<CoprocessorServiceResponse> newCaller()
96 .callWithRetries(callable, operationTimeout);
97 Message response = null;
98 if (result.getValue().hasValue()) {
99 response = responsePrototype.newBuilderForType()
100 .mergeFrom(result.getValue().getValue()).build();
101 } else {
102 response = responsePrototype.getDefaultInstanceForType();
103 }
104 lastRegion = result.getRegion().getValue().toByteArray();
105 if (LOG.isTraceEnabled()) {
106 LOG.trace("Result is region=" + Bytes.toStringBinary(lastRegion) + ", value=" + response);
107 }
108 return response;
109 }
110
111 public byte[] getLastRegion() {
112 return lastRegion;
113 }
114 }