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 java.io.IOException;
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Map;
024import java.util.concurrent.TimeUnit;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.TableName;
028import org.apache.hadoop.hbase.client.Append;
029import org.apache.hadoop.hbase.client.Delete;
030import org.apache.hadoop.hbase.client.Durability;
031import org.apache.hadoop.hbase.client.Get;
032import org.apache.hadoop.hbase.client.Increment;
033import org.apache.hadoop.hbase.client.Put;
034import org.apache.hadoop.hbase.client.RegionLocator;
035import org.apache.hadoop.hbase.client.Result;
036import org.apache.hadoop.hbase.client.ResultScanner;
037import org.apache.hadoop.hbase.client.Row;
038import org.apache.hadoop.hbase.client.RowMutations;
039import org.apache.hadoop.hbase.client.Scan;
040import org.apache.hadoop.hbase.client.Table;
041import org.apache.hadoop.hbase.client.TableDescriptor;
042import org.apache.hadoop.hbase.client.coprocessor.Batch.Call;
043import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback;
044import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
045import org.apache.hadoop.hbase.filter.Filter;
046import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
047
048import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor;
049import org.apache.hbase.thirdparty.com.google.protobuf.Message;
050import org.apache.hbase.thirdparty.com.google.protobuf.Service;
051import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
052
053/**
054 * An implementation of {@link Table} that sits directly on a Region; it decorates the passed in
055 * Region instance with the Table API. Some API is not implemented yet (throws
056 * {@link UnsupportedOperationException}) mostly because no need as yet or it necessitates copying a
057 * load of code local from RegionServer.
058 * <p>
059 * Use as an instance of a {@link Table} in-the-small -- no networking or servers necessary -- or to
060 * write a test that can run directly against the datastore and then over the network.
061 */
062public class RegionAsTable implements Table {
063  private final Region region;
064
065  /**
066   * @param region Region to decorate with Table API.
067   */
068  public RegionAsTable(final Region region) {
069    this.region = region;
070  }
071
072  @Override
073  public TableName getName() {
074    return this.region.getTableDescriptor().getTableName();
075  }
076
077  @Override
078  public Configuration getConfiguration() {
079    throw new UnsupportedOperationException();
080  }
081
082  @Override
083  public TableDescriptor getDescriptor() throws IOException {
084    return this.region.getTableDescriptor();
085  }
086
087  @Override
088  public boolean exists(Get get) throws IOException {
089    if (!get.isCheckExistenceOnly()) throw new IllegalArgumentException();
090    return get(get) != null;
091  }
092
093  @Override
094  public boolean[] exists(List<Get> gets) throws IOException {
095    boolean[] results = new boolean[gets.size()];
096    int index = 0;
097    for (Get get : gets) {
098      results[index++] = exists(get);
099    }
100    return results;
101  }
102
103  @Override
104  public void batch(List<? extends Row> actions, Object[] results)
105    throws IOException, InterruptedException {
106    throw new UnsupportedOperationException();
107  }
108
109  @Override
110  public <R> void batchCallback(List<? extends Row> actions, Object[] results, Callback<R> callback)
111    throws IOException, InterruptedException {
112    throw new UnsupportedOperationException();
113  }
114
115  @Override
116  public Result get(Get get) throws IOException {
117    return this.region.get(get);
118  }
119
120  @Override
121  public Result[] get(List<Get> gets) throws IOException {
122    Result[] results = new Result[gets.size()];
123    int index = 0;
124    for (Get get : gets) {
125      results[index++] = get(get);
126    }
127    return results;
128  }
129
130  static class RegionScannerToResultScannerAdaptor implements ResultScanner {
131
132    private final RegionScanner scanner;
133
134    private boolean moreRows = true;
135
136    private final List<Cell> cells = new ArrayList<>();
137
138    RegionScannerToResultScannerAdaptor(final RegionScanner scanner) {
139      this.scanner = scanner;
140    }
141
142    @Override
143    public Result next() throws IOException {
144      if (!moreRows) {
145        return null;
146      }
147      for (;;) {
148        moreRows = scanner.next(cells);
149        if (cells.isEmpty()) {
150          if (!moreRows) {
151            return null;
152          } else {
153            continue;
154          }
155        }
156        Result result = Result.create(cells);
157        cells.clear();
158        return result;
159      }
160    }
161
162    @Override
163    public void close() {
164      try {
165        scanner.close();
166      } catch (IOException e) {
167        throw new RuntimeException(e);
168      }
169    }
170
171    @Override
172    public boolean renewLease() {
173      throw new UnsupportedOperationException();
174    }
175
176    @Override
177    public ScanMetrics getScanMetrics() {
178      return null;
179    }
180  }
181
182  @Override
183  public ResultScanner getScanner(Scan scan) throws IOException {
184    return new RegionScannerToResultScannerAdaptor(this.region.getScanner(scan));
185  }
186
187  @Override
188  public ResultScanner getScanner(byte[] family) throws IOException {
189    return getScanner(new Scan().addFamily(family));
190  }
191
192  @Override
193  public ResultScanner getScanner(byte[] family, byte[] qualifier) throws IOException {
194    return getScanner(new Scan().addColumn(family, qualifier));
195  }
196
197  @Override
198  public void put(Put put) throws IOException {
199    this.region.put(put);
200  }
201
202  @Override
203  public void put(List<Put> puts) throws IOException {
204    for (Put put : puts)
205      put(put);
206  }
207
208  @Override
209  public void delete(Delete delete) throws IOException {
210    this.region.delete(delete);
211  }
212
213  @Override
214  public void delete(List<Delete> deletes) throws IOException {
215    for (Delete delete : deletes)
216      delete(delete);
217  }
218
219  @Override
220  public CheckAndMutateBuilder checkAndMutate(byte[] row, byte[] family) {
221    throw new UnsupportedOperationException();
222  }
223
224  @Override
225  public CheckAndMutateWithFilterBuilder checkAndMutate(byte[] row, Filter filter) {
226    throw new UnsupportedOperationException();
227  }
228
229  @Override
230  public Result mutateRow(RowMutations rm) throws IOException {
231    throw new UnsupportedOperationException();
232  }
233
234  @Override
235  public Result append(Append append) throws IOException {
236    return this.region.append(append);
237  }
238
239  @Override
240  public Result increment(Increment increment) throws IOException {
241    return this.region.increment(increment);
242  }
243
244  @Override
245  public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount)
246    throws IOException {
247    throw new UnsupportedOperationException();
248  }
249
250  @Override
251  public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount,
252    Durability durability) throws IOException {
253    throw new UnsupportedOperationException();
254  }
255
256  /**
257   * This call will NOT close the underlying region.
258   */
259  @Override
260  public void close() throws IOException {
261  }
262
263  @Override
264  public CoprocessorRpcChannel coprocessorService(byte[] row) {
265    throw new UnsupportedOperationException();
266  }
267
268  @Override
269  public <T extends Service, R> Map<byte[], R> coprocessorService(Class<T> service, byte[] startKey,
270    byte[] endKey, Call<T, R> callable) throws ServiceException, Throwable {
271    throw new UnsupportedOperationException();
272  }
273
274  @Override
275  public <T extends Service, R> void coprocessorService(Class<T> service, byte[] startKey,
276    byte[] endKey, Call<T, R> callable, Callback<R> callback) throws ServiceException, Throwable {
277    throw new UnsupportedOperationException();
278  }
279
280  @Override
281  public <R extends Message> Map<byte[], R> batchCoprocessorService(
282    MethodDescriptor methodDescriptor, Message request, byte[] startKey, byte[] endKey,
283    R responsePrototype) throws ServiceException, Throwable {
284    throw new UnsupportedOperationException();
285  }
286
287  @Override
288  public <R extends Message> void batchCoprocessorService(MethodDescriptor methodDescriptor,
289    Message request, byte[] startKey, byte[] endKey, R responsePrototype, Callback<R> callback)
290    throws ServiceException, Throwable {
291    throw new UnsupportedOperationException();
292  }
293
294  @Override
295  public long getReadRpcTimeout(TimeUnit unit) {
296    throw new UnsupportedOperationException();
297  }
298
299  @Override
300  public long getOperationTimeout(TimeUnit unit) {
301    throw new UnsupportedOperationException();
302  }
303
304  @Override
305  public long getWriteRpcTimeout(TimeUnit unit) {
306    throw new UnsupportedOperationException();
307  }
308
309  @Override
310  public long getRpcTimeout(TimeUnit unit) {
311    throw new UnsupportedOperationException();
312  }
313
314  @Override
315  public RegionLocator getRegionLocator() throws IOException {
316    throw new UnsupportedOperationException();
317  }
318}