1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.IOException;
22
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.classification.InterfaceStability;
25 import org.apache.hadoop.hbase.protobuf.generated.ErrorHandlingProtos.ForeignExceptionMessage;
26 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos;
27 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos.ProcedureState;
28 import org.apache.hadoop.hbase.security.User;
29 import org.apache.hadoop.hbase.util.ByteStringer;
30 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
31 import org.apache.hadoop.hbase.util.ForeignExceptionUtil;
32 import org.apache.hadoop.hbase.util.NonceKey;
33 import org.apache.hadoop.util.StringUtils;
34
35
36
37
38 @InterfaceAudience.Public
39 @InterfaceStability.Evolving
40 public class ProcedureInfo implements Cloneable {
41 private final long procId;
42 private final String procName;
43 private final String procOwner;
44 private final ProcedureState procState;
45 private final long parentId;
46 private final NonceKey nonceKey;
47 private final ForeignExceptionMessage exception;
48 private final long lastUpdate;
49 private final long startTime;
50 private final byte[] result;
51
52 private long clientAckTime = -1;
53
54 @InterfaceAudience.Private
55 public ProcedureInfo(
56 final long procId,
57 final String procName,
58 final String procOwner,
59 final ProcedureState procState,
60 final long parentId,
61 final NonceKey nonceKey,
62 final ForeignExceptionMessage exception,
63 final long lastUpdate,
64 final long startTime,
65 final byte[] result) {
66 this.procId = procId;
67 this.procName = procName;
68 this.procOwner = procOwner;
69 this.procState = procState;
70 this.parentId = parentId;
71 this.nonceKey = nonceKey;
72 this.lastUpdate = lastUpdate;
73 this.startTime = startTime;
74
75
76 this.exception = exception;
77 this.result = result;
78 }
79
80 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="CN_IDIOM_NO_SUPER_CALL",
81 justification="Intentional; calling super class clone doesn't make sense here.")
82 public ProcedureInfo clone() {
83 return new ProcedureInfo(procId, procName, procOwner, procState, parentId, nonceKey,
84 exception, lastUpdate, startTime, result);
85 }
86
87 @Override
88 public String toString() {
89 StringBuilder sb = new StringBuilder();
90 sb.append("Procedure=");
91 sb.append(procName);
92 sb.append(" (id=");
93 sb.append(procId);
94 if (hasParentId()) {
95 sb.append(", parent=");
96 sb.append(parentId);
97 }
98 if (hasOwner()) {
99 sb.append(", owner=");
100 sb.append(procOwner);
101 }
102 sb.append(", state=");
103 sb.append(procState);
104
105 long now = EnvironmentEdgeManager.currentTime();
106 sb.append(", startTime=");
107 sb.append(StringUtils.formatTime(now - startTime));
108 sb.append(" ago, lastUpdate=");
109 sb.append(StringUtils.formatTime(now - startTime));
110 sb.append(" ago");
111
112 if (isFailed()) {
113 sb.append(", exception=\"");
114 sb.append(getExceptionMessage());
115 sb.append("\"");
116 }
117 sb.append(")");
118 return sb.toString();
119 }
120
121 public long getProcId() {
122 return procId;
123 }
124
125 public String getProcName() {
126 return procName;
127 }
128
129 private boolean hasOwner() {
130 return procOwner != null;
131 }
132
133 public String getProcOwner() {
134 return procOwner;
135 }
136
137 public ProcedureState getProcState() {
138 return procState;
139 }
140
141 public boolean hasParentId() {
142 return (parentId != -1);
143 }
144
145 public long getParentId() {
146 return parentId;
147 }
148
149 public NonceKey getNonceKey() {
150 return nonceKey;
151 }
152
153 public boolean isFailed() {
154 return exception != null;
155 }
156
157 public IOException getException() {
158 if (isFailed()) {
159 return ForeignExceptionUtil.toIOException(exception);
160 }
161 return null;
162 }
163
164 @InterfaceAudience.Private
165 public ForeignExceptionMessage getForeignExceptionMessage() {
166 return exception;
167 }
168
169 public String getExceptionCause() {
170 assert isFailed();
171 return exception.getGenericException().getClassName();
172 }
173
174 public String getExceptionMessage() {
175 assert isFailed();
176 return exception.getGenericException().getMessage();
177 }
178
179 public String getExceptionFullMessage() {
180 assert isFailed();
181 return getExceptionCause() + " - " + getExceptionMessage();
182 }
183
184 public boolean hasResultData() {
185 return result != null;
186 }
187
188 public byte[] getResult() {
189 return result;
190 }
191
192 public long getStartTime() {
193 return startTime;
194 }
195
196 public long getLastUpdate() {
197 return lastUpdate;
198 }
199
200 public long executionTime() {
201 return lastUpdate - startTime;
202 }
203
204 @InterfaceAudience.Private
205 public boolean hasClientAckTime() {
206 return clientAckTime != -1;
207 }
208
209 @InterfaceAudience.Private
210 public long getClientAckTime() {
211 return clientAckTime;
212 }
213
214 @InterfaceAudience.Private
215 public void setClientAckTime(final long timestamp) {
216 this.clientAckTime = timestamp;
217 }
218
219
220
221
222
223 @InterfaceAudience.Private
224 public static ProcedureProtos.Procedure convertToProcedureProto(
225 final ProcedureInfo procInfo) {
226 ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder();
227
228 builder.setClassName(procInfo.getProcName());
229 builder.setProcId(procInfo.getProcId());
230 builder.setStartTime(procInfo.getStartTime());
231 builder.setState(procInfo.getProcState());
232 builder.setLastUpdate(procInfo.getLastUpdate());
233
234 if (procInfo.hasParentId()) {
235 builder.setParentId(procInfo.getParentId());
236 }
237
238 if (procInfo.getProcOwner() != null) {
239 builder.setOwner(procInfo.getProcOwner());
240 }
241
242 if (procInfo.isFailed()) {
243 builder.setException(procInfo.getForeignExceptionMessage());
244 }
245
246 if (procInfo.hasResultData()) {
247 builder.setResult(ByteStringer.wrap(procInfo.getResult()));
248 }
249
250 return builder.build();
251 }
252
253
254
255
256
257
258 @InterfaceAudience.Private
259 public static ProcedureInfo convert(final ProcedureProtos.Procedure procProto) {
260 NonceKey nonceKey = null;
261 if (procProto.getNonce() != HConstants.NO_NONCE) {
262 nonceKey = new NonceKey(procProto.getNonceGroup(), procProto.getNonce());
263 }
264
265 return new ProcedureInfo(
266 procProto.getProcId(),
267 procProto.getClassName(),
268 procProto.getOwner(),
269 procProto.getState(),
270 procProto.hasParentId() ? procProto.getParentId() : -1,
271 nonceKey,
272 procProto.hasException() ? procProto.getException() : null,
273 procProto.getLastUpdate(),
274 procProto.getStartTime(),
275 procProto.hasResult() ? procProto.getResult().toByteArray() : null);
276 }
277
278
279
280
281
282
283
284
285 @InterfaceAudience.Private
286 public static boolean isProcedureOwner(final ProcedureInfo procInfo, final User user) {
287 if (user == null) {
288 return false;
289 }
290 String procOwner = procInfo.getProcOwner();
291 if (procOwner == null) {
292 return false;
293 }
294 return procOwner.equals(user.getShortName());
295 }
296 }