1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.ipc;
19
20 import com.google.common.base.Preconditions;
21 import com.google.protobuf.CodedOutputStream;
22 import com.google.protobuf.Message;
23
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.net.ConnectException;
27 import java.net.SocketTimeoutException;
28 import java.nio.ByteBuffer;
29
30 import org.apache.hadoop.hbase.DoNotRetryIOException;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.classification.InterfaceAudience;
33 import org.apache.hadoop.hbase.exceptions.ConnectionClosingException;
34 import org.apache.hadoop.hbase.net.Address;
35 import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.CellBlockMeta;
36 import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.ExceptionResponse;
37 import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.RequestHeader;
38 import org.apache.hadoop.hbase.protobuf.generated.TracingProtos.RPCTInfo;
39 import org.apache.hadoop.hbase.util.Bytes;
40 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
41 import org.apache.hadoop.ipc.RemoteException;
42
43
44
45
46 @InterfaceAudience.Private
47 class IPCUtil {
48
49
50
51
52
53
54
55
56
57
58 public static int write(final OutputStream dos, final Message header, final Message param,
59 final ByteBuffer cellBlock) throws IOException {
60
61
62
63 int totalSize = IPCUtil.getTotalSizeWhenWrittenDelimited(header, param);
64 if (cellBlock != null) {
65 totalSize += cellBlock.remaining();
66 }
67 return write(dos, header, param, cellBlock, totalSize);
68 }
69
70 private static int write(final OutputStream dos, final Message header, final Message param,
71 final ByteBuffer cellBlock, final int totalSize) throws IOException {
72
73 dos.write(Bytes.toBytes(totalSize));
74
75 header.writeDelimitedTo(dos);
76 if (param != null) {
77 param.writeDelimitedTo(dos);
78 }
79 if (cellBlock != null) {
80 dos.write(cellBlock.array(), 0, cellBlock.remaining());
81 }
82 dos.flush();
83 return totalSize;
84 }
85
86
87
88
89 public static int getTotalSizeWhenWrittenDelimited(Message... messages) {
90 int totalSize = 0;
91 for (Message m : messages) {
92 if (m == null) {
93 continue;
94 }
95 totalSize += m.getSerializedSize();
96 totalSize += CodedOutputStream.computeRawVarint32Size(m.getSerializedSize());
97 }
98 Preconditions.checkArgument(totalSize < Integer.MAX_VALUE);
99 return totalSize;
100 }
101
102 static RequestHeader buildRequestHeader(Call call, CellBlockMeta cellBlockMeta) {
103 RequestHeader.Builder builder = RequestHeader.newBuilder();
104 builder.setCallId(call.id);
105 if (call.span != null) {
106 builder.setTraceInfo(RPCTInfo.newBuilder().setParentId(call.span.getSpanId())
107 .setTraceId(call.span.getTraceId()));
108 }
109 builder.setMethodName(call.md.getName());
110 builder.setRequestParam(call.param != null);
111 if (cellBlockMeta != null) {
112 builder.setCellBlockMeta(cellBlockMeta);
113 }
114
115 if (call.priority != HConstants.PRIORITY_UNSET) {
116 builder.setPriority(call.priority);
117 }
118 builder.setTimeout(call.timeout);
119
120 return builder.build();
121 }
122
123
124
125
126
127 static RemoteException createRemoteException(final ExceptionResponse e) {
128 String innerExceptionClassName = e.getExceptionClassName();
129 boolean doNotRetry = e.getDoNotRetry();
130 return e.hasHostname() ?
131
132 new RemoteWithExtrasException(innerExceptionClassName, e.getStackTrace(), e.getHostname(),
133 e.getPort(), doNotRetry)
134 : new RemoteWithExtrasException(innerExceptionClassName, e.getStackTrace(), doNotRetry);
135 }
136
137
138
139
140 static boolean isFatalConnectionException(final ExceptionResponse e) {
141 return e.getExceptionClassName().equals(FatalConnectionException.class.getName());
142 }
143
144 static IOException toIOE(Throwable t) {
145 if (t instanceof IOException) {
146 return (IOException) t;
147 } else {
148 return new IOException(t);
149 }
150 }
151
152
153
154
155
156
157
158
159
160
161
162 static IOException wrapException(Address addr, Exception exception) {
163 if (exception instanceof ConnectException) {
164
165 return (ConnectException) new ConnectException(
166 "Call to " + addr + " failed on connection exception: " + exception).initCause(exception);
167 } else if (exception instanceof SocketTimeoutException) {
168 return (SocketTimeoutException) new SocketTimeoutException(
169 "Call to " + addr + " failed because " + exception).initCause(exception);
170 } else if (exception instanceof ConnectionClosingException) {
171 return new ConnectionClosingException("Call to " + addr + " failed on local exception: "
172 + exception, exception);
173 } else if (exception instanceof ServerTooBusyException) {
174
175 return (IOException) exception;
176 } else if (exception instanceof DoNotRetryIOException) {
177 return new DoNotRetryIOException(
178 "Call to " + addr + " failed on local exception: " + exception, exception);
179 } else {
180 return new IOException(
181 "Call to " + addr + " failed on local exception: " + exception, exception);
182 }
183 }
184
185 static void setCancelled(Call call) {
186 call.setException(new CallCancelledException("Call id=" + call.id + ", waitTime=" +
187 (EnvironmentEdgeManager.currentTime() - call.getStartTime()) + ", rpcTimeout=" +
188 call.timeout));
189 }
190 }