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