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.ipc; 019 020import java.util.List; 021 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.hbase.CellScannable; 024import org.apache.hadoop.hbase.CellScanner; 025import org.apache.yetus.audience.InterfaceAudience; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.apache.hadoop.hbase.util.ReflectionUtils; 029 030/** 031 * Factory to create a {@link HBaseRpcController} 032 */ 033@InterfaceAudience.Private 034public class RpcControllerFactory { 035 private static final Logger LOG = LoggerFactory.getLogger(RpcControllerFactory.class); 036 037 /** 038 * Custom RPC Controller factory allows frameworks to change the RPC controller. If the configured 039 * controller cannot be found in the classpath or loaded, we fall back to the default RPC 040 * controller factory. 041 */ 042 public static final String CUSTOM_CONTROLLER_CONF_KEY = "hbase.rpc.controllerfactory.class"; 043 protected final Configuration conf; 044 045 public RpcControllerFactory(Configuration conf) { 046 this.conf = conf; 047 } 048 049 public HBaseRpcController newController() { 050 // TODO: Set HConstants default rpc timeout here rather than nothing? 051 return new HBaseRpcControllerImpl(); 052 } 053 054 public HBaseRpcController newController(final CellScanner cellScanner) { 055 return new HBaseRpcControllerImpl(cellScanner); 056 } 057 058 public HBaseRpcController newController(final List<CellScannable> cellIterables) { 059 return new HBaseRpcControllerImpl(cellIterables); 060 } 061 062 063 public static RpcControllerFactory instantiate(Configuration configuration) { 064 String rpcControllerFactoryClazz = 065 configuration.get(CUSTOM_CONTROLLER_CONF_KEY, 066 RpcControllerFactory.class.getName()); 067 try { 068 return ReflectionUtils.instantiateWithCustomCtor(rpcControllerFactoryClazz, 069 new Class[] { Configuration.class }, new Object[] { configuration }); 070 } catch (UnsupportedOperationException | NoClassDefFoundError ex) { 071 // HBASE-14960: In case the RPCController is in a non-HBase jar (Phoenix), but the application 072 // is a pure HBase application, we want to fallback to the default one. 073 String msg = "Cannot load configured \"" + CUSTOM_CONTROLLER_CONF_KEY + "\" (" 074 + rpcControllerFactoryClazz + ") from hbase-site.xml, falling back to use " 075 + "default RpcControllerFactory"; 076 if (LOG.isDebugEnabled()) { 077 LOG.warn(msg, ex); // if DEBUG enabled, we want the exception, but still log in WARN level 078 } else { 079 LOG.warn(msg); 080 } 081 return new RpcControllerFactory(configuration); 082 } 083 } 084}