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 com.google.protobuf.Descriptors;
22 import com.google.protobuf.Message;
23 import com.google.protobuf.RpcController;
24
25 import java.io.IOException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.classification.InterfaceAudience;
32 import org.apache.hadoop.hbase.client.ClusterConnection;
33 import org.apache.hadoop.hbase.client.RegionServerCallable;
34 import org.apache.hadoop.hbase.client.RpcRetryingCallerFactory;
35 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
36 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
37 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceResponse;
38 import org.apache.hadoop.hbase.util.Bytes;
39
40
41
42
43
44
45
46
47
48 @InterfaceAudience.Private
49 public class RegionCoprocessorRpcChannel extends CoprocessorRpcChannel{
50 private static final Log LOG = LogFactory.getLog(RegionCoprocessorRpcChannel.class);
51
52 private final ClusterConnection connection;
53 private final TableName table;
54 private final byte[] row;
55 private byte[] lastRegion;
56 private int operationTimeout;
57
58 private RpcRetryingCallerFactory rpcCallerFactory;
59 private RpcControllerFactory rpcControllerFactory;
60
61 public RegionCoprocessorRpcChannel(ClusterConnection conn, TableName table, byte[] row) {
62 this.connection = conn;
63 this.table = table;
64 this.row = row;
65 this.rpcCallerFactory = conn.getRpcRetryingCallerFactory();
66 this.rpcControllerFactory = conn.getRpcControllerFactory();
67 this.operationTimeout = conn.getConnectionConfiguration().getOperationTimeout();
68 }
69
70 @Override
71 protected Message callExecService(RpcController controller,
72 Descriptors.MethodDescriptor method, 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 RpcController rpcController = controller == null
83 ? rpcControllerFactory.newController() : controller;
84
85 final ClientProtos.CoprocessorServiceCall call =
86 CoprocessorRpcUtils.buildServiceCall(row, method, request);
87 RegionServerCallable<CoprocessorServiceResponse> callable =
88 new RegionServerCallable<CoprocessorServiceResponse>(connection, table, row, HConstants.PRIORITY_UNSET) {
89 @Override
90 public CoprocessorServiceResponse call(int callTimeout) throws Exception {
91 if (rpcController instanceof HBaseRpcController) {
92 HBaseRpcController hrc = (HBaseRpcController) rpcController;
93 hrc.setPriority(tableName);
94 hrc.setCallTimeout(callTimeout);
95 }
96 byte[] regionName = getLocation().getRegionInfo().getRegionName();
97 return ProtobufUtil.execService(rpcController, getStub(), call, regionName);
98 }
99 };
100 CoprocessorServiceResponse result = rpcCallerFactory.<CoprocessorServiceResponse> newCaller()
101 .callWithRetries(callable, operationTimeout);
102 Message response = null;
103 if (result.getValue().hasValue()) {
104 Message.Builder builder = responsePrototype.newBuilderForType();
105 ProtobufUtil.mergeFrom(builder, result.getValue().getValue());
106 response = builder.build();
107 } else {
108 response = responsePrototype.getDefaultInstanceForType();
109 }
110 lastRegion = result.getRegion().getValue().toByteArray();
111 if (LOG.isTraceEnabled()) {
112 LOG.trace("Result is region=" + Bytes.toStringBinary(lastRegion) + ", value=" + response);
113 }
114 return response;
115 }
116
117 public byte[] getLastRegion() {
118 return lastRegion;
119 }
120 }