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