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 @Override
83 public ProcedureInfo clone() {
84 return new ProcedureInfo(procId, procName, procOwner, procState, parentId, nonceKey,
85 exception, lastUpdate, startTime, result);
86 }
87
88 @Override
89 public String toString() {
90 StringBuilder sb = new StringBuilder();
91 sb.append("Procedure=");
92 sb.append(procName);
93 sb.append(" (id=");
94 sb.append(procId);
95 if (hasParentId()) {
96 sb.append(", parent=");
97 sb.append(parentId);
98 }
99 if (hasOwner()) {
100 sb.append(", owner=");
101 sb.append(procOwner);
102 }
103 sb.append(", state=");
104 sb.append(procState);
105
106 long now = EnvironmentEdgeManager.currentTime();
107 sb.append(", startTime=");
108 sb.append(StringUtils.formatTime(now - startTime));
109 sb.append(" ago, lastUpdate=");
110 sb.append(StringUtils.formatTime(now - startTime));
111 sb.append(" ago");
112
113 if (isFailed()) {
114 sb.append(", exception=\"");
115 sb.append(getExceptionMessage());
116 sb.append("\"");
117 }
118 sb.append(")");
119 return sb.toString();
120 }
121
122 public long getProcId() {
123 return procId;
124 }
125
126 public String getProcName() {
127 return procName;
128 }
129
130 private boolean hasOwner() {
131 return procOwner != null;
132 }
133
134 public String getProcOwner() {
135 return procOwner;
136 }
137
138 public ProcedureState getProcState() {
139 return procState;
140 }
141
142 public boolean hasParentId() {
143 return (parentId != -1);
144 }
145
146 public long getParentId() {
147 return parentId;
148 }
149
150 public NonceKey getNonceKey() {
151 return nonceKey;
152 }
153
154 public boolean isFailed() {
155 return exception != null;
156 }
157
158 public IOException getException() {
159 if (isFailed()) {
160 return ForeignExceptionUtil.toIOException(exception);
161 }
162 return null;
163 }
164
165 @InterfaceAudience.Private
166 @Deprecated
167 public ForeignExceptionMessage getForeignExceptionMessage() {
168 return exception;
169 }
170
171 public String getExceptionCause() {
172 assert isFailed();
173 return exception.getGenericException().getClassName();
174 }
175
176 public String getExceptionMessage() {
177 assert isFailed();
178 return exception.getGenericException().getMessage();
179 }
180
181 public String getExceptionFullMessage() {
182 assert isFailed();
183 return getExceptionCause() + " - " + getExceptionMessage();
184 }
185
186 public boolean hasResultData() {
187 return result != null;
188 }
189
190 public byte[] getResult() {
191 return result;
192 }
193
194 public long getStartTime() {
195 return startTime;
196 }
197
198 public long getLastUpdate() {
199 return lastUpdate;
200 }
201
202 public long executionTime() {
203 return lastUpdate - startTime;
204 }
205
206 @InterfaceAudience.Private
207 public boolean hasClientAckTime() {
208 return clientAckTime != -1;
209 }
210
211 @InterfaceAudience.Private
212 public long getClientAckTime() {
213 return clientAckTime;
214 }
215
216 @InterfaceAudience.Private
217 public void setClientAckTime(final long timestamp) {
218 this.clientAckTime = timestamp;
219 }
220
221
222
223
224
225 @InterfaceAudience.Private
226 @Deprecated
227 public static ProcedureProtos.Procedure convertToProcedureProto(
228 final ProcedureInfo procInfo) {
229 ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder();
230
231 builder.setClassName(procInfo.getProcName());
232 builder.setProcId(procInfo.getProcId());
233 builder.setStartTime(procInfo.getStartTime());
234 builder.setState(procInfo.getProcState());
235 builder.setLastUpdate(procInfo.getLastUpdate());
236
237 if (procInfo.hasParentId()) {
238 builder.setParentId(procInfo.getParentId());
239 }
240
241 if (procInfo.getProcOwner() != null) {
242 builder.setOwner(procInfo.getProcOwner());
243 }
244
245 if (procInfo.isFailed()) {
246 builder.setException(procInfo.getForeignExceptionMessage());
247 }
248
249 if (procInfo.hasResultData()) {
250 builder.setResult(ByteStringer.wrap(procInfo.getResult()));
251 }
252
253 return builder.build();
254 }
255
256
257
258
259
260
261 @InterfaceAudience.Private
262 @Deprecated
263 public static ProcedureInfo convert(final ProcedureProtos.Procedure procProto) {
264 NonceKey nonceKey = null;
265 if (procProto.getNonce() != HConstants.NO_NONCE) {
266 nonceKey = new NonceKey(procProto.getNonceGroup(), procProto.getNonce());
267 }
268
269 return new ProcedureInfo(
270 procProto.getProcId(),
271 procProto.getClassName(),
272 procProto.getOwner(),
273 procProto.getState(),
274 procProto.hasParentId() ? procProto.getParentId() : -1,
275 nonceKey,
276 procProto.hasException() ? procProto.getException() : null,
277 procProto.getLastUpdate(),
278 procProto.getStartTime(),
279 procProto.hasResult() ? procProto.getResult().toByteArray() : null);
280 }
281
282
283
284
285
286
287
288
289 @InterfaceAudience.Private
290 public static boolean isProcedureOwner(final ProcedureInfo procInfo, final User user) {
291 if (user == null) {
292 return false;
293 }
294 String procOwner = procInfo.getProcOwner();
295 if (procOwner == null) {
296 return false;
297 }
298 return procOwner.equals(user.getShortName());
299 }
300 }