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