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 @Deprecated
166 public ForeignExceptionMessage getForeignExceptionMessage() {
167 return exception;
168 }
169
170 public String getExceptionCause() {
171 assert isFailed();
172 return exception.getGenericException().getClassName();
173 }
174
175 public String getExceptionMessage() {
176 assert isFailed();
177 return exception.getGenericException().getMessage();
178 }
179
180 public String getExceptionFullMessage() {
181 assert isFailed();
182 return getExceptionCause() + " - " + getExceptionMessage();
183 }
184
185 public boolean hasResultData() {
186 return result != null;
187 }
188
189 public byte[] getResult() {
190 return result;
191 }
192
193 public long getStartTime() {
194 return startTime;
195 }
196
197 public long getLastUpdate() {
198 return lastUpdate;
199 }
200
201 public long executionTime() {
202 return lastUpdate - startTime;
203 }
204
205 @InterfaceAudience.Private
206 public boolean hasClientAckTime() {
207 return clientAckTime != -1;
208 }
209
210 @InterfaceAudience.Private
211 public long getClientAckTime() {
212 return clientAckTime;
213 }
214
215 @InterfaceAudience.Private
216 public void setClientAckTime(final long timestamp) {
217 this.clientAckTime = timestamp;
218 }
219
220
221
222
223
224 @InterfaceAudience.Private
225 @Deprecated
226 public static ProcedureProtos.Procedure convertToProcedureProto(
227 final ProcedureInfo procInfo) {
228 ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder();
229
230 builder.setClassName(procInfo.getProcName());
231 builder.setProcId(procInfo.getProcId());
232 builder.setStartTime(procInfo.getStartTime());
233 builder.setState(procInfo.getProcState());
234 builder.setLastUpdate(procInfo.getLastUpdate());
235
236 if (procInfo.hasParentId()) {
237 builder.setParentId(procInfo.getParentId());
238 }
239
240 if (procInfo.getProcOwner() != null) {
241 builder.setOwner(procInfo.getProcOwner());
242 }
243
244 if (procInfo.isFailed()) {
245 builder.setException(procInfo.getForeignExceptionMessage());
246 }
247
248 if (procInfo.hasResultData()) {
249 builder.setResult(ByteStringer.wrap(procInfo.getResult()));
250 }
251
252 return builder.build();
253 }
254
255
256
257
258
259
260 @InterfaceAudience.Private
261 @Deprecated
262 public static ProcedureInfo convert(final ProcedureProtos.Procedure procProto) {
263 NonceKey nonceKey = null;
264 if (procProto.getNonce() != HConstants.NO_NONCE) {
265 nonceKey = new NonceKey(procProto.getNonceGroup(), procProto.getNonce());
266 }
267
268 return new ProcedureInfo(
269 procProto.getProcId(),
270 procProto.getClassName(),
271 procProto.getOwner(),
272 procProto.getState(),
273 procProto.hasParentId() ? procProto.getParentId() : -1,
274 nonceKey,
275 procProto.hasException() ? procProto.getException() : null,
276 procProto.getLastUpdate(),
277 procProto.getStartTime(),
278 procProto.hasResult() ? procProto.getResult().toByteArray() : null);
279 }
280
281
282
283
284
285
286
287
288 @InterfaceAudience.Private
289 public static boolean isProcedureOwner(final ProcedureInfo procInfo, final User user) {
290 if (user == null) {
291 return false;
292 }
293 String procOwner = procInfo.getProcOwner();
294 if (procOwner == null) {
295 return false;
296 }
297 return procOwner.equals(user.getShortName());
298 }
299 }