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 */
018
019package org.apache.hadoop.hbase.thrift;
020
021import java.io.IOException;
022import java.util.List;
023import java.util.Optional;
024
025import org.apache.hadoop.hbase.CallQueueTooBigException;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.DoNotRetryIOException;
028import org.apache.hadoop.hbase.MultiActionResultTooLarge;
029import org.apache.hadoop.hbase.NotServingRegionException;
030import org.apache.hadoop.hbase.RegionTooBusyException;
031import org.apache.hadoop.hbase.UnknownScannerException;
032import org.apache.hadoop.hbase.client.Get;
033import org.apache.hadoop.hbase.coprocessor.CoreCoprocessor;
034import org.apache.hadoop.hbase.coprocessor.ObserverContext;
035import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
036import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
037import org.apache.hadoop.hbase.coprocessor.RegionObserver;
038import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;
039import org.apache.hadoop.hbase.exceptions.OutOfOrderScannerNextException;
040import org.apache.hadoop.hbase.exceptions.RegionMovedException;
041import org.apache.hadoop.hbase.exceptions.ScannerResetException;
042import org.apache.hadoop.hbase.metrics.ExceptionTrackingSource;
043import org.apache.hadoop.hbase.util.Bytes;
044
045/**
046 * Simple test coprocessor for injecting exceptions on Get requests.
047 */
048@CoreCoprocessor
049public class ErrorThrowingGetObserver implements RegionCoprocessor, RegionObserver {
050  @Override
051  public Optional<RegionObserver> getRegionObserver() {
052    return Optional.of(this);
053  }
054
055  public static final String SHOULD_ERROR_ATTRIBUTE = "error";
056
057  @Override
058  public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e,
059                       Get get, List<Cell> results) throws IOException {
060    byte[] errorType = get.getAttribute(SHOULD_ERROR_ATTRIBUTE);
061    if (errorType != null) {
062      ErrorType type = ErrorType.valueOf(Bytes.toString(errorType));
063      switch (type) {
064        case CALL_QUEUE_TOO_BIG:
065          throw new CallQueueTooBigException("Failing for test");
066        case MULTI_ACTION_RESULT_TOO_LARGE:
067          throw new MultiActionResultTooLarge("Failing for test");
068        case FAILED_SANITY_CHECK:
069          throw new FailedSanityCheckException("Failing for test");
070        case NOT_SERVING_REGION:
071          throw new NotServingRegionException("Failing for test");
072        case REGION_MOVED:
073          throw new RegionMovedException(e.getEnvironment().getServerName(), 1);
074        case SCANNER_RESET:
075          throw new ScannerResetException("Failing for test");
076        case UNKNOWN_SCANNER:
077          throw new UnknownScannerException("Failing for test");
078        case REGION_TOO_BUSY:
079          throw new RegionTooBusyException("Failing for test");
080        case OUT_OF_ORDER_SCANNER_NEXT:
081          throw new OutOfOrderScannerNextException("Failing for test");
082        default:
083          throw new DoNotRetryIOException("Failing for test");
084      }
085    }
086  }
087
088  public enum ErrorType {
089    CALL_QUEUE_TOO_BIG(ExceptionTrackingSource.EXCEPTIONS_CALL_QUEUE_TOO_BIG),
090    MULTI_ACTION_RESULT_TOO_LARGE(ExceptionTrackingSource.EXCEPTIONS_MULTI_TOO_LARGE_NAME),
091    FAILED_SANITY_CHECK(ExceptionTrackingSource.EXCEPTIONS_SANITY_NAME),
092    NOT_SERVING_REGION(ExceptionTrackingSource.EXCEPTIONS_NSRE_NAME),
093    REGION_MOVED(ExceptionTrackingSource.EXCEPTIONS_MOVED_NAME),
094    SCANNER_RESET(ExceptionTrackingSource.EXCEPTIONS_SCANNER_RESET_NAME),
095    UNKNOWN_SCANNER(ExceptionTrackingSource.EXCEPTIONS_UNKNOWN_NAME),
096    REGION_TOO_BUSY(ExceptionTrackingSource.EXCEPTIONS_BUSY_NAME),
097    OUT_OF_ORDER_SCANNER_NEXT(ExceptionTrackingSource.EXCEPTIONS_OOO_NAME);
098
099    private final String metricName;
100
101    ErrorType(String metricName) {
102      this.metricName = metricName;
103    }
104
105    public String getMetricName() {
106      return metricName;
107    }
108  }
109}