View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.thrift2;
20  
21  import org.apache.hadoop.classification.InterfaceAudience;
22  import org.apache.hadoop.hbase.HConstants;
23  import org.apache.hadoop.hbase.KeyValue;
24  import org.apache.hadoop.hbase.KeyValueUtil;
25  import org.apache.hadoop.hbase.client.*;
26  import org.apache.hadoop.hbase.thrift2.generated.*;
27  
28  import java.io.IOException;
29  import java.nio.ByteBuffer;
30  import java.util.*;
31  
32  @InterfaceAudience.Private
33  public class ThriftUtilities {
34  
35    private ThriftUtilities() {
36      throw new UnsupportedOperationException("Can't initialize class");
37    }
38  
39    /**
40     * Creates a {@link Get} (HBase) from a {@link TGet} (Thrift).
41     *
42     * This ignores any timestamps set on {@link TColumn} objects.
43     *
44     * @param in the <code>TGet</code> to convert
45     *
46     * @return <code>Get</code> object
47     *
48     * @throws IOException if an invalid time range or max version parameter is given
49     */
50    public static Get getFromThrift(TGet in) throws IOException {
51      Get out = new Get(in.getRow());
52  
53      // Timestamp overwrites time range if both are set
54      if (in.isSetTimestamp()) {
55        out.setTimeStamp(in.getTimestamp());
56      } else if (in.isSetTimeRange()) {
57        out.setTimeRange(in.getTimeRange().getMinStamp(), in.getTimeRange().getMaxStamp());
58      }
59  
60      if (in.isSetMaxVersions()) {
61        out.setMaxVersions(in.getMaxVersions());
62      }
63  
64      if (!in.isSetColumns()) {
65        return out;
66      }
67  
68      for (TColumn column : in.getColumns()) {
69        if (column.isSetQualifier()) {
70          out.addColumn(column.getFamily(), column.getQualifier());
71        } else {
72          out.addFamily(column.getFamily());
73        }
74      }
75  
76      return out;
77    }
78  
79    /**
80     * Converts multiple {@link TGet}s (Thrift) into a list of {@link Get}s (HBase).
81     *
82     * @param in list of <code>TGet</code>s to convert
83     *
84     * @return list of <code>Get</code> objects
85     *
86     * @throws IOException if an invalid time range or max version parameter is given
87     * @see #getFromThrift(TGet)
88     */
89    public static List<Get> getsFromThrift(List<TGet> in) throws IOException {
90      List<Get> out = new ArrayList<Get>(in.size());
91      for (TGet get : in) {
92        out.add(getFromThrift(get));
93      }
94      return out;
95    }
96  
97    /**
98     * Creates a {@link TResult} (Thrift) from a {@link Result} (HBase).
99     *
100    * @param in the <code>Result</code> to convert
101    *
102    * @return converted result, returns an empty result if the input is <code>null</code>
103    */
104   public static TResult resultFromHBase(Result in) {
105     KeyValue[] raw = in.raw();
106     TResult out = new TResult();
107     byte[] row = in.getRow();
108     if (row != null) {
109       out.setRow(in.getRow());
110     }
111     List<TColumnValue> columnValues = new ArrayList<TColumnValue>();
112     for (KeyValue kv : raw) {
113       TColumnValue col = new TColumnValue();
114       col.setFamily(kv.getFamily());
115       col.setQualifier(kv.getQualifier());
116       col.setTimestamp(kv.getTimestamp());
117       col.setValue(kv.getValue());
118       columnValues.add(col);
119     }
120     out.setColumnValues(columnValues);
121     return out;
122   }
123 
124   /**
125    * Converts multiple {@link Result}s (HBase) into a list of {@link TResult}s (Thrift).
126    *
127    * @param in array of <code>Result</code>s to convert
128    *
129    * @return list of converted <code>TResult</code>s
130    *
131    * @see #resultFromHBase(Result)
132    */
133   public static List<TResult> resultsFromHBase(Result[] in) {
134     List<TResult> out = new ArrayList<TResult>(in.length);
135     for (Result result : in) {
136       out.add(resultFromHBase(result));
137     }
138     return out;
139   }
140 
141   /**
142    * Creates a {@link Put} (HBase) from a {@link TPut} (Thrift)
143    *
144    * @param in the <code>TPut</code> to convert
145    *
146    * @return converted <code>Put</code>
147    */
148   public static Put putFromThrift(TPut in) {
149     Put out;
150 
151     if (in.isSetTimestamp()) {
152       out = new Put(in.getRow(), in.getTimestamp());
153     } else {
154       out = new Put(in.getRow());
155     }
156 
157     out.setWriteToWAL(in.isWriteToWal());
158 
159     for (TColumnValue columnValue : in.getColumnValues()) {
160       if (columnValue.isSetTimestamp()) {
161         out.add(columnValue.getFamily(), columnValue.getQualifier(), columnValue.getTimestamp(),
162             columnValue.getValue());
163       } else {
164         out.add(columnValue.getFamily(), columnValue.getQualifier(), columnValue.getValue());
165       }
166     }
167 
168     return out;
169   }
170 
171   /**
172    * Converts multiple {@link TPut}s (Thrift) into a list of {@link Put}s (HBase).
173    *
174    * @param in list of <code>TPut</code>s to convert
175    *
176    * @return list of converted <code>Put</code>s
177    *
178    * @see #putFromThrift(TPut)
179    */
180   public static List<Put> putsFromThrift(List<TPut> in) {
181     List<Put> out = new ArrayList<Put>(in.size());
182     for (TPut put : in) {
183       out.add(putFromThrift(put));
184     }
185     return out;
186   }
187 
188   /**
189    * Creates a {@link Delete} (HBase) from a {@link TDelete} (Thrift).
190    *
191    * @param in the <code>TDelete</code> to convert
192    *
193    * @return converted <code>Delete</code>
194    */
195   public static Delete deleteFromThrift(TDelete in) {
196     Delete out;
197 
198     if (in.isSetColumns()) {
199       out = new Delete(in.getRow());
200       for (TColumn column : in.getColumns()) {
201         if (column.isSetQualifier()) {
202           if (column.isSetTimestamp()) {
203             if (in.isSetDeleteType() &&
204                 in.getDeleteType().equals(TDeleteType.DELETE_COLUMNS))
205               out.deleteColumns(column.getFamily(), column.getQualifier(), column.getTimestamp());
206             else
207               out.deleteColumn(column.getFamily(), column.getQualifier(), column.getTimestamp());
208           } else {
209             if (in.isSetDeleteType() &&
210                 in.getDeleteType().equals(TDeleteType.DELETE_COLUMNS))
211               out.deleteColumns(column.getFamily(), column.getQualifier());
212             else
213               out.deleteColumn(column.getFamily(), column.getQualifier());
214           }
215 
216         } else {
217           if (column.isSetTimestamp()) {
218             out.deleteFamily(column.getFamily(), column.getTimestamp());
219           } else {
220             out.deleteFamily(column.getFamily());
221           }
222         }
223       }
224     } else {
225       if (in.isSetTimestamp()) {
226         out = new Delete(in.getRow(), in.getTimestamp());
227       } else {
228         out = new Delete(in.getRow());
229       }
230     }
231     out.setWriteToWAL(in.isWriteToWal());
232     return out;
233   }
234 
235   /**
236    * Converts multiple {@link TDelete}s (Thrift) into a list of {@link Delete}s (HBase).
237    *
238    * @param in list of <code>TDelete</code>s to convert
239    *
240    * @return list of converted <code>Delete</code>s
241    *
242    * @see #deleteFromThrift(TDelete)
243    */
244 
245   public static List<Delete> deletesFromThrift(List<TDelete> in) {
246     List<Delete> out = new ArrayList<Delete>(in.size());
247     for (TDelete delete : in) {
248       out.add(deleteFromThrift(delete));
249     }
250     return out;
251   }
252 
253   public static TDelete deleteFromHBase(Delete in) {
254     TDelete out = new TDelete(ByteBuffer.wrap(in.getRow()));
255 
256     List<TColumn> columns = new ArrayList<TColumn>();
257     long rowTimestamp = in.getTimeStamp();
258     if (rowTimestamp != HConstants.LATEST_TIMESTAMP) {
259       out.setTimestamp(rowTimestamp);
260     }
261 
262     // Map<family, List<KeyValue>>
263     for (Map.Entry<byte[], List<? extends org.apache.hadoop.hbase.Cell>> familyEntry:
264         in.getFamilyMap().entrySet()) {
265       TColumn column = new TColumn(ByteBuffer.wrap(familyEntry.getKey()));
266       for (org.apache.hadoop.hbase.Cell cell: familyEntry.getValue()) {
267         KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
268         byte[] family = kv.getFamily();
269         byte[] qualifier = kv.getQualifier();
270         long timestamp = kv.getTimestamp();
271         if (family != null) {
272           column.setFamily(family);
273         }
274         if (qualifier != null) {
275           column.setQualifier(qualifier);
276         }
277         if (timestamp != HConstants.LATEST_TIMESTAMP) {
278           column.setTimestamp(kv.getTimestamp());
279         }
280       }
281       columns.add(column);
282     }
283     out.setColumns(columns);
284 
285     return out;
286   }
287 
288   public static Scan scanFromThrift(TScan in) throws IOException {
289     Scan out = new Scan();
290 
291     if (in.isSetStartRow())
292       out.setStartRow(in.getStartRow());
293     if (in.isSetStopRow())
294       out.setStopRow(in.getStopRow());
295     if (in.isSetCaching())
296       out.setCaching(in.getCaching());
297     if (in.isSetMaxVersions()) {
298       out.setMaxVersions(in.getMaxVersions());
299     }
300 
301     if (in.isSetColumns()) {
302       for (TColumn column : in.getColumns()) {
303         if (column.isSetQualifier()) {
304           out.addColumn(column.getFamily(), column.getQualifier());
305         } else {
306           out.addFamily(column.getFamily());
307         }
308       }
309     }
310 
311     TTimeRange timeRange = in.getTimeRange();
312     if (timeRange != null &&
313         timeRange.isSetMinStamp() && timeRange.isSetMaxStamp()) {
314       out.setTimeRange(timeRange.getMinStamp(), timeRange.getMaxStamp());
315     }
316 
317     return out;
318   }
319 
320   public static Increment incrementFromThrift(TIncrement in) throws IOException {
321     Increment out = new Increment(in.getRow());
322     for (TColumnIncrement column : in.getColumns()) {
323       out.addColumn(column.getFamily(), column.getQualifier(), column.getAmount());
324     }
325     out.setWriteToWAL(in.isWriteToWal());
326     return out;
327   }
328 }