View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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.ForeignExceptionUtil;
31  
32  /**
33   * Procedure information
34   */
35  @InterfaceAudience.Public
36  @InterfaceStability.Evolving
37  public class ProcedureInfo {
38    private final long procId;
39    private final String procName;
40    private final String procOwner;
41    private final ProcedureState procState;
42    private final long parentId;
43    private final ForeignExceptionMessage exception;
44    private final long lastUpdate;
45    private final long startTime;
46    private final byte[] result;
47  
48    private long clientAckTime = -1;
49  
50    @InterfaceAudience.Private
51    public ProcedureInfo(
52        final long procId,
53        final String procName,
54        final String procOwner,
55        final ProcedureState procState,
56        final long parentId,
57        final ForeignExceptionMessage exception,
58        final long lastUpdate,
59        final long startTime,
60        final byte[] result) {
61      this.procId = procId;
62      this.procName = procName;
63      this.procOwner = procOwner;
64      this.procState = procState;
65      this.parentId = parentId;
66      this.lastUpdate = lastUpdate;
67      this.startTime = startTime;
68  
69      // If the procedure is completed, we should treat exception and result differently
70      this.exception = exception;
71      this.result = result;
72    }
73  
74    public ProcedureInfo clone() {
75      return new ProcedureInfo(
76        procId, procName, procOwner, procState, parentId, exception, lastUpdate, startTime, result);
77    }
78  
79    public long getProcId() {
80      return procId;
81    }
82  
83    public String getProcName() {
84      return procName;
85    }
86  
87    public String getProcOwner() {
88      return procOwner;
89    }
90  
91    public ProcedureState getProcState() {
92      return procState;
93    }
94  
95    public boolean hasParentId() {
96      return (parentId != -1);
97    }
98  
99    public long getParentId() {
100     return parentId;
101   }
102 
103   public boolean isFailed() {
104     return exception != null;
105   }
106 
107   public IOException getException() {
108     if (isFailed()) {
109       return ForeignExceptionUtil.toIOException(exception);
110     }
111     return null;
112   }
113 
114   @InterfaceAudience.Private
115   public ForeignExceptionMessage getForeignExceptionMessage() {
116     return exception;
117   }
118 
119   public String getExceptionCause() {
120     assert isFailed();
121     return exception.getGenericException().getClassName();
122   }
123 
124   public String getExceptionMessage() {
125     assert isFailed();
126     return exception.getGenericException().getMessage();
127   }
128 
129   public String getExceptionFullMessage() {
130     assert isFailed();
131     return getExceptionCause() + " - " + getExceptionMessage();
132   }
133 
134   public boolean hasResultData() {
135     return result != null;
136   }
137 
138   public byte[] getResult() {
139     return result;
140   }
141 
142   public long getStartTime() {
143     return startTime;
144   }
145 
146   public long getLastUpdate() {
147     return lastUpdate;
148   }
149 
150   public long executionTime() {
151     return lastUpdate - startTime;
152   }
153 
154   @InterfaceAudience.Private
155   public boolean hasClientAckTime() {
156     return clientAckTime > 0;
157   }
158 
159   @InterfaceAudience.Private
160   public long getClientAckTime() {
161     return clientAckTime;
162   }
163 
164   @InterfaceAudience.Private
165   public void setClientAckTime(final long timestamp) {
166     this.clientAckTime = timestamp;
167   }
168 
169   /**
170    * @return Convert the current {@link ProcedureInfo} into a Protocol Buffers Procedure
171    * instance.
172    */
173   @InterfaceAudience.Private
174   public static ProcedureProtos.Procedure convertToProcedureProto(
175       final ProcedureInfo procInfo) {
176     ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder();
177 
178     builder.setClassName(procInfo.getProcName());
179     builder.setProcId(procInfo.getProcId());
180     builder.setStartTime(procInfo.getStartTime());
181     builder.setState(procInfo.getProcState());
182     builder.setLastUpdate(procInfo.getLastUpdate());
183 
184     if (procInfo.hasParentId()) {
185       builder.setParentId(procInfo.getParentId());
186     }
187 
188     if (procInfo.getProcOwner() != null) {
189        builder.setOwner(procInfo.getProcOwner());
190     }
191 
192     if (procInfo.isFailed()) {
193         builder.setException(procInfo.getForeignExceptionMessage());
194     }
195 
196     if (procInfo.hasResultData()) {
197       builder.setResult(ByteStringer.wrap(procInfo.getResult()));
198     }
199 
200     return builder.build();
201   }
202 
203   /**
204    * Helper to convert the protobuf object.
205    * @return Convert the current Protocol Buffers Procedure to {@link ProcedureInfo}
206    * instance.
207    */
208   @InterfaceAudience.Private
209   public static ProcedureInfo convert(final ProcedureProtos.Procedure procProto) {
210     return new ProcedureInfo(
211       procProto.getProcId(),
212       procProto.getClassName(),
213       procProto.getOwner(),
214       procProto.getState(),
215       procProto.hasParentId() ? procProto.getParentId() : -1,
216       procProto.hasException() ? procProto.getException() : null,
217       procProto.getLastUpdate(),
218       procProto.getStartTime(),
219       procProto.getState() == ProcedureState.FINISHED ? procProto.getResult().toByteArray() : null);
220   }
221 
222   /**
223   * Check if the user is this procedure's owner
224   * @param owner the owner field of the procedure
225   * @param user the user
226   * @return true if the user is the owner of the procedure,
227   *   false otherwise or the owner is unknown.
228   */
229   @InterfaceAudience.Private
230   public static boolean isProcedureOwner(final ProcedureInfo procInfo, final User user) {
231     if (user == null) {
232       return false;
233     }
234     String procOwner = procInfo.getProcOwner();
235     if (procOwner == null) {
236       return false;
237     }
238     return procOwner.equals(user.getShortName());
239   }
240 }