001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.client;
020
021import java.lang.reflect.Constructor;
022
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.hbase.HConstants;
025import org.apache.yetus.audience.InterfaceAudience;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029/**
030 * Factory implementation to provide the {@link ConnectionImplementation} with
031 * the implementation of the {@link RetryingCallerInterceptor} that we would use
032 * to intercept the {@link RpcRetryingCaller} during the course of their calls.
033 * 
034 */
035
036@InterfaceAudience.Private
037class RetryingCallerInterceptorFactory {
038  private static final Logger LOG = LoggerFactory
039      .getLogger(RetryingCallerInterceptorFactory.class);
040  private Configuration conf;
041  private final boolean failFast;
042  public static final RetryingCallerInterceptor NO_OP_INTERCEPTOR =
043      new NoOpRetryableCallerInterceptor(null);
044
045  public RetryingCallerInterceptorFactory(Configuration conf) {
046    this.conf = conf;
047    failFast = conf.getBoolean(HConstants.HBASE_CLIENT_FAST_FAIL_MODE_ENABLED,
048        HConstants.HBASE_CLIENT_ENABLE_FAST_FAIL_MODE_DEFAULT);
049  }
050
051  /**
052   * This builds the implementation of {@link RetryingCallerInterceptor} that we
053   * specify in the conf and returns the same.
054   * 
055   * To use {@link PreemptiveFastFailInterceptor}, set HBASE_CLIENT_ENABLE_FAST_FAIL_MODE to true.
056   * HBASE_CLIENT_FAST_FAIL_INTERCEPTOR_IMPL is defaulted to {@link PreemptiveFastFailInterceptor}
057   * 
058   * @return The factory build method which creates the
059   *         {@link RetryingCallerInterceptor} object according to the
060   *         configuration.
061   */
062  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION",
063      justification="Convert thrown exception to unchecked")
064  public RetryingCallerInterceptor build() {
065    RetryingCallerInterceptor ret = NO_OP_INTERCEPTOR;
066    if (failFast) {
067      try {
068        Class<?> c = conf.getClass(
069            HConstants.HBASE_CLIENT_FAST_FAIL_INTERCEPTOR_IMPL,
070            PreemptiveFastFailInterceptor.class);
071        Constructor<?> constructor = c
072            .getDeclaredConstructor(Configuration.class);
073        constructor.setAccessible(true);
074        ret = (RetryingCallerInterceptor) constructor.newInstance(conf);
075      } catch (Exception e) {
076        ret = new PreemptiveFastFailInterceptor(conf);
077      }
078    }
079    LOG.trace("Using " + ret.toString() + " for intercepting the RpcRetryingCaller");
080    return ret;
081  }
082}