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