View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.ipc;
21  
22  import java.io.IOException;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.classification.InterfaceAudience;
29  import org.apache.hadoop.conf.Configuration;
30  import org.apache.hadoop.hbase.IpcProtocol;
31  import org.apache.hadoop.util.ReflectionUtils;
32  
33  /**
34   * A simple RPC mechanism.
35   *
36   * This is a local hbase copy of the hadoop RPC so we can do things like
37   * address HADOOP-414 for hbase-only and try other hbase-specific
38   * optimizations.  Class has been renamed to avoid confusing it w/ hadoop
39   * versions.
40   * <p>
41   *
42   *
43   * A <i>protocol</i> is a Java interface.  All parameters and return types must
44   * be Protobuf objects.
45   * All methods in the protocol should throw only IOException.  No field data of
46   * the protocol instance is transmitted.
47   *
48   * This class provides the server side implementation.
49   */
50  @InterfaceAudience.Private
51  public class HBaseServerRPC {
52    // Leave this out in the hadoop ipc package but keep class name.  Do this
53    // so that we dont' get the logging of this class's invocations by doing our
54    // blanket enabling DEBUG on the o.a.h.h. package.
55    protected static final Log LOG =
56      LogFactory.getLog("org.apache.hadoop.ipc.HBaseServerRPC");
57  
58    // cache of RpcEngines by protocol
59    private static final Map<Class<? extends IpcProtocol>, RpcServerEngine> PROTOCOL_ENGINES =
60        new HashMap<Class<? extends IpcProtocol>, RpcServerEngine>();
61  
62    /**
63     * Configuration key for the {@link org.apache.hadoop.hbase.ipc.RpcServerEngine} implementation to
64     * load to handle connection protocols.  Handlers for individual protocols can be
65     * configured using {@code "hbase.rpc.server.engine." + protocol.class.name}.
66     */
67    public static final String RPC_ENGINE_PROP = "hbase.rpc.server.engine";
68  
69    private HBaseServerRPC() {
70      super();
71    }                                  // no public ctor
72  
73    // set a protocol to use a non-default RpcEngine
74    static void setProtocolEngine(Configuration conf,
75        Class<? extends IpcProtocol> protocol, Class<? extends RpcServerEngine> engine) {
76      conf.setClass(RPC_ENGINE_PROP + "." + protocol.getName(), engine, RpcServerEngine.class);
77    }
78  
79    // return the RpcEngine configured to handle a protocol
80    static synchronized RpcServerEngine getProtocolEngine(Class<? extends IpcProtocol> protocol,
81        Configuration conf) {
82      RpcServerEngine engine = PROTOCOL_ENGINES.get(protocol);
83      if (engine == null) {
84        // check for a configured default engine
85        Class<?> defaultEngine =
86            conf.getClass(RPC_ENGINE_PROP, ProtobufRpcServerEngine.class);
87  
88        // check for a per interface override
89        Class<?> impl = conf.getClass(RPC_ENGINE_PROP + "." + protocol.getName(),
90            defaultEngine);
91        LOG.debug("Using " + impl.getName() + " for " + protocol.getName());
92        engine = (RpcServerEngine) ReflectionUtils.newInstance(impl, conf);
93        PROTOCOL_ENGINES.put(protocol, engine);
94      }
95      return engine;
96    }
97  
98    /**
99     * Construct a server for a protocol implementation instance.
100    */
101   public static RpcServer getServer(Class<? extends IpcProtocol> protocol,
102                                     final Object instance,
103                                     final Class<?>[] ifaces,
104                                     String bindAddress,
105                                     int port,
106                                     final int numHandlers,
107                                     int metaHandlerCount,
108                                     final boolean verbose,
109                                     Configuration conf,
110                                     int highPriorityLevel)
111       throws IOException {
112     return getProtocolEngine(protocol, conf).
113       getServer(instance,
114             ifaces,
115             bindAddress,
116             port,
117             numHandlers,
118             metaHandlerCount,
119             verbose,
120             conf,
121             highPriorityLevel);
122   }
123 }