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 static org.apache.hadoop.hbase.thrift.Constants.SERVER_TYPE_CONF_KEY;
021
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.List;
025
026import org.apache.hadoop.conf.Configuration;
027import org.apache.thrift.server.THsHaServer;
028import org.apache.thrift.server.TNonblockingServer;
029import org.apache.thrift.server.TServer;
030import org.apache.thrift.server.TThreadedSelectorServer;
031import org.apache.yetus.audience.InterfaceAudience;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034
035import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
036import org.apache.hbase.thirdparty.org.apache.commons.cli.Option;
037import org.apache.hbase.thirdparty.org.apache.commons.cli.OptionGroup;
038
039/** An enum of server implementation selections */
040@InterfaceAudience.Private
041public enum ImplType {
042  HS_HA("hsha", true, THsHaServer.class, true),
043  NONBLOCKING("nonblocking", true, TNonblockingServer.class, true),
044  THREAD_POOL("threadpool", false, TBoundedThreadPoolServer.class, true),
045  THREADED_SELECTOR("threadedselector", true, TThreadedSelectorServer.class, true);
046
047  private static final Logger LOG = LoggerFactory.getLogger(ImplType.class);
048  public static final ImplType DEFAULT = THREAD_POOL;
049
050
051  final String option;
052  final boolean isAlwaysFramed;
053  final Class<? extends TServer> serverClass;
054  final boolean canSpecifyBindIP;
055
056  private ImplType(String option, boolean isAlwaysFramed,
057      Class<? extends TServer> serverClass, boolean canSpecifyBindIP) {
058    this.option = option;
059    this.isAlwaysFramed = isAlwaysFramed;
060    this.serverClass = serverClass;
061    this.canSpecifyBindIP = canSpecifyBindIP;
062  }
063
064  /**
065   * @return <code>-option</code>
066   */
067  @Override
068  public String toString() {
069    return "-" + option;
070  }
071
072  public String getOption() {
073    return option;
074  }
075
076  public boolean isAlwaysFramed() {
077    return isAlwaysFramed;
078  }
079
080  public String getDescription() {
081    StringBuilder sb = new StringBuilder("Use the " +
082        serverClass.getSimpleName());
083    if (isAlwaysFramed) {
084      sb.append(" This implies the framed transport.");
085    }
086    if (this == DEFAULT) {
087      sb.append("This is the default.");
088    }
089    return sb.toString();
090  }
091
092  static OptionGroup createOptionGroup() {
093    OptionGroup group = new OptionGroup();
094    for (ImplType t : values()) {
095      group.addOption(new Option(t.option, t.getDescription()));
096    }
097    return group;
098  }
099
100  public static ImplType getServerImpl(Configuration conf) {
101    String confType = conf.get(SERVER_TYPE_CONF_KEY, THREAD_POOL.option);
102    for (ImplType t : values()) {
103      if (confType.equals(t.option)) {
104        return t;
105      }
106    }
107    throw new AssertionError("Unknown server ImplType.option:" + confType);
108  }
109
110  static void setServerImpl(CommandLine cmd, Configuration conf) {
111    ImplType chosenType = null;
112    int numChosen = 0;
113    for (ImplType t : values()) {
114      if (cmd.hasOption(t.option)) {
115        chosenType = t;
116        ++numChosen;
117      }
118    }
119    if (numChosen < 1) {
120      LOG.info("Using default thrift server type");
121      chosenType = DEFAULT;
122    } else if (numChosen > 1) {
123      throw new AssertionError("Exactly one option out of " +
124          Arrays.toString(values()) + " has to be specified");
125    }
126    LOG.info("Using thrift server type " + chosenType.option);
127    conf.set(SERVER_TYPE_CONF_KEY, chosenType.option);
128  }
129
130  public String simpleClassName() {
131    return serverClass.getSimpleName();
132  }
133
134  public static List<String> serversThatCannotSpecifyBindIP() {
135    List<String> l = new ArrayList<>();
136    for (ImplType t : values()) {
137      if (!t.canSpecifyBindIP) {
138        l.add(t.simpleClassName());
139      }
140    }
141    return l;
142  }
143}