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