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.INFOPORT_OPTION; 021 022import java.io.IOException; 023import java.util.ArrayList; 024import java.util.List; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.HBaseTestingUtility; 027import org.apache.hadoop.hbase.thrift.ThriftMetrics.ThriftServerType; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031import org.apache.hbase.thirdparty.com.google.common.base.Joiner; 032 033public class HBaseThriftTestingUtility { 034 035 private static final Logger LOG = LoggerFactory.getLogger(HBaseThriftTestingUtility.class); 036 private Thread thriftServerThread; 037 private volatile Exception thriftServerException; 038 private ThriftServer thriftServer; 039 private int port; 040 041 public int getServerPort() { 042 return port; 043 } 044 045 /** 046 * start thrift server 047 * @param conf configuration 048 * @param type the type of thrift server 049 * @throws Exception When starting the thrift server fails. 050 */ 051 public void startThriftServer(Configuration conf, ThriftServerType type) throws Exception { 052 List<String> args = new ArrayList<>(); 053 port = HBaseTestingUtility.randomFreePort(); 054 args.add("-" + Constants.PORT_OPTION); 055 args.add(String.valueOf(port)); 056 args.add("-" + INFOPORT_OPTION); 057 int infoPort = HBaseTestingUtility.randomFreePort(); 058 args.add(String.valueOf(infoPort)); 059 060 LOG.info("Starting Thrift Server {} on port: {} ", type, port); 061 thriftServer = createThriftServer(conf, type); 062 startThriftServerThread(args.toArray(new String[args.size()])); 063 // wait up to 10s for the server to start 064 waitForThriftServer(); 065 LOG.info("Started Thrift Server {} on port {}", type, port); 066 } 067 068 private void startThriftServerThread(final String[] args) { 069 LOG.info("Starting HBase Thrift server with command line: " + Joiner.on(" ").join(args)); 070 071 thriftServerException = null; 072 thriftServerThread = new Thread(() -> { 073 try { 074 thriftServer.run(args); 075 } catch (Exception e) { 076 thriftServerException = e; 077 } 078 }); 079 thriftServerThread.setName(ThriftServer.class.getSimpleName()); 080 thriftServerThread.start(); 081 } 082 083 /** 084 * create a new thrift server 085 * @param conf configuration 086 * @param type the type of thrift server 087 * @return the instance of ThriftServer 088 */ 089 private ThriftServer createThriftServer(Configuration conf, ThriftServerType type) { 090 switch (type) { 091 case ONE: 092 return new ThriftServer(conf); 093 case TWO: 094 return new org.apache.hadoop.hbase.thrift2.ThriftServer(conf); 095 default: 096 throw new IllegalArgumentException("Unknown type: " + type); 097 } 098 } 099 100 private void waitForThriftServer() throws Exception { 101 boolean isServing = false; 102 int i = 0; 103 while (i++ < 100) { 104 if (thriftServer.tserver == null) { 105 Thread.sleep(100); 106 } else { 107 isServing = true; 108 break; 109 } 110 } 111 112 if (!isServing) { 113 if (thriftServer != null) { 114 thriftServer.stop(); 115 } 116 throw new IOException("Failed to start thrift server "); 117 } 118 } 119 120 public void stopThriftServer() throws Exception { 121 LOG.debug("Stopping Thrift Server"); 122 thriftServer.stop(); 123 thriftServerThread.join(); 124 if (thriftServerException != null) { 125 LOG.error("HBase Thrift server threw an exception ", thriftServerException); 126 throw new Exception(thriftServerException); 127 } 128 } 129}