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