001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import com.google.protobuf.Descriptors.MethodDescriptor;
021import com.google.protobuf.Message;
022import com.google.protobuf.Service;
023import com.google.protobuf.ServiceException;
024import java.io.IOException;
025import java.util.ArrayList;
026import java.util.List;
027import java.util.Map;
028import java.util.concurrent.TimeUnit;
029import org.apache.hadoop.conf.Configuration;
030import org.apache.hadoop.hbase.Cell;
031import org.apache.hadoop.hbase.CompareOperator;
032import org.apache.hadoop.hbase.HTableDescriptor;
033import org.apache.hadoop.hbase.TableName;
034import org.apache.hadoop.hbase.client.Append;
035import org.apache.hadoop.hbase.client.Delete;
036import org.apache.hadoop.hbase.client.Durability;
037import org.apache.hadoop.hbase.client.Get;
038import org.apache.hadoop.hbase.client.Increment;
039import org.apache.hadoop.hbase.client.Put;
040import org.apache.hadoop.hbase.client.RegionLocator;
041import org.apache.hadoop.hbase.client.Result;
042import org.apache.hadoop.hbase.client.ResultScanner;
043import org.apache.hadoop.hbase.client.Row;
044import org.apache.hadoop.hbase.client.RowMutations;
045import org.apache.hadoop.hbase.client.Scan;
046import org.apache.hadoop.hbase.client.Table;
047import org.apache.hadoop.hbase.client.TableDescriptor;
048import org.apache.hadoop.hbase.client.coprocessor.Batch.Call;
049import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback;
050import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
051import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
052import org.apache.hadoop.hbase.filter.Filter;
053import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
054
055/**
056 * An implementation of {@link Table} that sits directly on a Region; it decorates the passed in
057 * Region instance with the Table API. Some API is not implemented yet (throws
058 * {@link UnsupportedOperationException}) mostly because no need as yet or it necessitates copying a
059 * load of code local from RegionServer.
060 * <p>
061 * Use as an instance of a {@link Table} in-the-small -- no networking or servers necessary -- or to
062 * write a test that can run directly against the datastore and then over the network.
063 */
064public class RegionAsTable implements Table {
065  private final Region region;
066
067  /**
068   * @param region Region to decorate with Table API.
069   */
070  public RegionAsTable(final Region region) {
071    this.region = region;
072  }
073
074  @Override
075  public TableName getName() {
076    return this.region.getTableDescriptor().getTableName();
077  }
078
079  @Override
080  public Configuration getConfiguration() {
081    throw new UnsupportedOperationException();
082  }
083
084  @Override
085  @Deprecated
086  public HTableDescriptor getTableDescriptor() throws IOException {
087    return new HTableDescriptor(this.region.getTableDescriptor());
088  }
089
090  @Override
091  public TableDescriptor getDescriptor() throws IOException {
092    return this.region.getTableDescriptor();
093  }
094
095  @Override
096  public boolean exists(Get get) throws IOException {
097    if (!get.isCheckExistenceOnly()) throw new IllegalArgumentException();
098    return get(get) != null;
099  }
100
101  @Override
102  public boolean[] exists(List<Get> gets) throws IOException {
103    boolean[] results = new boolean[gets.size()];
104    int index = 0;
105    for (Get get : gets) {
106      results[index++] = exists(get);
107    }
108    return results;
109  }
110
111  @Override
112  public void batch(List<? extends Row> actions, Object[] results)
113    throws IOException, InterruptedException {
114    throw new UnsupportedOperationException();
115  }
116
117  @Override
118  public <R> void batchCallback(List<? extends Row> actions, Object[] results, Callback<R> callback)
119    throws IOException, InterruptedException {
120    throw new UnsupportedOperationException();
121  }
122
123  @Override
124  public Result get(Get get) throws IOException {
125    return this.region.get(get);
126  }
127
128  @Override
129  public Result[] get(List<Get> gets) throws IOException {
130    Result[] results = new Result[gets.size()];
131    int index = 0;
132    for (Get get : gets) {
133      results[index++] = get(get);
134    }
135    return results;
136  }
137
138  static class RegionScannerToResultScannerAdaptor implements ResultScanner {
139
140    private final RegionScanner scanner;
141
142    private boolean moreRows = true;
143
144    private final List<Cell> cells = new ArrayList<>();
145
146    RegionScannerToResultScannerAdaptor(final RegionScanner scanner) {
147      this.scanner = scanner;
148    }
149
150    @Override
151    public Result next() throws IOException {
152      if (!moreRows) {
153        return null;
154      }
155      for (;;) {
156        moreRows = scanner.next(cells);
157        if (cells.isEmpty()) {
158          if (!moreRows) {
159            return null;
160          } else {
161            continue;
162          }
163        }
164        Result result = Result.create(cells);
165        cells.clear();
166        return result;
167      }
168    }
169
170    @Override
171    public void close() {
172      try {
173        scanner.close();
174      } catch (IOException e) {
175        throw new RuntimeException(e);
176      }
177    }
178
179    @Override
180    public boolean renewLease() {
181      throw new UnsupportedOperationException();
182    }
183
184    @Override
185    public ScanMetrics getScanMetrics() {
186      return null;
187    }
188  };
189
190  @Override
191  public ResultScanner getScanner(Scan scan) throws IOException {
192    return new RegionScannerToResultScannerAdaptor(this.region.getScanner(scan));
193  }
194
195  @Override
196  public ResultScanner getScanner(byte[] family) throws IOException {
197    return getScanner(new Scan().addFamily(family));
198  }
199
200  @Override
201  public ResultScanner getScanner(byte[] family, byte[] qualifier) throws IOException {
202    return getScanner(new Scan().addColumn(family, qualifier));
203  }
204
205  @Override
206  public void put(Put put) throws IOException {
207    this.region.put(put);
208  }
209
210  @Override
211  public void put(List<Put> puts) throws IOException {
212    for (Put put : puts)
213      put(put);
214  }
215
216  @Override
217  @Deprecated
218  public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)
219    throws IOException {
220    throw new UnsupportedOperationException();
221  }
222
223  @Override
224  @Deprecated
225  public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
226    byte[] value, Put put) throws IOException {
227    throw new UnsupportedOperationException();
228  }
229
230  @Override
231  @Deprecated
232  public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp,
233    byte[] value, Put put) throws IOException {
234    throw new UnsupportedOperationException();
235  }
236
237  @Override
238  public void delete(Delete delete) throws IOException {
239    this.region.delete(delete);
240  }
241
242  @Override
243  public void delete(List<Delete> deletes) throws IOException {
244    for (Delete delete : deletes)
245      delete(delete);
246  }
247
248  @Override
249  public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value,
250    Delete delete) throws IOException {
251    throw new UnsupportedOperationException();
252  }
253
254  @Override
255  @Deprecated
256  public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
257    byte[] value, Delete delete) throws IOException {
258    throw new UnsupportedOperationException();
259  }
260
261  @Override
262  @Deprecated
263  public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
264    CompareOperator compareOp, byte[] value, Delete delete) throws IOException {
265    throw new UnsupportedOperationException();
266  }
267
268  @Override
269  public CheckAndMutateBuilder checkAndMutate(byte[] row, byte[] family) {
270    throw new UnsupportedOperationException();
271  }
272
273  @Override
274  public CheckAndMutateWithFilterBuilder checkAndMutate(byte[] row, Filter filter) {
275    throw new UnsupportedOperationException();
276  }
277
278  @Override
279  public Result mutateRow(RowMutations rm) throws IOException {
280    throw new UnsupportedOperationException();
281  }
282
283  @Override
284  public Result append(Append append) throws IOException {
285    return this.region.append(append);
286  }
287
288  @Override
289  public Result increment(Increment increment) throws IOException {
290    return this.region.increment(increment);
291  }
292
293  @Override
294  public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount)
295    throws IOException {
296    throw new UnsupportedOperationException();
297  }
298
299  @Override
300  public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount,
301    Durability durability) throws IOException {
302    throw new UnsupportedOperationException();
303  }
304
305  /**
306   * This call will NOT close the underlying region.
307   */
308  @Override
309  public void close() throws IOException {
310  }
311
312  @Override
313  public CoprocessorRpcChannel coprocessorService(byte[] row) {
314    throw new UnsupportedOperationException();
315  }
316
317  @Override
318  public <T extends Service, R> Map<byte[], R> coprocessorService(Class<T> service, byte[] startKey,
319    byte[] endKey, Call<T, R> callable) throws ServiceException, Throwable {
320    throw new UnsupportedOperationException();
321  }
322
323  @Override
324  public <T extends Service, R> void coprocessorService(Class<T> service, byte[] startKey,
325    byte[] endKey, Call<T, R> callable, Callback<R> callback) throws ServiceException, Throwable {
326    throw new UnsupportedOperationException();
327  }
328
329  @Override
330  public <R extends Message> Map<byte[], R> batchCoprocessorService(
331    MethodDescriptor methodDescriptor, Message request, byte[] startKey, byte[] endKey,
332    R responsePrototype) throws ServiceException, Throwable {
333    throw new UnsupportedOperationException();
334  }
335
336  @Override
337  public <R extends Message> void batchCoprocessorService(MethodDescriptor methodDescriptor,
338    Message request, byte[] startKey, byte[] endKey, R responsePrototype, Callback<R> callback)
339    throws ServiceException, Throwable {
340    throw new UnsupportedOperationException();
341  }
342
343  @Override
344  @Deprecated
345  public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
346    byte[] value, RowMutations mutation) throws IOException {
347    throw new UnsupportedOperationException();
348  }
349
350  @Override
351  @Deprecated
352  public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier,
353    CompareOperator compareOp, byte[] value, RowMutations mutation) throws IOException {
354    throw new UnsupportedOperationException();
355  }
356
357  @Override
358  @Deprecated
359  public void setOperationTimeout(int operationTimeout) {
360    throw new UnsupportedOperationException();
361  }
362
363  @Override
364  @Deprecated
365  public int getOperationTimeout() {
366    throw new UnsupportedOperationException();
367  }
368
369  @Override
370  @Deprecated
371  public void setRpcTimeout(int rpcTimeout) {
372    throw new UnsupportedOperationException();
373  }
374
375  @Override
376  public long getReadRpcTimeout(TimeUnit unit) {
377    throw new UnsupportedOperationException();
378  }
379
380  @Override
381  @Deprecated
382  public void setWriteRpcTimeout(int writeRpcTimeout) {
383    throw new UnsupportedOperationException();
384  }
385
386  @Override
387  public long getOperationTimeout(TimeUnit unit) {
388    throw new UnsupportedOperationException();
389  }
390
391  @Override
392  @Deprecated
393  public void setReadRpcTimeout(int readRpcTimeout) {
394    throw new UnsupportedOperationException();
395  }
396
397  @Override
398  public long getWriteRpcTimeout(TimeUnit unit) {
399    throw new UnsupportedOperationException();
400  }
401
402  @Override
403  @Deprecated
404  public int getRpcTimeout() {
405    throw new UnsupportedOperationException();
406  }
407
408  @Override
409  public long getRpcTimeout(TimeUnit unit) {
410    throw new UnsupportedOperationException();
411  }
412
413  @Override
414  @Deprecated
415  public int getWriteRpcTimeout() {
416    throw new UnsupportedOperationException();
417  }
418
419  @Override
420  @Deprecated
421  public int getReadRpcTimeout() {
422    throw new UnsupportedOperationException();
423  }
424
425  @Override
426  public RegionLocator getRegionLocator() throws IOException {
427    throw new UnsupportedOperationException();
428  }
429}