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  package org.apache.hadoop.hbase.master;
19  
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.net.InetSocketAddress;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Random;
27  import java.util.TreeMap;
28  import java.util.concurrent.ConcurrentSkipListMap;
29  
30  import org.apache.hadoop.conf.Configuration;
31  import org.apache.hadoop.fs.FileSystem;
32  import org.apache.hadoop.hbase.CellScannable;
33  import org.apache.hadoop.hbase.CellUtil;
34  import org.apache.hadoop.hbase.TableName;
35  import org.apache.hadoop.hbase.HRegionInfo;
36  import org.apache.hadoop.hbase.ServerName;
37  import org.apache.hadoop.hbase.ZooKeeperConnectionException;
38  import org.apache.hadoop.hbase.catalog.CatalogTracker;
39  import org.apache.hadoop.hbase.client.Get;
40  import org.apache.hadoop.hbase.client.Result;
41  import org.apache.hadoop.hbase.client.Scan;
42  import org.apache.hadoop.hbase.executor.ExecutorService;
43  import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController;
44  import org.apache.hadoop.hbase.ipc.RpcServerInterface;
45  import org.apache.hadoop.hbase.master.TableLockManager.NullTableLockManager;
46  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
47  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
48  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionRequest;
49  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CloseRegionResponse;
50  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionRequest;
51  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.CompactRegionResponse;
52  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionRequest;
53  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.FlushRegionResponse;
54  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionRequest;
55  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetOnlineRegionResponse;
56  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoRequest;
57  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse;
58  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
59  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoResponse;
60  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest;
61  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileResponse;
62  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsRequest;
63  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.MergeRegionsResponse;
64  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest;
65  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionResponse;
66  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ReplicateWALEntryRequest;
67  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ReplicateWALEntryResponse;
68  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterRequest;
69  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.RollWALWriterResponse;
70  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest;
71  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionResponse;
72  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerRequest;
73  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.StopServerResponse;
74  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
75  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
76  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileResponse;
77  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
78  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetResponse;
79  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiGetRequest;
80  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiGetResponse;
81  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest;
82  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiResponse;
83  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
84  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateResponse;
85  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultCellMeta;
86  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
87  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
88  import org.apache.hadoop.hbase.regionserver.CompactionRequestor;
89  import org.apache.hadoop.hbase.regionserver.FlushRequester;
90  import org.apache.hadoop.hbase.regionserver.HRegion;
91  import org.apache.hadoop.hbase.regionserver.Leases;
92  import org.apache.hadoop.hbase.regionserver.RegionServerAccounting;
93  import org.apache.hadoop.hbase.regionserver.RegionServerServices;
94  import org.apache.hadoop.hbase.regionserver.wal.HLog;
95  import org.apache.hadoop.hbase.util.Bytes;
96  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
97  import org.apache.zookeeper.KeeperException;
98  
99  import com.google.protobuf.RpcController;
100 import com.google.protobuf.ServiceException;
101 
102 /**
103  * A mock RegionServer implementation.
104  * Use this when you can't bend Mockito to your liking (e.g. return null result
105  * when 'scanning' until master timesout and then return a coherent meta row
106  * result thereafter.  Have some facility for faking gets and scans.  See
107  * {@link #setGetResult(byte[], byte[], Result)} for how to fill the backing data
108  * store that the get pulls from.
109  */
110 class MockRegionServer
111 implements AdminProtos.AdminService.BlockingInterface,
112 ClientProtos.ClientService.BlockingInterface, RegionServerServices {
113   private final ServerName sn;
114   private final ZooKeeperWatcher zkw;
115   private final Configuration conf;
116   private final Random random = new Random();
117 
118   /**
119    * Map of regions to map of rows and {@link Results}.  Used as data source when
120    * {@link MockRegionServer#get(byte[], Get)} is called. Because we have a byte
121    * key, need to use TreeMap and provide a Comparator.  Use
122    * {@link #setGetResult(byte[], byte[], Result)} filling this map.
123    */
124   private final Map<byte [], Map<byte [], Result>> gets =
125     new TreeMap<byte [], Map<byte [], Result>>(Bytes.BYTES_COMPARATOR);
126 
127   /**
128    * Map of regions to results to return when scanning.
129    */
130   private final Map<byte [], Result []> nexts =
131     new TreeMap<byte [], Result []>(Bytes.BYTES_COMPARATOR);
132 
133   /**
134    * Data structure that holds regionname and index used scanning.
135    */
136   class RegionNameAndIndex {
137     private final byte[] regionName;
138     private int index = 0;
139 
140     RegionNameAndIndex(final byte[] regionName) {
141       this.regionName = regionName;
142     }
143 
144     byte[] getRegionName() {
145       return this.regionName;
146     }
147 
148     int getThenIncrement() {
149       int currentIndex = this.index;
150       this.index++;
151       return currentIndex;
152     }
153   }
154 
155   /**
156    * Outstanding scanners and their offset into <code>nexts</code>
157    */
158   private final Map<Long, RegionNameAndIndex> scannersAndOffsets =
159     new HashMap<Long, RegionNameAndIndex>();
160 
161   /**
162    * @param sn Name of this mock regionserver
163    * @throws IOException
164    * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException
165    */
166   MockRegionServer(final Configuration conf, final ServerName sn)
167   throws ZooKeeperConnectionException, IOException {
168     this.sn = sn;
169     this.conf = conf;
170     this.zkw = new ZooKeeperWatcher(conf, sn.toString(), this, true);
171   }
172 
173   /**
174    * Use this method filling the backing data source used by {@link #get(byte[], Get)}
175    * @param regionName
176    * @param row
177    * @param r
178    */
179   void setGetResult(final byte [] regionName, final byte [] row, final Result r) {
180     Map<byte [], Result> value = this.gets.get(regionName);
181     if (value == null) {
182       // If no value already, create one.  Needs to be treemap because we are
183       // using byte array as key.   Not thread safe.
184       value = new TreeMap<byte [], Result>(Bytes.BYTES_COMPARATOR);
185       this.gets.put(regionName, value);
186     }
187     value.put(row, r);
188   }
189 
190   /**
191    * Use this method to set what a scanner will reply as we next through
192    * @param regionName
193    * @param rs
194    */
195   void setNextResults(final byte [] regionName, final Result [] rs) {
196     this.nexts.put(regionName, rs);
197   }
198 
199   @Override
200   public boolean isStopped() {
201     // TODO Auto-generated method stub
202     return false;
203   }
204 
205   @Override
206   public void abort(String why, Throwable e) {
207     throw new RuntimeException(this.sn + ": " + why, e);
208   }
209 
210   @Override
211   public boolean isAborted() {
212     return false;
213   }
214 
215   public long openScanner(byte[] regionName, Scan scan) throws IOException {
216     long scannerId = this.random.nextLong();
217     this.scannersAndOffsets.put(scannerId, new RegionNameAndIndex(regionName));
218     return scannerId;
219   }
220 
221   public Result next(long scannerId) throws IOException {
222     RegionNameAndIndex rnai = this.scannersAndOffsets.get(scannerId);
223     int index = rnai.getThenIncrement();
224     Result [] results = this.nexts.get(rnai.getRegionName());
225     if (results == null) return null;
226     return index < results.length? results[index]: null;
227   }
228 
229   public Result [] next(long scannerId, int numberOfRows) throws IOException {
230     // Just return one result whatever they ask for.
231     Result r = next(scannerId);
232     return r == null? null: new Result [] {r};
233   }
234 
235   public void close(final long scannerId) throws IOException {
236     this.scannersAndOffsets.remove(scannerId);
237   }
238 
239   @Override
240   public void stop(String why) {
241     this.zkw.close();
242   }
243 
244   @Override
245   public void addToOnlineRegions(HRegion r) {
246     // TODO Auto-generated method stub
247   }
248 
249   @Override
250   public boolean removeFromOnlineRegions(HRegion r, ServerName destination) {
251     // TODO Auto-generated method stub
252     return false;
253   }
254 
255   @Override
256   public HRegion getFromOnlineRegions(String encodedRegionName) {
257     // TODO Auto-generated method stub
258     return null;
259   }
260 
261   @Override
262   public Configuration getConfiguration() {
263     return this.conf;
264   }
265 
266   @Override
267   public ZooKeeperWatcher getZooKeeper() {
268     return this.zkw;
269   }
270 
271   @Override
272   public CatalogTracker getCatalogTracker() {
273     // TODO Auto-generated method stub
274     return null;
275   }
276 
277   @Override
278   public ServerName getServerName() {
279     return this.sn;
280   }
281 
282   @Override
283   public boolean isStopping() {
284     return false;
285   }
286 
287   @Override
288   public CompactionRequestor getCompactionRequester() {
289     // TODO Auto-generated method stub
290     return null;
291   }
292 
293   @Override
294   public FlushRequester getFlushRequester() {
295     // TODO Auto-generated method stub
296     return null;
297   }
298 
299   @Override
300   public RegionServerAccounting getRegionServerAccounting() {
301     // TODO Auto-generated method stub
302     return null;
303   }
304 
305   public TableLockManager getTableLockManager() {
306     return new NullTableLockManager();
307   }
308 
309   @Override
310   public void postOpenDeployTasks(HRegion r, CatalogTracker ct)
311       throws KeeperException, IOException {
312     // TODO Auto-generated method stub
313   }
314 
315   @Override
316   public RpcServerInterface getRpcServer() {
317     // TODO Auto-generated method stub
318     return null;
319   }
320 
321   @Override
322   public ConcurrentSkipListMap<byte[], Boolean> getRegionsInTransitionInRS() {
323     // TODO Auto-generated method stub
324     return null;
325   }
326 
327   @Override
328   public FileSystem getFileSystem() {
329     // TODO Auto-generated method stub
330     return null;
331   }
332 
333   @Override
334   public GetResponse get(RpcController controller, GetRequest request)
335   throws ServiceException {
336     byte[] regionName = request.getRegion().getValue().toByteArray();
337     Map<byte [], Result> m = this.gets.get(regionName);
338     GetResponse.Builder builder = GetResponse.newBuilder();
339     if (m != null) {
340       byte[] row = request.getGet().getRow().toByteArray();
341       builder.setResult(ProtobufUtil.toResult(m.get(row)));
342     }
343     return builder.build();
344   }
345 
346   @Override
347   public MultiGetResponse multiGet(RpcController controller, MultiGetRequest requests)
348   throws ServiceException {
349     byte[] regionName = requests.getRegion().getValue().toByteArray();
350     Map<byte [], Result> m = this.gets.get(regionName);
351     MultiGetResponse.Builder builder = MultiGetResponse.newBuilder();
352     if (m != null) {
353       for (ClientProtos.Get get: requests.getGetList()) {
354         byte[] row = get.getRow().toByteArray();
355         builder.addResult(ProtobufUtil.toResult(m.get(row)));
356       }
357     }
358     return builder.build();
359   }
360 
361 
362   @Override
363   public MutateResponse mutate(RpcController controller, MutateRequest request)
364       throws ServiceException {
365     // TODO Auto-generated method stub
366     return null;
367   }
368 
369   @Override
370   public ScanResponse scan(RpcController controller, ScanRequest request)
371       throws ServiceException {
372     ScanResponse.Builder builder = ScanResponse.newBuilder();
373     try {
374       if (request.hasScan()) {
375         byte[] regionName = request.getRegion().getValue().toByteArray();
376         builder.setScannerId(openScanner(regionName, null));
377         builder.setMoreResults(true);
378       }
379       else {
380         long scannerId = request.getScannerId();
381         Result result = next(scannerId);
382         if (result != null) {
383           ResultCellMeta.Builder metaBuilder = ResultCellMeta.newBuilder();
384           metaBuilder.addCellsLength(result.size());
385           builder.setResultCellMeta(metaBuilder.build());
386           List<CellScannable> results = new ArrayList<CellScannable>(1);
387           results.add(result);
388           ((PayloadCarryingRpcController) controller).setCellScanner(CellUtil
389               .createCellScanner(results));
390           builder.setMoreResults(true);
391         }
392         else {
393           builder.setMoreResults(false);
394           close(scannerId);
395         }
396       }
397     } catch (IOException ie) {
398       throw new ServiceException(ie);
399     }
400     return builder.build();
401   }
402 
403   @Override
404   public BulkLoadHFileResponse bulkLoadHFile(RpcController controller,
405       BulkLoadHFileRequest request) throws ServiceException {
406     // TODO Auto-generated method stub
407     return null;
408   }
409 
410   @Override
411   public ClientProtos.CoprocessorServiceResponse execService(RpcController controller,
412       ClientProtos.CoprocessorServiceRequest request) throws ServiceException {
413     return null;
414   }
415 
416   @Override
417   public org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiResponse multi(
418       RpcController controller, MultiRequest request) throws ServiceException {
419     // TODO Auto-generated method stub
420     return null;
421   }
422 
423   @Override
424   public GetRegionInfoResponse getRegionInfo(RpcController controller,
425       GetRegionInfoRequest request) throws ServiceException {
426     GetRegionInfoResponse.Builder builder = GetRegionInfoResponse.newBuilder();
427     builder.setRegionInfo(HRegionInfo.convert(HRegionInfo.FIRST_META_REGIONINFO));
428     return builder.build();
429   }
430 
431   @Override
432   public GetStoreFileResponse getStoreFile(RpcController controller,
433       GetStoreFileRequest request) throws ServiceException {
434     // TODO Auto-generated method stub
435     return null;
436   }
437 
438   @Override
439   public GetOnlineRegionResponse getOnlineRegion(RpcController controller,
440       GetOnlineRegionRequest request) throws ServiceException {
441     // TODO Auto-generated method stub
442     return null;
443   }
444 
445   @Override
446   public OpenRegionResponse openRegion(RpcController controller,
447       OpenRegionRequest request) throws ServiceException {
448     // TODO Auto-generated method stub
449     return null;
450   }
451 
452   @Override
453   public CloseRegionResponse closeRegion(RpcController controller,
454       CloseRegionRequest request) throws ServiceException {
455     // TODO Auto-generated method stub
456     return null;
457   }
458 
459   @Override
460   public FlushRegionResponse flushRegion(RpcController controller,
461       FlushRegionRequest request) throws ServiceException {
462     // TODO Auto-generated method stub
463     return null;
464   }
465 
466   @Override
467   public SplitRegionResponse splitRegion(RpcController controller,
468       SplitRegionRequest request) throws ServiceException {
469     // TODO Auto-generated method stub
470     return null;
471   }
472 
473   @Override
474   public MergeRegionsResponse mergeRegions(RpcController controller,
475       MergeRegionsRequest request) throws ServiceException {
476     // TODO Auto-generated method stub
477     return null;
478   }
479 
480   @Override
481   public CompactRegionResponse compactRegion(RpcController controller,
482       CompactRegionRequest request) throws ServiceException {
483     // TODO Auto-generated method stub
484     return null;
485   }
486 
487   @Override
488   public ReplicateWALEntryResponse replicateWALEntry(RpcController controller,
489       ReplicateWALEntryRequest request) throws ServiceException {
490     // TODO Auto-generated method stub
491     return null;
492   }
493 
494   @Override
495   public RollWALWriterResponse rollWALWriter(RpcController controller,
496       RollWALWriterRequest request) throws ServiceException {
497     // TODO Auto-generated method stub
498     return null;
499   }
500 
501   @Override
502   public GetServerInfoResponse getServerInfo(RpcController controller,
503       GetServerInfoRequest request) throws ServiceException {
504     // TODO Auto-generated method stub
505     return null;
506   }
507 
508   @Override
509   public StopServerResponse stopServer(RpcController controller,
510       StopServerRequest request) throws ServiceException {
511     // TODO Auto-generated method stub
512     return null;
513   }
514 
515   @Override
516   public List<HRegion> getOnlineRegions(TableName tableName) throws IOException {
517     // TODO Auto-generated method stub
518     return null;
519   }
520 
521   @Override
522   public Leases getLeases() {
523     // TODO Auto-generated method stub
524     return null;
525   }
526 
527   @Override
528   public HLog getWAL(HRegionInfo regionInfo) throws IOException {
529     // TODO Auto-generated method stub
530     return null;
531   }
532 
533   @Override
534   public ExecutorService getExecutorService() {
535     return null;
536   }
537 
538   @Override
539   public void updateRegionFavoredNodesMapping(String encodedRegionName,
540       List<org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName> favoredNodes) {
541   }
542 
543   @Override
544   public InetSocketAddress[] getFavoredNodesForRegion(String encodedRegionName) {
545     return null;
546   }
547 
548   @Override
549   public MultiResponse replay(RpcController controller, MultiRequest request)
550       throws ServiceException {
551     // TODO Auto-generated method stub
552     return null;
553   }
554 
555   @Override
556   public Map<String, HRegion> getRecoveringRegions() {
557     // TODO Auto-generated method stub
558     return null;
559   }
560 }