From commits-return-98762-archive-asf-public=cust-asf.ponee.io@hbase.apache.org Fri Jun 4 20:20:24 2021 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mxout1-ec2-va.apache.org (mxout1-ec2-va.apache.org [3.227.148.255]) by mx-eu-01.ponee.io (Postfix) with ESMTPS id B8C1A18066B for ; Fri, 4 Jun 2021 22:20:23 +0200 (CEST) Received: from mail.apache.org (mailroute1-lw-us.apache.org [207.244.88.153]) by mxout1-ec2-va.apache.org (ASF Mail Server at mxout1-ec2-va.apache.org) with SMTP id B20BC3EECE for ; Fri, 4 Jun 2021 20:20:22 +0000 (UTC) Received: (qmail 48389 invoked by uid 500); 4 Jun 2021 20:20:22 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 48367 invoked by uid 99); 4 Jun 2021 20:20:22 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Jun 2021 20:20:22 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id EE64D81A86; Fri, 4 Jun 2021 20:20:21 +0000 (UTC) Date: Fri, 04 Jun 2021 20:20:21 +0000 To: "commits@hbase.apache.org" Subject: [hbase-site] branch asf-site updated: Published site at 1ecff8a3903f8f131149c6c073108d2ab2166b36. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <162283802112.1898.7444071606068821905@gitbox.apache.org> From: git-site-role@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: hbase-site X-Git-Refname: refs/heads/asf-site X-Git-Reftype: branch X-Git-Oldrev: b664c11ce3e90ea0abeea449ed5a1bf29f4c29fe X-Git-Newrev: 6c1b24e218921fb9453d09bd6ec53e7be13bfaed X-Git-Rev: 6c1b24e218921fb9453d09bd6ec53e7be13bfaed X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated This is an automated email from the ASF dual-hosted git repository. git-site-role pushed a commit to branch asf-site in repository https://gitbox.apache.org/repos/asf/hbase-site.git The following commit(s) were added to refs/heads/asf-site by this push: new 6c1b24e Published site at 1ecff8a3903f8f131149c6c073108d2ab2166b36. 6c1b24e is described below commit 6c1b24e218921fb9453d09bd6ec53e7be13bfaed Author: jenkins AuthorDate: Fri Jun 4 20:19:42 2021 +0000 Published site at 1ecff8a3903f8f131149c6c073108d2ab2166b36. --- acid-semantics.html | 2 +- apache_hbase_reference_guide.pdf | 4 +- book.html | 2 +- bulk-loads.html | 2 +- checkstyle-aggregate.html | 2 +- coc.html | 2 +- dependencies.html | 2 +- dependency-convergence.html | 2 +- dependency-info.html | 2 +- dependency-management.html | 2 +- .../apache/hadoop/hbase/thrift/ThriftServer.html | 98 +- .../apache/hadoop/hbase/thrift/ThriftServer.html | 1579 ++++++++++---------- downloads.html | 2 +- export_control.html | 2 +- index.html | 2 +- issue-tracking.html | 2 +- mail-lists.html | 2 +- metrics.html | 2 +- old_news.html | 2 +- plugin-management.html | 2 +- plugins.html | 2 +- poweredbyhbase.html | 2 +- project-info.html | 2 +- project-reports.html | 2 +- project-summary.html | 2 +- pseudo-distributed.html | 2 +- replication.html | 2 +- resources.html | 2 +- source-repository.html | 2 +- sponsors.html | 2 +- supportingprojects.html | 2 +- team-list.html | 2 +- 32 files changed, 878 insertions(+), 861 deletions(-) diff --git a/acid-semantics.html b/acid-semantics.html index 4d62dd7..80d26bc 100644 --- a/acid-semantics.html +++ b/acid-semantics.html @@ -467,7 +467,7 @@

Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf index 52b4f1d..834102b 100644 --- a/apache_hbase_reference_guide.pdf +++ b/apache_hbase_reference_guide.pdf @@ -5,8 +5,8 @@ /Author (Apache HBase Team) /Creator (Asciidoctor PDF 1.5.3, based on Prawn 2.2.2) /Producer (Apache HBase Team) -/ModDate (D:20210603200617+00'00') -/CreationDate (D:20210603201801+00'00') +/ModDate (D:20210604200557+00'00') +/CreationDate (D:20210604201720+00'00') >> endobj 2 0 obj diff --git a/book.html b/book.html index 8344e7f..14f78dd 100644 --- a/book.html +++ b/book.html @@ -46192,7 +46192,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/

    diff --git a/bulk-loads.html b/bulk-loads.html index 7a52f4a..d23c9d3 100644 --- a/bulk-loads.html +++ b/bulk-loads.html @@ -172,7 +172,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html index c7d2e56..ff2726b 100644 --- a/checkstyle-aggregate.html +++ b/checkstyle-aggregate.html @@ -73511,7 +73511,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/coc.html b/coc.html index ac5d0d8..8f734b5 100644 --- a/coc.html +++ b/coc.html @@ -241,7 +241,7 @@ email to the priv

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/dependencies.html b/dependencies.html index d78c7fd..2b75f04 100644 --- a/dependencies.html +++ b/dependencies.html @@ -313,7 +313,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/dependency-convergence.html b/dependency-convergence.html index 634c596..319a50d 100644 --- a/dependency-convergence.html +++ b/dependency-convergence.html @@ -824,7 +824,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/dependency-info.html b/dependency-info.html index 01918e3..426a9f6 100644 --- a/dependency-info.html +++ b/dependency-info.html @@ -194,7 +194,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/dependency-management.html b/dependency-management.html index 5853583..d18b8b4 100644 --- a/dependency-management.html +++ b/dependency-management.html @@ -1201,7 +1201,7 @@

    Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

  • Last Published: 2021-06-03
  • +All rights reserved.
  • Last Published: 2021-06-04
  • Built by Maven diff --git a/devapidocs/org/apache/hadoop/hbase/thrift/ThriftServer.html b/devapidocs/org/apache/hadoop/hbase/thrift/ThriftServer.html index dd33917..7b23953 100644 --- a/devapidocs/org/apache/hadoop/hbase/thrift/ThriftServer.html +++ b/devapidocs/org/apache/hadoop/hbase/thrift/ThriftServer.html @@ -123,7 +123,7 @@ var activeTableTab = "activeTableTab";



    @InterfaceAudience.LimitedPrivate(value="Tools")
    -public class ThriftServer
    +public class ThriftServer
     extends org.apache.hadoop.conf.Configured
     implements org.apache.hadoop.util.Tool
    ThriftServer- this class starts up a Thrift server which implements the @@ -450,7 +450,7 @@ implements org.apache.hadoop.util.Tool
    • LOG

      -
      private static final org.slf4j.Logger LOG
      +
      private static final org.slf4j.Logger LOG
    @@ -459,7 +459,7 @@ implements org.apache.hadoop.util.Tool @@ -468,7 +468,7 @@ implements org.apache.hadoop.util.Tool @@ -477,7 +477,7 @@ implements org.apache.hadoop.util.Tool @@ -486,7 +486,7 @@ implements org.apache.hadoop.util.Tool @@ -495,7 +495,7 @@ implements org.apache.hadoop.util.Tool @@ -504,7 +504,7 @@ implements org.apache.hadoop.util.Tool @@ -513,7 +513,7 @@ implements org.apache.hadoop.util.Tool @@ -522,7 +522,7 @@ implements org.apache.hadoop.util.Tool @@ -531,7 +531,7 @@ implements org.apache.hadoop.util.Tool @@ -540,7 +540,7 @@ implements org.apache.hadoop.util.Tool @@ -549,7 +549,7 @@ implements org.apache.hadoop.util.Tool @@ -558,7 +558,7 @@ implements org.apache.hadoop.util.Tool @@ -567,7 +567,7 @@ implements org.apache.hadoop.util.Tool @@ -576,7 +576,7 @@ implements org.apache.hadoop.util.Tool @@ -585,7 +585,7 @@ implements org.apache.hadoop.util.Tool @@ -594,7 +594,7 @@ implements org.apache.hadoop.util.Tool @@ -611,7 +611,7 @@ implements org.apache.hadoop.util.Tool
    • ThriftServer

      -
      public ThriftServer(org.apache.hadoop.conf.Configuration conf)
      +
      public ThriftServer(org.apache.hadoop.conf.Configuration conf)
    @@ -628,7 +628,7 @@ implements org.apache.hadoop.util.Tool @@ -637,7 +637,7 @@ implements org.apache.hadoop.util.Tool
    • setupParamters

      -
      protected void setupParamters()
      +
      protected void setupParamters()
                              throws IOException
      Throws:
      @@ -651,7 +651,7 @@ implements org.apache.hadoop.util.Tool
      @@ -966,7 +966,7 @@ public org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server 
    • optionToConf

      -
      protected static void optionToConf(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine cmd,
      +
      protected static void optionToConf(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine cmd,
                                          String option,
                                          org.apache.hadoop.conf.Configuration conf,
                                          String destConfKey)
      @@ -978,7 +978,7 @@ public org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server 
    • run

      -
      public int run()
      +
      public int run()
               throws Exception
      Run without any command line arguments
      @@ -995,7 +995,7 @@ public org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server 
    • run

      -
      public int run(String[] strings)
      +
      public int run(String[] strings)
               throws Exception
      Specified by:
      @@ -1011,7 +1011,7 @@ public org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server 
    • main

      -
      public static void main(String[] args)
      +
      public static void main(String[] args)
                        throws Exception
      Throws:
      diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/thrift/ThriftServer.html b/devapidocs/src-html/org/apache/hadoop/hbase/thrift/ThriftServer.html index 38d0118..6a05d69 100644 --- a/devapidocs/src-html/org/apache/hadoop/hbase/thrift/ThriftServer.html +++ b/devapidocs/src-html/org/apache/hadoop/hbase/thrift/ThriftServer.html @@ -86,795 +86,812 @@ 078import java.net.InetAddress; 079import java.net.InetSocketAddress; 080import java.net.UnknownHostException; -081import java.util.List; -082import java.util.Map; -083import java.util.concurrent.BlockingQueue; -084import java.util.concurrent.ExecutorService; -085import java.util.concurrent.LinkedBlockingQueue; -086import java.util.concurrent.ThreadPoolExecutor; -087import java.util.concurrent.TimeUnit; -088import javax.security.auth.callback.Callback; -089import javax.security.auth.callback.UnsupportedCallbackException; -090import javax.security.sasl.AuthorizeCallback; -091import javax.security.sasl.SaslServer; -092import org.apache.commons.lang3.ArrayUtils; -093import org.apache.hadoop.conf.Configuration; -094import org.apache.hadoop.conf.Configured; -095import org.apache.hadoop.hbase.HBaseConfiguration; -096import org.apache.hadoop.hbase.HBaseInterfaceAudience; -097import org.apache.hadoop.hbase.filter.ParseFilter; -098import org.apache.hadoop.hbase.http.HttpServerUtil; -099import org.apache.hadoop.hbase.http.InfoServer; -100import org.apache.hadoop.hbase.security.SaslUtil; -101import org.apache.hadoop.hbase.security.SecurityUtil; -102import org.apache.hadoop.hbase.security.UserProvider; -103import org.apache.hadoop.hbase.thrift.generated.Hbase; -104import org.apache.hadoop.hbase.util.DNS; -105import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; -106import org.apache.hadoop.hbase.util.JvmPauseMonitor; -107import org.apache.hadoop.hbase.util.Strings; -108import org.apache.hadoop.hbase.util.VersionInfo; -109import org.apache.hadoop.security.SaslRpcServer; -110import org.apache.hadoop.security.UserGroupInformation; -111import org.apache.hadoop.security.authorize.ProxyUsers; -112import org.apache.hadoop.util.Shell.ExitCodeException; -113import org.apache.hadoop.util.Tool; -114import org.apache.hadoop.util.ToolRunner; -115import org.apache.thrift.TProcessor; -116import org.apache.thrift.protocol.TBinaryProtocol; -117import org.apache.thrift.protocol.TCompactProtocol; -118import org.apache.thrift.protocol.TProtocolFactory; -119import org.apache.thrift.server.THsHaServer; -120import org.apache.thrift.server.TNonblockingServer; -121import org.apache.thrift.server.TServer; -122import org.apache.thrift.server.TServlet; -123import org.apache.thrift.server.TThreadedSelectorServer; -124import org.apache.thrift.transport.TNonblockingServerSocket; -125import org.apache.thrift.transport.TNonblockingServerTransport; -126import org.apache.thrift.transport.TSaslServerTransport; -127import org.apache.thrift.transport.TServerSocket; -128import org.apache.thrift.transport.TServerTransport; -129import org.apache.thrift.transport.TTransportFactory; -130import org.apache.thrift.transport.layered.TFramedTransport; -131import org.apache.yetus.audience.InterfaceAudience; -132import org.slf4j.Logger; -133import org.slf4j.LoggerFactory; -134 -135import org.apache.hbase.thirdparty.com.google.common.base.Joiner; -136import org.apache.hbase.thirdparty.com.google.common.base.Splitter; -137import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder; -138import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine; -139import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser; -140import org.apache.hbase.thirdparty.org.apache.commons.cli.DefaultParser; -141import org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter; -142import org.apache.hbase.thirdparty.org.apache.commons.cli.Options; -143import org.apache.hbase.thirdparty.org.eclipse.jetty.http.HttpVersion; -144import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConfiguration; -145import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConnectionFactory; -146import org.apache.hbase.thirdparty.org.eclipse.jetty.server.SecureRequestCustomizer; -147import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server; -148import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector; -149import org.apache.hbase.thirdparty.org.eclipse.jetty.server.SslConnectionFactory; -150import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler; -151import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder; -152import org.apache.hbase.thirdparty.org.eclipse.jetty.util.ssl.SslContextFactory; -153import org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool; -154 -155/** -156 * ThriftServer- this class starts up a Thrift server which implements the -157 * Hbase API specified in the Hbase.thrift IDL file. The server runs in an -158 * independent process. -159 */ -160@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS) -161public class ThriftServer extends Configured implements Tool { -162 -163 private static final Logger LOG = LoggerFactory.getLogger(ThriftServer.class); +081import java.security.PrivilegedAction; +082import java.util.List; +083import java.util.Map; +084import java.util.concurrent.BlockingQueue; +085import java.util.concurrent.ExecutorService; +086import java.util.concurrent.LinkedBlockingQueue; +087import java.util.concurrent.ThreadPoolExecutor; +088import java.util.concurrent.TimeUnit; +089import javax.security.auth.callback.Callback; +090import javax.security.auth.callback.UnsupportedCallbackException; +091import javax.security.sasl.AuthorizeCallback; +092import javax.security.sasl.SaslServer; +093import org.apache.commons.lang3.ArrayUtils; +094import org.apache.hadoop.conf.Configuration; +095import org.apache.hadoop.conf.Configured; +096import org.apache.hadoop.hbase.HBaseConfiguration; +097import org.apache.hadoop.hbase.HBaseInterfaceAudience; +098import org.apache.hadoop.hbase.filter.ParseFilter; +099import org.apache.hadoop.hbase.http.HttpServerUtil; +100import org.apache.hadoop.hbase.http.InfoServer; +101import org.apache.hadoop.hbase.log.HBaseMarkers; +102import org.apache.hadoop.hbase.security.SaslUtil; +103import org.apache.hadoop.hbase.security.SecurityUtil; +104import org.apache.hadoop.hbase.security.UserProvider; +105import org.apache.hadoop.hbase.thrift.generated.Hbase; +106import org.apache.hadoop.hbase.util.DNS; +107import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; +108import org.apache.hadoop.hbase.util.JvmPauseMonitor; +109import org.apache.hadoop.hbase.util.Strings; +110import org.apache.hadoop.hbase.util.VersionInfo; +111import org.apache.hadoop.security.SaslRpcServer; +112import org.apache.hadoop.security.UserGroupInformation; +113import org.apache.hadoop.security.authorize.ProxyUsers; +114import org.apache.hadoop.util.Shell.ExitCodeException; +115import org.apache.hadoop.util.Tool; +116import org.apache.hadoop.util.ToolRunner; +117import org.apache.thrift.TProcessor; +118import org.apache.thrift.protocol.TBinaryProtocol; +119import org.apache.thrift.protocol.TCompactProtocol; +120import org.apache.thrift.protocol.TProtocolFactory; +121import org.apache.thrift.server.THsHaServer; +122import org.apache.thrift.server.TNonblockingServer; +123import org.apache.thrift.server.TServer; +124import org.apache.thrift.server.TServlet; +125import org.apache.thrift.server.TThreadedSelectorServer; +126import org.apache.thrift.transport.TNonblockingServerSocket; +127import org.apache.thrift.transport.TNonblockingServerTransport; +128import org.apache.thrift.transport.TSaslServerTransport; +129import org.apache.thrift.transport.TServerSocket; +130import org.apache.thrift.transport.TServerTransport; +131import org.apache.thrift.transport.TTransportFactory; +132import org.apache.thrift.transport.layered.TFramedTransport; +133import org.apache.yetus.audience.InterfaceAudience; +134import org.slf4j.Logger; +135import org.slf4j.LoggerFactory; +136 +137import org.apache.hbase.thirdparty.com.google.common.base.Joiner; +138import org.apache.hbase.thirdparty.com.google.common.base.Splitter; +139import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder; +140import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine; +141import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser; +142import org.apache.hbase.thirdparty.org.apache.commons.cli.DefaultParser; +143import org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter; +144import org.apache.hbase.thirdparty.org.apache.commons.cli.Options; +145import org.apache.hbase.thirdparty.org.eclipse.jetty.http.HttpVersion; +146import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConfiguration; +147import org.apache.hbase.thirdparty.org.eclipse.jetty.server.HttpConnectionFactory; +148import org.apache.hbase.thirdparty.org.eclipse.jetty.server.SecureRequestCustomizer; +149import org.apache.hbase.thirdparty.org.eclipse.jetty.server.Server; +150import org.apache.hbase.thirdparty.org.eclipse.jetty.server.ServerConnector; +151import org.apache.hbase.thirdparty.org.eclipse.jetty.server.SslConnectionFactory; +152import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletContextHandler; +153import org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder; +154import org.apache.hbase.thirdparty.org.eclipse.jetty.util.ssl.SslContextFactory; +155import org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool; +156 +157/** +158 * ThriftServer- this class starts up a Thrift server which implements the +159 * Hbase API specified in the Hbase.thrift IDL file. The server runs in an +160 * independent process. +161 */ +162@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS) +163public class ThriftServer extends Configured implements Tool { 164 -165 +165 private static final Logger LOG = LoggerFactory.getLogger(ThriftServer.class); 166 -167 protected Configuration conf; +167 168 -169 protected InfoServer infoServer; +169 protected Configuration conf; 170 -171 protected TProcessor processor; +171 protected InfoServer infoServer; 172 -173 protected ThriftMetrics metrics; -174 protected HBaseServiceHandler hbaseServiceHandler; -175 protected UserGroupInformation serviceUGI; -176 protected UserGroupInformation httpUGI; -177 protected boolean httpEnabled; -178 -179 protected SaslUtil.QualityOfProtection qop; -180 protected String host; -181 protected int listenPort; -182 -183 -184 protected boolean securityEnabled; -185 protected boolean doAsEnabled; -186 -187 protected JvmPauseMonitor pauseMonitor; +173 protected TProcessor processor; +174 +175 protected ThriftMetrics metrics; +176 protected HBaseServiceHandler hbaseServiceHandler; +177 protected UserGroupInformation serviceUGI; +178 protected UserGroupInformation httpUGI; +179 protected boolean httpEnabled; +180 +181 protected SaslUtil.QualityOfProtection qop; +182 protected String host; +183 protected int listenPort; +184 +185 +186 protected boolean securityEnabled; +187 protected boolean doAsEnabled; 188 -189 protected volatile TServer tserver; -190 protected volatile Server httpServer; -191 -192 -193 // -194 // Main program and support routines +189 protected JvmPauseMonitor pauseMonitor; +190 +191 protected volatile TServer tserver; +192 protected volatile Server httpServer; +193 +194 195 // -196 -197 public ThriftServer(Configuration conf) { -198 this.conf = HBaseConfiguration.create(conf); -199 } -200 -201 protected ThriftMetrics createThriftMetrics(Configuration conf) { -202 return new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.ONE); -203 } -204 -205 protected void setupParamters() throws IOException { -206 // login the server principal (if using secure Hadoop) -207 UserProvider userProvider = UserProvider.instantiate(conf); -208 securityEnabled = userProvider.isHadoopSecurityEnabled() -209 && userProvider.isHBaseSecurityEnabled(); -210 if (securityEnabled) { -211 host = Strings.domainNamePointerToHostName(DNS.getDefaultHost( -212 conf.get(THRIFT_DNS_INTERFACE_KEY, "default"), -213 conf.get(THRIFT_DNS_NAMESERVER_KEY, "default"))); -214 userProvider.login(THRIFT_KEYTAB_FILE_KEY, THRIFT_KERBEROS_PRINCIPAL_KEY, host); -215 -216 // Setup the SPNEGO user for HTTP if configured -217 String spnegoPrincipal = getSpengoPrincipal(conf, host); -218 String spnegoKeytab = getSpnegoKeytab(conf); -219 UserGroupInformation.setConfiguration(conf); -220 // login the SPNEGO principal using UGI to avoid polluting the login user -221 this.httpUGI = UserGroupInformation.loginUserFromKeytabAndReturnUGI(spnegoPrincipal, -222 spnegoKeytab); -223 } -224 this.serviceUGI = userProvider.getCurrent().getUGI(); -225 if (httpUGI == null) { -226 this.httpUGI = serviceUGI; -227 } -228 -229 this.listenPort = conf.getInt(PORT_CONF_KEY, DEFAULT_LISTEN_PORT); -230 this.metrics = createThriftMetrics(conf); -231 this.pauseMonitor = new JvmPauseMonitor(conf, this.metrics.getSource()); -232 this.hbaseServiceHandler = createHandler(conf, userProvider); -233 this.hbaseServiceHandler.initMetrics(metrics); -234 this.processor = createProcessor(); -235 -236 httpEnabled = conf.getBoolean(USE_HTTP_CONF_KEY, false); -237 doAsEnabled = conf.getBoolean(THRIFT_SUPPORT_PROXYUSER_KEY, false); -238 if (doAsEnabled && !httpEnabled) { -239 LOG.warn("Fail to enable the doAs feature. " + USE_HTTP_CONF_KEY + " is not configured"); -240 } -241 -242 String strQop = conf.get(THRIFT_QOP_KEY); -243 if (strQop != null) { -244 this.qop = SaslUtil.getQop(strQop); -245 } -246 if (qop != null) { -247 if (qop != SaslUtil.QualityOfProtection.AUTHENTICATION && -248 qop != SaslUtil.QualityOfProtection.INTEGRITY && -249 qop != SaslUtil.QualityOfProtection.PRIVACY) { -250 throw new IOException(String.format("Invalid %s: It must be one of %s, %s, or %s.", -251 THRIFT_QOP_KEY, -252 SaslUtil.QualityOfProtection.AUTHENTICATION.name(), -253 SaslUtil.QualityOfProtection.INTEGRITY.name(), -254 SaslUtil.QualityOfProtection.PRIVACY.name())); -255 } -256 checkHttpSecurity(qop, conf); -257 if (!securityEnabled) { -258 throw new IOException("Thrift server must run in secure mode to support authentication"); -259 } -260 } -261 registerFilters(conf); -262 pauseMonitor.start(); -263 } -264 -265 private String getSpengoPrincipal(Configuration conf, String host) throws IOException { -266 String principal = conf.get(THRIFT_SPNEGO_PRINCIPAL_KEY); -267 if (principal == null) { -268 // We cannot use the Hadoop configuration deprecation handling here since -269 // the THRIFT_KERBEROS_PRINCIPAL_KEY config is still valid for regular Kerberos -270 // communication. The preference should be to use the THRIFT_SPNEGO_PRINCIPAL_KEY -271 // config so that THRIFT_KERBEROS_PRINCIPAL_KEY doesn't control both backend -272 // Kerberos principal and SPNEGO principal. -273 LOG.info("Using deprecated {} config for SPNEGO principal. Use {} instead.", -274 THRIFT_KERBEROS_PRINCIPAL_KEY, THRIFT_SPNEGO_PRINCIPAL_KEY); -275 principal = conf.get(THRIFT_KERBEROS_PRINCIPAL_KEY); -276 } -277 // Handle _HOST in principal value -278 return org.apache.hadoop.security.SecurityUtil.getServerPrincipal(principal, host); -279 } -280 -281 private String getSpnegoKeytab(Configuration conf) { -282 String keytab = conf.get(THRIFT_SPNEGO_KEYTAB_FILE_KEY); -283 if (keytab == null) { -284 // We cannot use the Hadoop configuration deprecation handling here since -285 // the THRIFT_KEYTAB_FILE_KEY config is still valid for regular Kerberos -286 // communication. The preference should be to use the THRIFT_SPNEGO_KEYTAB_FILE_KEY -287 // config so that THRIFT_KEYTAB_FILE_KEY doesn't control both backend -288 // Kerberos keytab and SPNEGO keytab. -289 LOG.info("Using deprecated {} config for SPNEGO keytab. Use {} instead.", -290 THRIFT_KEYTAB_FILE_KEY, THRIFT_SPNEGO_KEYTAB_FILE_KEY); -291 keytab = conf.get(THRIFT_KEYTAB_FILE_KEY); -292 } -293 return keytab; -294 } -295 -296 protected void startInfoServer() throws IOException { -297 // Put up info server. -298 int port = conf.getInt(THRIFT_INFO_SERVER_PORT , THRIFT_INFO_SERVER_PORT_DEFAULT); -299 -300 if (port >= 0) { -301 conf.setLong("startcode", EnvironmentEdgeManager.currentTime()); -302 String a = conf -303 .get(THRIFT_INFO_SERVER_BINDING_ADDRESS, THRIFT_INFO_SERVER_BINDING_ADDRESS_DEFAULT); -304 infoServer = new InfoServer("thrift", a, port, false, conf); -305 infoServer.setAttribute("hbase.conf", conf); -306 infoServer.setAttribute("hbase.thrift.server.type", metrics.getThriftServerType().name()); -307 infoServer.start(); -308 } -309 } -310 -311 protected void checkHttpSecurity(SaslUtil.QualityOfProtection qop, Configuration conf) { -312 if (qop == SaslUtil.QualityOfProtection.PRIVACY && -313 conf.getBoolean(USE_HTTP_CONF_KEY, false) && -314 !conf.getBoolean(THRIFT_SSL_ENABLED_KEY, false)) { -315 throw new IllegalArgumentException("Thrift HTTP Server's QoP is privacy, but " + -316 THRIFT_SSL_ENABLED_KEY + " is false"); -317 } -318 } -319 -320 protected HBaseServiceHandler createHandler(Configuration conf, UserProvider userProvider) -321 throws IOException { -322 return new ThriftHBaseServiceHandler(conf, userProvider); -323 } -324 -325 protected TProcessor createProcessor() { -326 return new Hbase.Processor<>( -327 HbaseHandlerMetricsProxy.newInstance((Hbase.Iface) hbaseServiceHandler, metrics, conf)); -328 } -329 -330 /** -331 * the thrift server, not null means the server is started, for test only -332 * @return the tServer -333 */ -334 @InterfaceAudience.Private -335 public TServer getTserver() { -336 return tserver; -337 } -338 -339 /** -340 * the Jetty server, not null means the HTTP server is started, for test only -341 * @return the http server -342 */ -343 @InterfaceAudience.Private -344 public Server getHttpServer() { -345 return httpServer; -346 } -347 -348 protected void printUsageAndExit(Options options, int exitCode) -349 throws ExitCodeException { -350 HelpFormatter formatter = new HelpFormatter(); -351 formatter.printHelp("Thrift", null, options, -352 "To start the Thrift server run 'hbase-daemon.sh start thrift' or " + -353 "'hbase thrift'\n" + -354 "To shutdown the thrift server run 'hbase-daemon.sh stop " + -355 "thrift' or send a kill signal to the thrift server pid", -356 true); -357 throw new ExitCodeException(exitCode, ""); -358 } -359 -360 /** -361 * Create a Servlet for the http server -362 * @param protocolFactory protocolFactory -363 * @return the servlet -364 */ -365 protected TServlet createTServlet(TProtocolFactory protocolFactory) { -366 return new ThriftHttpServlet(processor, protocolFactory, serviceUGI, httpUGI, -367 hbaseServiceHandler, securityEnabled, doAsEnabled); -368 } -369 -370 /** -371 * Setup an HTTP Server using Jetty to serve calls from THttpClient -372 * -373 * @throws IOException IOException -374 */ -375 protected void setupHTTPServer() throws IOException { -376 TProtocolFactory protocolFactory = new TBinaryProtocol.Factory(); -377 TServlet thriftHttpServlet = createTServlet(protocolFactory); -378 -379 // Set the default max thread number to 100 to limit -380 // the number of concurrent requests so that Thrfit HTTP server doesn't OOM easily. -381 // Jetty set the default max thread number to 250, if we don't set it. -382 // -383 // Our default min thread number 2 is the same as that used by Jetty. -384 int minThreads = conf.getInt(HTTP_MIN_THREADS_KEY, -385 conf.getInt(TBoundedThreadPoolServer.MIN_WORKER_THREADS_CONF_KEY, -386 HTTP_MIN_THREADS_KEY_DEFAULT)); -387 int maxThreads = conf.getInt(HTTP_MAX_THREADS_KEY, -388 conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, -389 HTTP_MAX_THREADS_KEY_DEFAULT)); -390 QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads); -391 threadPool.setMinThreads(minThreads); -392 httpServer = new Server(threadPool); -393 -394 // Context handler -395 ServletContextHandler ctxHandler = new ServletContextHandler(httpServer, "/", -396 ServletContextHandler.SESSIONS); -397 ctxHandler.addServlet(new ServletHolder(thriftHttpServlet), "/*"); -398 HttpServerUtil.constrainHttpMethods(ctxHandler, -399 conf.getBoolean(THRIFT_HTTP_ALLOW_OPTIONS_METHOD, -400 THRIFT_HTTP_ALLOW_OPTIONS_METHOD_DEFAULT)); -401 -402 // set up Jetty and run the embedded server -403 HttpConfiguration httpConfig = new HttpConfiguration(); -404 httpConfig.setSecureScheme("https"); -405 httpConfig.setSecurePort(listenPort); -406 httpConfig.setHeaderCacheSize(DEFAULT_HTTP_MAX_HEADER_SIZE); -407 httpConfig.setRequestHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); -408 httpConfig.setResponseHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); -409 httpConfig.setSendServerVersion(false); -410 httpConfig.setSendDateHeader(false); -411 -412 ServerConnector serverConnector; -413 if(conf.getBoolean(THRIFT_SSL_ENABLED_KEY, false)) { -414 HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); -415 httpsConfig.addCustomizer(new SecureRequestCustomizer()); -416 -417 SslContextFactory sslCtxFactory = new SslContextFactory(); -418 String keystore = conf.get(THRIFT_SSL_KEYSTORE_STORE_KEY); -419 String password = HBaseConfiguration.getPassword(conf, -420 THRIFT_SSL_KEYSTORE_PASSWORD_KEY, null); -421 String keyPassword = HBaseConfiguration.getPassword(conf, -422 THRIFT_SSL_KEYSTORE_KEYPASSWORD_KEY, password); -423 sslCtxFactory.setKeyStorePath(keystore); -424 sslCtxFactory.setKeyStorePassword(password); -425 sslCtxFactory.setKeyManagerPassword(keyPassword); -426 -427 String[] excludeCiphers = conf.getStrings( -428 THRIFT_SSL_EXCLUDE_CIPHER_SUITES_KEY, ArrayUtils.EMPTY_STRING_ARRAY); -429 if (excludeCiphers.length != 0) { -430 sslCtxFactory.setExcludeCipherSuites(excludeCiphers); -431 } -432 String[] includeCiphers = conf.getStrings( -433 THRIFT_SSL_INCLUDE_CIPHER_SUITES_KEY, ArrayUtils.EMPTY_STRING_ARRAY); -434 if (includeCiphers.length != 0) { -435 sslCtxFactory.setIncludeCipherSuites(includeCiphers); -436 } -437 -438 // Disable SSLv3 by default due to "Poodle" Vulnerability - CVE-2014-3566 -439 String[] excludeProtocols = conf.getStrings( -440 THRIFT_SSL_EXCLUDE_PROTOCOLS_KEY, "SSLv3"); -441 if (excludeProtocols.length != 0) { -442 sslCtxFactory.setExcludeProtocols(excludeProtocols); -443 } -444 String[] includeProtocols = conf.getStrings( -445 THRIFT_SSL_INCLUDE_PROTOCOLS_KEY, ArrayUtils.EMPTY_STRING_ARRAY); -446 if (includeProtocols.length != 0) { -447 sslCtxFactory.setIncludeProtocols(includeProtocols); -448 } -449 -450 serverConnector = new ServerConnector(httpServer, -451 new SslConnectionFactory(sslCtxFactory, HttpVersion.HTTP_1_1.toString()), -452 new HttpConnectionFactory(httpsConfig)); -453 } else { -454 serverConnector = new ServerConnector(httpServer, new HttpConnectionFactory(httpConfig)); -455 } -456 serverConnector.setPort(listenPort); -457 serverConnector.setHost(getBindAddress(conf).getHostAddress()); -458 httpServer.addConnector(serverConnector); -459 httpServer.setStopAtShutdown(true); -460 -461 if (doAsEnabled) { -462 ProxyUsers.refreshSuperUserGroupsConfiguration(conf); -463 } -464 LOG.info("Starting Thrift HTTP Server on {}", Integer.toString(listenPort)); -465 } -466 -467 /** -468 * Setting up the thrift TServer -469 */ -470 protected void setupServer() throws Exception { -471 // Construct correct ProtocolFactory -472 TProtocolFactory protocolFactory = getProtocolFactory(); -473 -474 ImplType implType = ImplType.getServerImpl(conf); -475 TProcessor processorToUse = processor; -476 -477 // Construct correct TransportFactory -478 TTransportFactory transportFactory; -479 if (conf.getBoolean(FRAMED_CONF_KEY, FRAMED_CONF_DEFAULT) || implType.isAlwaysFramed) { -480 if (qop != null) { -481 throw new RuntimeException("Thrift server authentication" -482 + " doesn't work with framed transport yet"); -483 } -484 transportFactory = new TFramedTransport.Factory( -485 conf.getInt(MAX_FRAME_SIZE_CONF_KEY, MAX_FRAME_SIZE_CONF_DEFAULT) * 1024 * 1024); -486 LOG.debug("Using framed transport"); -487 } else if (qop == null) { -488 transportFactory = new TTransportFactory(); -489 } else { -490 // Extract the name from the principal -491 String thriftKerberosPrincipal = conf.get(THRIFT_KERBEROS_PRINCIPAL_KEY); -492 if (thriftKerberosPrincipal == null) { -493 throw new IllegalArgumentException(THRIFT_KERBEROS_PRINCIPAL_KEY + " cannot be null"); -494 } -495 String name = SecurityUtil.getUserFromPrincipal(thriftKerberosPrincipal); -496 Map<String, String> saslProperties = SaslUtil.initSaslProperties(qop.name()); -497 TSaslServerTransport.Factory saslFactory = new TSaslServerTransport.Factory(); -498 saslFactory.addServerDefinition("GSSAPI", name, host, saslProperties, -499 new SaslRpcServer.SaslGssCallbackHandler() { -500 @Override -501 public void handle(Callback[] callbacks) -502 throws UnsupportedCallbackException { -503 AuthorizeCallback ac = null; -504 for (Callback callback : callbacks) { -505 if (callback instanceof AuthorizeCallback) { -506 ac = (AuthorizeCallback) callback; -507 } else { -508 throw new UnsupportedCallbackException(callback, -509 "Unrecognized SASL GSSAPI Callback"); -510 } -511 } -512 if (ac != null) { -513 String authid = ac.getAuthenticationID(); -514 String authzid = ac.getAuthorizationID(); -515 if (!authid.equals(authzid)) { -516 ac.setAuthorized(false); -517 } else { -518 ac.setAuthorized(true); -519 String userName = SecurityUtil.getUserFromPrincipal(authzid); -520 LOG.info("Effective user: {}", userName); -521 ac.setAuthorizedID(userName); -522 } -523 } -524 } -525 }); -526 transportFactory = saslFactory; -527 -528 // Create a processor wrapper, to get the caller -529 processorToUse = (inProt, outProt) -> { -530 TSaslServerTransport saslServerTransport = -531 (TSaslServerTransport)inProt.getTransport(); -532 SaslServer saslServer = saslServerTransport.getSaslServer(); -533 String principal = saslServer.getAuthorizationID(); -534 hbaseServiceHandler.setEffectiveUser(principal); -535 processor.process(inProt, outProt); -536 }; -537 } -538 -539 if (conf.get(BIND_CONF_KEY) != null && !implType.canSpecifyBindIP) { -540 LOG.error("Server types {} don't support IP address binding at the moment. See " + -541 "https://issues.apache.org/jira/browse/HBASE-2155 for details.", -542 Joiner.on(", ").join(ImplType.serversThatCannotSpecifyBindIP())); -543 throw new RuntimeException("-" + BIND_CONF_KEY + " not supported with " + implType); -544 } -545 -546 InetSocketAddress inetSocketAddress = new InetSocketAddress(getBindAddress(conf), listenPort); -547 if (implType == ImplType.HS_HA || implType == ImplType.NONBLOCKING || -548 implType == ImplType.THREADED_SELECTOR) { -549 TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(inetSocketAddress); -550 if (implType == ImplType.NONBLOCKING) { -551 tserver = getTNonBlockingServer(serverTransport, protocolFactory, processorToUse, -552 transportFactory, inetSocketAddress); -553 } else if (implType == ImplType.HS_HA) { -554 tserver = getTHsHaServer(serverTransport, protocolFactory, processorToUse, transportFactory, -555 inetSocketAddress); -556 } else { // THREADED_SELECTOR -557 tserver = getTThreadedSelectorServer(serverTransport, protocolFactory, processorToUse, -558 transportFactory, inetSocketAddress); -559 } -560 LOG.info("starting HBase {} server on {}", implType.simpleClassName(), -561 Integer.toString(listenPort)); -562 } else if (implType == ImplType.THREAD_POOL) { -563 this.tserver = getTThreadPoolServer(protocolFactory, processorToUse, transportFactory, -564 inetSocketAddress); -565 } else { -566 throw new AssertionError("Unsupported Thrift server implementation: " + -567 implType.simpleClassName()); -568 } -569 -570 // A sanity check that we instantiated the right type of server. -571 if (tserver.getClass() != implType.serverClass) { -572 throw new AssertionError("Expected to create Thrift server class " + -573 implType.serverClass.getName() + " but got " + -574 tserver.getClass().getName()); -575 } -576 } -577 -578 protected TServer getTNonBlockingServer(TNonblockingServerTransport serverTransport, -579 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, -580 InetSocketAddress inetSocketAddress) { -581 LOG.info("starting HBase Nonblocking Thrift server on " + inetSocketAddress.toString()); -582 TNonblockingServer.Args serverArgs = new TNonblockingServer.Args(serverTransport); -583 serverArgs.processor(processor); -584 serverArgs.transportFactory(transportFactory); -585 serverArgs.protocolFactory(protocolFactory); -586 return new TNonblockingServer(serverArgs); -587 } -588 -589 protected TServer getTHsHaServer(TNonblockingServerTransport serverTransport, -590 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, -591 InetSocketAddress inetSocketAddress) { -592 LOG.info("starting HBase HsHA Thrift server on " + inetSocketAddress.toString()); -593 THsHaServer.Args serverArgs = new THsHaServer.Args(serverTransport); -594 int queueSize = conf.getInt(TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY, -595 TBoundedThreadPoolServer.DEFAULT_MAX_QUEUED_REQUESTS); -596 CallQueue callQueue = new CallQueue(new LinkedBlockingQueue<>(queueSize), metrics); -597 int workerThread = conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, -598 serverArgs.getMaxWorkerThreads()); -599 ExecutorService executorService = createExecutor( -600 callQueue, workerThread, workerThread); -601 serverArgs.executorService(executorService).processor(processor) -602 .transportFactory(transportFactory).protocolFactory(protocolFactory); -603 return new THsHaServer(serverArgs); -604 } -605 -606 protected TServer getTThreadedSelectorServer(TNonblockingServerTransport serverTransport, -607 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, -608 InetSocketAddress inetSocketAddress) { -609 LOG.info("starting HBase ThreadedSelector Thrift server on " + inetSocketAddress.toString()); -610 TThreadedSelectorServer.Args serverArgs = -611 new HThreadedSelectorServerArgs(serverTransport, conf); -612 int queueSize = conf.getInt(TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY, -613 TBoundedThreadPoolServer.DEFAULT_MAX_QUEUED_REQUESTS); -614 CallQueue callQueue = new CallQueue(new LinkedBlockingQueue<>(queueSize), metrics); -615 int workerThreads = conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, -616 serverArgs.getWorkerThreads()); -617 int selectorThreads = conf.getInt(THRIFT_SELECTOR_NUM, serverArgs.getSelectorThreads()); -618 serverArgs.selectorThreads(selectorThreads); -619 ExecutorService executorService = createExecutor( -620 callQueue, workerThreads, workerThreads); -621 serverArgs.executorService(executorService).processor(processor) -622 .transportFactory(transportFactory).protocolFactory(protocolFactory); -623 return new TThreadedSelectorServer(serverArgs); -624 } -625 -626 protected TServer getTThreadPoolServer(TProtocolFactory protocolFactory, TProcessor processor, -627 TTransportFactory transportFactory, InetSocketAddress inetSocketAddress) throws Exception { -628 LOG.info("starting HBase ThreadPool Thrift server on " + inetSocketAddress.toString()); -629 // Thrift's implementation uses '0' as a placeholder for 'use the default.' -630 int backlog = conf.getInt(BACKLOG_CONF_KEY, BACKLOG_CONF_DEAFULT); -631 int readTimeout = conf.getInt(THRIFT_SERVER_SOCKET_READ_TIMEOUT_KEY, -632 THRIFT_SERVER_SOCKET_READ_TIMEOUT_DEFAULT); -633 TServerTransport serverTransport = new TServerSocket( -634 new TServerSocket.ServerSocketTransportArgs(). -635 bindAddr(inetSocketAddress).backlog(backlog). -636 clientTimeout(readTimeout)); -637 -638 TBoundedThreadPoolServer.Args serverArgs = -639 new TBoundedThreadPoolServer.Args(serverTransport, conf); -640 serverArgs.processor(processor).transportFactory(transportFactory) -641 .protocolFactory(protocolFactory); -642 return new TBoundedThreadPoolServer(serverArgs, metrics); -643 } -644 -645 protected TProtocolFactory getProtocolFactory() { -646 TProtocolFactory protocolFactory; -647 -648 if (conf.getBoolean(COMPACT_CONF_KEY, COMPACT_CONF_DEFAULT)) { -649 LOG.debug("Using compact protocol"); -650 protocolFactory = new TCompactProtocol.Factory(); -651 } else { -652 LOG.debug("Using binary protocol"); -653 protocolFactory = new TBinaryProtocol.Factory(); -654 } -655 -656 return protocolFactory; -657 } -658 -659 protected ExecutorService createExecutor(BlockingQueue<Runnable> callQueue, -660 int minWorkers, int maxWorkers) { -661 ThreadFactoryBuilder tfb = new ThreadFactoryBuilder(); -662 tfb.setDaemon(true); -663 tfb.setNameFormat("thrift-worker-%d"); -664 ThreadPoolExecutor threadPool = new THBaseThreadPoolExecutor(minWorkers, maxWorkers, -665 Long.MAX_VALUE, TimeUnit.SECONDS, callQueue, tfb.build(), metrics); -666 threadPool.allowCoreThreadTimeOut(true); -667 return threadPool; -668 } -669 -670 protected InetAddress getBindAddress(Configuration conf) -671 throws UnknownHostException { -672 String bindAddressStr = conf.get(BIND_CONF_KEY, DEFAULT_BIND_ADDR); -673 return InetAddress.getByName(bindAddressStr); -674 } -675 -676 -677 public static void registerFilters(Configuration conf) { -678 String[] filters = conf.getStrings(THRIFT_FILTERS); -679 Splitter splitter = Splitter.on(':'); -680 if(filters != null) { -681 for(String filterClass: filters) { -682 List<String> filterPart = splitter.splitToList(filterClass); -683 if(filterPart.size() != 2) { -684 LOG.warn("Invalid filter specification " + filterClass + " - skipping"); -685 } else { -686 ParseFilter.registerFilter(filterPart.get(0), filterPart.get(1)); -687 } -688 } -689 } -690 } -691 -692 /** -693 * Add options to command lines -694 * @param options options -695 */ -696 protected void addOptions(Options options) { -697 options.addOption("b", BIND_OPTION, true, "Address to bind " + -698 "the Thrift server to. [default: " + DEFAULT_BIND_ADDR + "]"); -699 options.addOption("p", PORT_OPTION, true, "Port to bind to [default: " + -700 DEFAULT_LISTEN_PORT + "]"); -701 options.addOption("f", FRAMED_OPTION, false, "Use framed transport"); -702 options.addOption("c", COMPACT_OPTION, false, "Use the compact protocol"); -703 options.addOption("h", "help", false, "Print help information"); -704 options.addOption("s", SELECTOR_NUM_OPTION, true, "How many selector threads to use."); -705 options.addOption(null, INFOPORT_OPTION, true, "Port for web UI"); -706 -707 options.addOption("m", MIN_WORKERS_OPTION, true, -708 "The minimum number of worker threads for " + -709 ImplType.THREAD_POOL.simpleClassName()); -710 -711 options.addOption("w", MAX_WORKERS_OPTION, true, -712 "The maximum number of worker threads for " + -713 ImplType.THREAD_POOL.simpleClassName()); -714 -715 options.addOption("q", MAX_QUEUE_SIZE_OPTION, true, -716 "The maximum number of queued requests in " + -717 ImplType.THREAD_POOL.simpleClassName()); -718 -719 options.addOption("k", KEEP_ALIVE_SEC_OPTION, true, -720 "The amount of time in secods to keep a thread alive when idle in " + -721 ImplType.THREAD_POOL.simpleClassName()); -722 -723 options.addOption("t", READ_TIMEOUT_OPTION, true, -724 "Amount of time in milliseconds before a server thread will timeout " + -725 "waiting for client to send data on a connected socket. Currently, " + -726 "only applies to TBoundedThreadPoolServer"); -727 -728 options.addOptionGroup(ImplType.createOptionGroup()); -729 } -730 -731 protected void parseCommandLine(CommandLine cmd, Options options) throws ExitCodeException { -732 // Get port to bind to -733 try { -734 if (cmd.hasOption(PORT_OPTION)) { -735 int listenPort = Integer.parseInt(cmd.getOptionValue(PORT_OPTION)); -736 conf.setInt(PORT_CONF_KEY, listenPort); -737 } -738 } catch (NumberFormatException e) { -739 LOG.error("Could not parse the value provided for the port option", e); -740 printUsageAndExit(options, -1); -741 } -742 // check for user-defined info server port setting, if so override the conf -743 try { -744 if (cmd.hasOption(INFOPORT_OPTION)) { -745 String val = cmd.getOptionValue(INFOPORT_OPTION); -746 conf.setInt(THRIFT_INFO_SERVER_PORT, Integer.parseInt(val)); -747 LOG.debug("Web UI port set to " + val); -748 } -749 } catch (NumberFormatException e) { -750 LOG.error("Could not parse the value provided for the " + INFOPORT_OPTION + -751 " option", e); -752 printUsageAndExit(options, -1); -753 } -754 // Make optional changes to the configuration based on command-line options -755 optionToConf(cmd, MIN_WORKERS_OPTION, -756 conf, TBoundedThreadPoolServer.MIN_WORKER_THREADS_CONF_KEY); -757 optionToConf(cmd, MAX_WORKERS_OPTION, -758 conf, TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY); -759 optionToConf(cmd, MAX_QUEUE_SIZE_OPTION, -760 conf, TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY); -761 optionToConf(cmd, KEEP_ALIVE_SEC_OPTION, -762 conf, TBoundedThreadPoolServer.THREAD_KEEP_ALIVE_TIME_SEC_CONF_KEY); -763 optionToConf(cmd, READ_TIMEOUT_OPTION, conf, THRIFT_SERVER_SOCKET_READ_TIMEOUT_KEY); -764 optionToConf(cmd, SELECTOR_NUM_OPTION, conf, THRIFT_SELECTOR_NUM); -765 -766 // Set general thrift server options -767 boolean compact = cmd.hasOption(COMPACT_OPTION) || -768 conf.getBoolean(COMPACT_CONF_KEY, false); -769 conf.setBoolean(COMPACT_CONF_KEY, compact); -770 boolean framed = cmd.hasOption(FRAMED_OPTION) || -771 conf.getBoolean(FRAMED_CONF_KEY, false); -772 conf.setBoolean(FRAMED_CONF_KEY, framed); -773 -774 optionToConf(cmd, BIND_OPTION, conf, BIND_CONF_KEY); +196 // Main program and support routines +197 // +198 +199 public ThriftServer(Configuration conf) { +200 this.conf = HBaseConfiguration.create(conf); +201 } +202 +203 protected ThriftMetrics createThriftMetrics(Configuration conf) { +204 return new ThriftMetrics(conf, ThriftMetrics.ThriftServerType.ONE); +205 } +206 +207 protected void setupParamters() throws IOException { +208 // login the server principal (if using secure Hadoop) +209 UserProvider userProvider = UserProvider.instantiate(conf); +210 securityEnabled = userProvider.isHadoopSecurityEnabled() +211 && userProvider.isHBaseSecurityEnabled(); +212 if (securityEnabled) { +213 host = Strings.domainNamePointerToHostName(DNS.getDefaultHost( +214 conf.get(THRIFT_DNS_INTERFACE_KEY, "default"), +215 conf.get(THRIFT_DNS_NAMESERVER_KEY, "default"))); +216 userProvider.login(THRIFT_KEYTAB_FILE_KEY, THRIFT_KERBEROS_PRINCIPAL_KEY, host); +217 +218 // Setup the SPNEGO user for HTTP if configured +219 String spnegoPrincipal = getSpengoPrincipal(conf, host); +220 String spnegoKeytab = getSpnegoKeytab(conf); +221 UserGroupInformation.setConfiguration(conf); +222 // login the SPNEGO principal using UGI to avoid polluting the login user +223 this.httpUGI = UserGroupInformation.loginUserFromKeytabAndReturnUGI(spnegoPrincipal, +224 spnegoKeytab); +225 } +226 this.serviceUGI = userProvider.getCurrent().getUGI(); +227 if (httpUGI == null) { +228 this.httpUGI = serviceUGI; +229 } +230 +231 this.listenPort = conf.getInt(PORT_CONF_KEY, DEFAULT_LISTEN_PORT); +232 this.metrics = createThriftMetrics(conf); +233 this.pauseMonitor = new JvmPauseMonitor(conf, this.metrics.getSource()); +234 this.hbaseServiceHandler = createHandler(conf, userProvider); +235 this.hbaseServiceHandler.initMetrics(metrics); +236 this.processor = createProcessor(); +237 +238 httpEnabled = conf.getBoolean(USE_HTTP_CONF_KEY, false); +239 doAsEnabled = conf.getBoolean(THRIFT_SUPPORT_PROXYUSER_KEY, false); +240 if (doAsEnabled && !httpEnabled) { +241 LOG.warn("Fail to enable the doAs feature. " + USE_HTTP_CONF_KEY + " is not configured"); +242 } +243 +244 String strQop = conf.get(THRIFT_QOP_KEY); +245 if (strQop != null) { +246 this.qop = SaslUtil.getQop(strQop); +247 } +248 if (qop != null) { +249 if (qop != SaslUtil.QualityOfProtection.AUTHENTICATION && +250 qop != SaslUtil.QualityOfProtection.INTEGRITY && +251 qop != SaslUtil.QualityOfProtection.PRIVACY) { +252 throw new IOException(String.format("Invalid %s: It must be one of %s, %s, or %s.", +253 THRIFT_QOP_KEY, +254 SaslUtil.QualityOfProtection.AUTHENTICATION.name(), +255 SaslUtil.QualityOfProtection.INTEGRITY.name(), +256 SaslUtil.QualityOfProtection.PRIVACY.name())); +257 } +258 checkHttpSecurity(qop, conf); +259 if (!securityEnabled) { +260 throw new IOException("Thrift server must run in secure mode to support authentication"); +261 } +262 } +263 registerFilters(conf); +264 pauseMonitor.start(); +265 } +266 +267 private String getSpengoPrincipal(Configuration conf, String host) throws IOException { +268 String principal = conf.get(THRIFT_SPNEGO_PRINCIPAL_KEY); +269 if (principal == null) { +270 // We cannot use the Hadoop configuration deprecation handling here since +271 // the THRIFT_KERBEROS_PRINCIPAL_KEY config is still valid for regular Kerberos +272 // communication. The preference should be to use the THRIFT_SPNEGO_PRINCIPAL_KEY +273 // config so that THRIFT_KERBEROS_PRINCIPAL_KEY doesn't control both backend +274 // Kerberos principal and SPNEGO principal. +275 LOG.info("Using deprecated {} config for SPNEGO principal. Use {} instead.", +276 THRIFT_KERBEROS_PRINCIPAL_KEY, THRIFT_SPNEGO_PRINCIPAL_KEY); +277 principal = conf.get(THRIFT_KERBEROS_PRINCIPAL_KEY); +278 } +279 // Handle _HOST in principal value +280 return org.apache.hadoop.security.SecurityUtil.getServerPrincipal(principal, host); +281 } +282 +283 private String getSpnegoKeytab(Configuration conf) { +284 String keytab = conf.get(THRIFT_SPNEGO_KEYTAB_FILE_KEY); +285 if (keytab == null) { +286 // We cannot use the Hadoop configuration deprecation handling here since +287 // the THRIFT_KEYTAB_FILE_KEY config is still valid for regular Kerberos +288 // communication. The preference should be to use the THRIFT_SPNEGO_KEYTAB_FILE_KEY +289 // config so that THRIFT_KEYTAB_FILE_KEY doesn't control both backend +290 // Kerberos keytab and SPNEGO keytab. +291 LOG.info("Using deprecated {} config for SPNEGO keytab. Use {} instead.", +292 THRIFT_KEYTAB_FILE_KEY, THRIFT_SPNEGO_KEYTAB_FILE_KEY); +293 keytab = conf.get(THRIFT_KEYTAB_FILE_KEY); +294 } +295 return keytab; +296 } +297 +298 protected void startInfoServer() throws IOException { +299 // Put up info server. +300 int port = conf.getInt(THRIFT_INFO_SERVER_PORT , THRIFT_INFO_SERVER_PORT_DEFAULT); +301 +302 if (port >= 0) { +303 conf.setLong("startcode", EnvironmentEdgeManager.currentTime()); +304 String a = conf +305 .get(THRIFT_INFO_SERVER_BINDING_ADDRESS, THRIFT_INFO_SERVER_BINDING_ADDRESS_DEFAULT); +306 infoServer = new InfoServer("thrift", a, port, false, conf); +307 infoServer.setAttribute("hbase.conf", conf); +308 infoServer.setAttribute("hbase.thrift.server.type", metrics.getThriftServerType().name()); +309 infoServer.start(); +310 } +311 } +312 +313 protected void checkHttpSecurity(SaslUtil.QualityOfProtection qop, Configuration conf) { +314 if (qop == SaslUtil.QualityOfProtection.PRIVACY && +315 conf.getBoolean(USE_HTTP_CONF_KEY, false) && +316 !conf.getBoolean(THRIFT_SSL_ENABLED_KEY, false)) { +317 throw new IllegalArgumentException("Thrift HTTP Server's QoP is privacy, but " + +318 THRIFT_SSL_ENABLED_KEY + " is false"); +319 } +320 } +321 +322 protected HBaseServiceHandler createHandler(Configuration conf, UserProvider userProvider) +323 throws IOException { +324 return new ThriftHBaseServiceHandler(conf, userProvider); +325 } +326 +327 protected TProcessor createProcessor() { +328 return new Hbase.Processor<>( +329 HbaseHandlerMetricsProxy.newInstance((Hbase.Iface) hbaseServiceHandler, metrics, conf)); +330 } +331 +332 /** +333 * the thrift server, not null means the server is started, for test only +334 * @return the tServer +335 */ +336 @InterfaceAudience.Private +337 public TServer getTserver() { +338 return tserver; +339 } +340 +341 /** +342 * the Jetty server, not null means the HTTP server is started, for test only +343 * @return the http server +344 */ +345 @InterfaceAudience.Private +346 public Server getHttpServer() { +347 return httpServer; +348 } +349 +350 protected void printUsageAndExit(Options options, int exitCode) +351 throws ExitCodeException { +352 HelpFormatter formatter = new HelpFormatter(); +353 formatter.printHelp("Thrift", null, options, +354 "To start the Thrift server run 'hbase-daemon.sh start thrift' or " + +355 "'hbase thrift'\n" + +356 "To shutdown the thrift server run 'hbase-daemon.sh stop " + +357 "thrift' or send a kill signal to the thrift server pid", +358 true); +359 throw new ExitCodeException(exitCode, ""); +360 } +361 +362 /** +363 * Create a Servlet for the http server +364 * @param protocolFactory protocolFactory +365 * @return the servlet +366 */ +367 protected TServlet createTServlet(TProtocolFactory protocolFactory) { +368 return new ThriftHttpServlet(processor, protocolFactory, serviceUGI, httpUGI, +369 hbaseServiceHandler, securityEnabled, doAsEnabled); +370 } +371 +372 /** +373 * Setup an HTTP Server using Jetty to serve calls from THttpClient +374 * +375 * @throws IOException IOException +376 */ +377 protected void setupHTTPServer() throws IOException { +378 TProtocolFactory protocolFactory = new TBinaryProtocol.Factory(); +379 TServlet thriftHttpServlet = createTServlet(protocolFactory); +380 +381 // Set the default max thread number to 100 to limit +382 // the number of concurrent requests so that Thrfit HTTP server doesn't OOM easily. +383 // Jetty set the default max thread number to 250, if we don't set it. +384 // +385 // Our default min thread number 2 is the same as that used by Jetty. +386 int minThreads = conf.getInt(HTTP_MIN_THREADS_KEY, +387 conf.getInt(TBoundedThreadPoolServer.MIN_WORKER_THREADS_CONF_KEY, +388 HTTP_MIN_THREADS_KEY_DEFAULT)); +389 int maxThreads = conf.getInt(HTTP_MAX_THREADS_KEY, +390 conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, +391 HTTP_MAX_THREADS_KEY_DEFAULT)); +392 QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads); +393 threadPool.setMinThreads(minThreads); +394 httpServer = new Server(threadPool); +395 +396 // Context handler +397 ServletContextHandler ctxHandler = new ServletContextHandler(httpServer, "/", +398 ServletContextHandler.SESSIONS); +399 ctxHandler.addServlet(new ServletHolder(thriftHttpServlet), "/*"); +400 HttpServerUtil.constrainHttpMethods(ctxHandler, +401 conf.getBoolean(THRIFT_HTTP_ALLOW_OPTIONS_METHOD, +402 THRIFT_HTTP_ALLOW_OPTIONS_METHOD_DEFAULT)); +403 +404 // set up Jetty and run the embedded server +405 HttpConfiguration httpConfig = new HttpConfiguration(); +406 httpConfig.setSecureScheme("https"); +407 httpConfig.setSecurePort(listenPort); +408 httpConfig.setHeaderCacheSize(DEFAULT_HTTP_MAX_HEADER_SIZE); +409 httpConfig.setRequestHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); +410 httpConfig.setResponseHeaderSize(DEFAULT_HTTP_MAX_HEADER_SIZE); +411 httpConfig.setSendServerVersion(false); +412 httpConfig.setSendDateHeader(false); +413 +414 ServerConnector serverConnector; +415 if(conf.getBoolean(THRIFT_SSL_ENABLED_KEY, false)) { +416 HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig); +417 httpsConfig.addCustomizer(new SecureRequestCustomizer()); +418 +419 SslContextFactory sslCtxFactory = new SslContextFactory(); +420 String keystore = conf.get(THRIFT_SSL_KEYSTORE_STORE_KEY); +421 String password = HBaseConfiguration.getPassword(conf, +422 THRIFT_SSL_KEYSTORE_PASSWORD_KEY, null); +423 String keyPassword = HBaseConfiguration.getPassword(conf, +424 THRIFT_SSL_KEYSTORE_KEYPASSWORD_KEY, password); +425 sslCtxFactory.setKeyStorePath(keystore); +426 sslCtxFactory.setKeyStorePassword(password); +427 sslCtxFactory.setKeyManagerPassword(keyPassword); +428 +429 String[] excludeCiphers = conf.getStrings( +430 THRIFT_SSL_EXCLUDE_CIPHER_SUITES_KEY, ArrayUtils.EMPTY_STRING_ARRAY); +431 if (excludeCiphers.length != 0) { +432 sslCtxFactory.setExcludeCipherSuites(excludeCiphers); +433 } +434 String[] includeCiphers = conf.getStrings( +435 THRIFT_SSL_INCLUDE_CIPHER_SUITES_KEY, ArrayUtils.EMPTY_STRING_ARRAY); +436 if (includeCiphers.length != 0) { +437 sslCtxFactory.setIncludeCipherSuites(includeCiphers); +438 } +439 +440 // Disable SSLv3 by default due to "Poodle" Vulnerability - CVE-2014-3566 +441 String[] excludeProtocols = conf.getStrings( +442 THRIFT_SSL_EXCLUDE_PROTOCOLS_KEY, "SSLv3"); +443 if (excludeProtocols.length != 0) { +444 sslCtxFactory.setExcludeProtocols(excludeProtocols); +445 } +446 String[] includeProtocols = conf.getStrings( +447 THRIFT_SSL_INCLUDE_PROTOCOLS_KEY, ArrayUtils.EMPTY_STRING_ARRAY); +448 if (includeProtocols.length != 0) { +449 sslCtxFactory.setIncludeProtocols(includeProtocols); +450 } +451 +452 serverConnector = new ServerConnector(httpServer, +453 new SslConnectionFactory(sslCtxFactory, HttpVersion.HTTP_1_1.toString()), +454 new HttpConnectionFactory(httpsConfig)); +455 } else { +456 serverConnector = new ServerConnector(httpServer, new HttpConnectionFactory(httpConfig)); +457 } +458 serverConnector.setPort(listenPort); +459 serverConnector.setHost(getBindAddress(conf).getHostAddress()); +460 httpServer.addConnector(serverConnector); +461 httpServer.setStopAtShutdown(true); +462 +463 if (doAsEnabled) { +464 ProxyUsers.refreshSuperUserGroupsConfiguration(conf); +465 } +466 LOG.info("Starting Thrift HTTP Server on {}", Integer.toString(listenPort)); +467 } +468 +469 /** +470 * Setting up the thrift TServer +471 */ +472 protected void setupServer() throws Exception { +473 // Construct correct ProtocolFactory +474 TProtocolFactory protocolFactory = getProtocolFactory(); +475 +476 ImplType implType = ImplType.getServerImpl(conf); +477 TProcessor processorToUse = processor; +478 +479 // Construct correct TransportFactory +480 TTransportFactory transportFactory; +481 if (conf.getBoolean(FRAMED_CONF_KEY, FRAMED_CONF_DEFAULT) || implType.isAlwaysFramed) { +482 if (qop != null) { +483 throw new RuntimeException("Thrift server authentication" +484 + " doesn't work with framed transport yet"); +485 } +486 transportFactory = new TFramedTransport.Factory( +487 conf.getInt(MAX_FRAME_SIZE_CONF_KEY, MAX_FRAME_SIZE_CONF_DEFAULT) * 1024 * 1024); +488 LOG.debug("Using framed transport"); +489 } else if (qop == null) { +490 transportFactory = new TTransportFactory(); +491 } else { +492 // Extract the name from the principal +493 String thriftKerberosPrincipal = conf.get(THRIFT_KERBEROS_PRINCIPAL_KEY); +494 if (thriftKerberosPrincipal == null) { +495 throw new IllegalArgumentException(THRIFT_KERBEROS_PRINCIPAL_KEY + " cannot be null"); +496 } +497 String name = SecurityUtil.getUserFromPrincipal(thriftKerberosPrincipal); +498 Map<String, String> saslProperties = SaslUtil.initSaslProperties(qop.name()); +499 TSaslServerTransport.Factory saslFactory = new TSaslServerTransport.Factory(); +500 saslFactory.addServerDefinition("GSSAPI", name, host, saslProperties, +501 new SaslRpcServer.SaslGssCallbackHandler() { +502 @Override +503 public void handle(Callback[] callbacks) +504 throws UnsupportedCallbackException { +505 AuthorizeCallback ac = null; +506 for (Callback callback : callbacks) { +507 if (callback instanceof AuthorizeCallback) { +508 ac = (AuthorizeCallback) callback; +509 } else { +510 throw new UnsupportedCallbackException(callback, +511 "Unrecognized SASL GSSAPI Callback"); +512 } +513 } +514 if (ac != null) { +515 String authid = ac.getAuthenticationID(); +516 String authzid = ac.getAuthorizationID(); +517 if (!authid.equals(authzid)) { +518 ac.setAuthorized(false); +519 } else { +520 ac.setAuthorized(true); +521 String userName = SecurityUtil.getUserFromPrincipal(authzid); +522 LOG.info("Effective user: {}", userName); +523 ac.setAuthorizedID(userName); +524 } +525 } +526 } +527 }); +528 transportFactory = saslFactory; +529 +530 // Create a processor wrapper, to get the caller +531 processorToUse = (inProt, outProt) -> { +532 TSaslServerTransport saslServerTransport = +533 (TSaslServerTransport)inProt.getTransport(); +534 SaslServer saslServer = saslServerTransport.getSaslServer(); +535 String principal = saslServer.getAuthorizationID(); +536 hbaseServiceHandler.setEffectiveUser(principal); +537 processor.process(inProt, outProt); +538 }; +539 } +540 +541 if (conf.get(BIND_CONF_KEY) != null && !implType.canSpecifyBindIP) { +542 LOG.error("Server types {} don't support IP address binding at the moment. See " + +543 "https://issues.apache.org/jira/browse/HBASE-2155 for details.", +544 Joiner.on(", ").join(ImplType.serversThatCannotSpecifyBindIP())); +545 throw new RuntimeException("-" + BIND_CONF_KEY + " not supported with " + implType); +546 } +547 +548 InetSocketAddress inetSocketAddress = new InetSocketAddress(getBindAddress(conf), listenPort); +549 if (implType == ImplType.HS_HA || implType == ImplType.NONBLOCKING || +550 implType == ImplType.THREADED_SELECTOR) { +551 TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(inetSocketAddress); +552 if (implType == ImplType.NONBLOCKING) { +553 tserver = getTNonBlockingServer(serverTransport, protocolFactory, processorToUse, +554 transportFactory, inetSocketAddress); +555 } else if (implType == ImplType.HS_HA) { +556 tserver = getTHsHaServer(serverTransport, protocolFactory, processorToUse, transportFactory, +557 inetSocketAddress); +558 } else { // THREADED_SELECTOR +559 tserver = getTThreadedSelectorServer(serverTransport, protocolFactory, processorToUse, +560 transportFactory, inetSocketAddress); +561 } +562 LOG.info("starting HBase {} server on {}", implType.simpleClassName(), +563 Integer.toString(listenPort)); +564 } else if (implType == ImplType.THREAD_POOL) { +565 this.tserver = getTThreadPoolServer(protocolFactory, processorToUse, transportFactory, +566 inetSocketAddress); +567 } else { +568 throw new AssertionError("Unsupported Thrift server implementation: " + +569 implType.simpleClassName()); +570 } +571 +572 // A sanity check that we instantiated the right type of server. +573 if (tserver.getClass() != implType.serverClass) { +574 throw new AssertionError("Expected to create Thrift server class " + +575 implType.serverClass.getName() + " but got " + +576 tserver.getClass().getName()); +577 } +578 } +579 +580 protected TServer getTNonBlockingServer(TNonblockingServerTransport serverTransport, +581 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, +582 InetSocketAddress inetSocketAddress) { +583 LOG.info("starting HBase Nonblocking Thrift server on " + inetSocketAddress.toString()); +584 TNonblockingServer.Args serverArgs = new TNonblockingServer.Args(serverTransport); +585 serverArgs.processor(processor); +586 serverArgs.transportFactory(transportFactory); +587 serverArgs.protocolFactory(protocolFactory); +588 return new TNonblockingServer(serverArgs); +589 } +590 +591 protected TServer getTHsHaServer(TNonblockingServerTransport serverTransport, +592 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, +593 InetSocketAddress inetSocketAddress) { +594 LOG.info("starting HBase HsHA Thrift server on " + inetSocketAddress.toString()); +595 THsHaServer.Args serverArgs = new THsHaServer.Args(serverTransport); +596 int queueSize = conf.getInt(TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY, +597 TBoundedThreadPoolServer.DEFAULT_MAX_QUEUED_REQUESTS); +598 CallQueue callQueue = new CallQueue(new LinkedBlockingQueue<>(queueSize), metrics); +599 int workerThread = conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, +600 serverArgs.getMaxWorkerThreads()); +601 ExecutorService executorService = createExecutor( +602 callQueue, workerThread, workerThread); +603 serverArgs.executorService(executorService).processor(processor) +604 .transportFactory(transportFactory).protocolFactory(protocolFactory); +605 return new THsHaServer(serverArgs); +606 } +607 +608 protected TServer getTThreadedSelectorServer(TNonblockingServerTransport serverTransport, +609 TProtocolFactory protocolFactory, TProcessor processor, TTransportFactory transportFactory, +610 InetSocketAddress inetSocketAddress) { +611 LOG.info("starting HBase ThreadedSelector Thrift server on " + inetSocketAddress.toString()); +612 TThreadedSelectorServer.Args serverArgs = +613 new HThreadedSelectorServerArgs(serverTransport, conf); +614 int queueSize = conf.getInt(TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY, +615 TBoundedThreadPoolServer.DEFAULT_MAX_QUEUED_REQUESTS); +616 CallQueue callQueue = new CallQueue(new LinkedBlockingQueue<>(queueSize), metrics); +617 int workerThreads = conf.getInt(TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY, +618 serverArgs.getWorkerThreads()); +619 int selectorThreads = conf.getInt(THRIFT_SELECTOR_NUM, serverArgs.getSelectorThreads()); +620 serverArgs.selectorThreads(selectorThreads); +621 ExecutorService executorService = createExecutor( +622 callQueue, workerThreads, workerThreads); +623 serverArgs.executorService(executorService).processor(processor) +624 .transportFactory(transportFactory).protocolFactory(protocolFactory); +625 return new TThreadedSelectorServer(serverArgs); +626 } +627 +628 protected TServer getTThreadPoolServer(TProtocolFactory protocolFactory, TProcessor processor, +629 TTransportFactory transportFactory, InetSocketAddress inetSocketAddress) throws Exception { +630 LOG.info("starting HBase ThreadPool Thrift server on " + inetSocketAddress.toString()); +631 // Thrift's implementation uses '0' as a placeholder for 'use the default.' +632 int backlog = conf.getInt(BACKLOG_CONF_KEY, BACKLOG_CONF_DEAFULT); +633 int readTimeout = conf.getInt(THRIFT_SERVER_SOCKET_READ_TIMEOUT_KEY, +634 THRIFT_SERVER_SOCKET_READ_TIMEOUT_DEFAULT); +635 TServerTransport serverTransport = new TServerSocket( +636 new TServerSocket.ServerSocketTransportArgs(). +637 bindAddr(inetSocketAddress).backlog(backlog). +638 clientTimeout(readTimeout)); +639 +640 TBoundedThreadPoolServer.Args serverArgs = +641 new TBoundedThreadPoolServer.Args(serverTransport, conf); +642 serverArgs.processor(processor).transportFactory(transportFactory) +643 .protocolFactory(protocolFactory); +644 return new TBoundedThreadPoolServer(serverArgs, metrics); +645 } +646 +647 protected TProtocolFactory getProtocolFactory() { +648 TProtocolFactory protocolFactory; +649 +650 if (conf.getBoolean(COMPACT_CONF_KEY, COMPACT_CONF_DEFAULT)) { +651 LOG.debug("Using compact protocol"); +652 protocolFactory = new TCompactProtocol.Factory(); +653 } else { +654 LOG.debug("Using binary protocol"); +655 protocolFactory = new TBinaryProtocol.Factory(); +656 } +657 +658 return protocolFactory; +659 } +660 +661 protected ExecutorService createExecutor(BlockingQueue<Runnable> callQueue, +662 int minWorkers, int maxWorkers) { +663 ThreadFactoryBuilder tfb = new ThreadFactoryBuilder(); +664 tfb.setDaemon(true); +665 tfb.setNameFormat("thrift-worker-%d"); +666 ThreadPoolExecutor threadPool = new THBaseThreadPoolExecutor(minWorkers, maxWorkers, +667 Long.MAX_VALUE, TimeUnit.SECONDS, callQueue, tfb.build(), metrics); +668 threadPool.allowCoreThreadTimeOut(true); +669 return threadPool; +670 } +671 +672 protected InetAddress getBindAddress(Configuration conf) +673 throws UnknownHostException { +674 String bindAddressStr = conf.get(BIND_CONF_KEY, DEFAULT_BIND_ADDR); +675 return InetAddress.getByName(bindAddressStr); +676 } +677 +678 +679 public static void registerFilters(Configuration conf) { +680 String[] filters = conf.getStrings(THRIFT_FILTERS); +681 Splitter splitter = Splitter.on(':'); +682 if(filters != null) { +683 for(String filterClass: filters) { +684 List<String> filterPart = splitter.splitToList(filterClass); +685 if(filterPart.size() != 2) { +686 LOG.warn("Invalid filter specification " + filterClass + " - skipping"); +687 } else { +688 ParseFilter.registerFilter(filterPart.get(0), filterPart.get(1)); +689 } +690 } +691 } +692 } +693 +694 /** +695 * Add options to command lines +696 * @param options options +697 */ +698 protected void addOptions(Options options) { +699 options.addOption("b", BIND_OPTION, true, "Address to bind " + +700 "the Thrift server to. [default: " + DEFAULT_BIND_ADDR + "]"); +701 options.addOption("p", PORT_OPTION, true, "Port to bind to [default: " + +702 DEFAULT_LISTEN_PORT + "]"); +703 options.addOption("f", FRAMED_OPTION, false, "Use framed transport"); +704 options.addOption("c", COMPACT_OPTION, false, "Use the compact protocol"); +705 options.addOption("h", "help", false, "Print help information"); +706 options.addOption("s", SELECTOR_NUM_OPTION, true, "How many selector threads to use."); +707 options.addOption(null, INFOPORT_OPTION, true, "Port for web UI"); +708 +709 options.addOption("m", MIN_WORKERS_OPTION, true, +710 "The minimum number of worker threads for " + +711 ImplType.THREAD_POOL.simpleClassName()); +712 +713 options.addOption("w", MAX_WORKERS_OPTION, true, +714 "The maximum number of worker threads for " + +715 ImplType.THREAD_POOL.simpleClassName()); +716 +717 options.addOption("q", MAX_QUEUE_SIZE_OPTION, true, +718 "The maximum number of queued requests in " + +719 ImplType.THREAD_POOL.simpleClassName()); +720 +721 options.addOption("k", KEEP_ALIVE_SEC_OPTION, true, +722 "The amount of time in secods to keep a thread alive when idle in " + +723 ImplType.THREAD_POOL.simpleClassName()); +724 +725 options.addOption("t", READ_TIMEOUT_OPTION, true, +726 "Amount of time in milliseconds before a server thread will timeout " + +727 "waiting for client to send data on a connected socket. Currently, " + +728 "only applies to TBoundedThreadPoolServer"); +729 +730 options.addOptionGroup(ImplType.createOptionGroup()); +731 } +732 +733 protected void parseCommandLine(CommandLine cmd, Options options) throws ExitCodeException { +734 // Get port to bind to +735 try { +736 if (cmd.hasOption(PORT_OPTION)) { +737 int listenPort = Integer.parseInt(cmd.getOptionValue(PORT_OPTION)); +738 conf.setInt(PORT_CONF_KEY, listenPort); +739 } +740 } catch (NumberFormatException e) { +741 LOG.error("Could not parse the value provided for the port option", e); +742 printUsageAndExit(options, -1); +743 } +744 // check for user-defined info server port setting, if so override the conf +745 try { +746 if (cmd.hasOption(INFOPORT_OPTION)) { +747 String val = cmd.getOptionValue(INFOPORT_OPTION); +748 conf.setInt(THRIFT_INFO_SERVER_PORT, Integer.parseInt(val)); +749 LOG.debug("Web UI port set to " + val); +750 } +751 } catch (NumberFormatException e) { +752 LOG.error("Could not parse the value provided for the " + INFOPORT_OPTION + +753 " option", e); +754 printUsageAndExit(options, -1); +755 } +756 // Make optional changes to the configuration based on command-line options +757 optionToConf(cmd, MIN_WORKERS_OPTION, +758 conf, TBoundedThreadPoolServer.MIN_WORKER_THREADS_CONF_KEY); +759 optionToConf(cmd, MAX_WORKERS_OPTION, +760 conf, TBoundedThreadPoolServer.MAX_WORKER_THREADS_CONF_KEY); +761 optionToConf(cmd, MAX_QUEUE_SIZE_OPTION, +762 conf, TBoundedThreadPoolServer.MAX_QUEUED_REQUESTS_CONF_KEY); +763 optionToConf(cmd, KEEP_ALIVE_SEC_OPTION, +764 conf, TBoundedThreadPoolServer.THREAD_KEEP_ALIVE_TIME_SEC_CONF_KEY); +765 optionToConf(cmd, READ_TIMEOUT_OPTION, conf, THRIFT_SERVER_SOCKET_READ_TIMEOUT_KEY); +766 optionToConf(cmd, SELECTOR_NUM_OPTION, conf, THRIFT_SELECTOR_NUM); +767 +768 // Set general thrift server options +769 boolean compact = cmd.hasOption(COMPACT_OPTION) || +770 conf.getBoolean(COMPACT_CONF_KEY, false); +771 conf.setBoolean(COMPACT_CONF_KEY, compact); +772 boolean framed = cmd.hasOption(FRAMED_OPTION) || +773 conf.getBoolean(FRAMED_CONF_KEY, false); +774 conf.setBoolean(FRAMED_CONF_KEY, framed); 775 -776 -777 ImplType.setServerImpl(cmd, conf); -778 } -779 -780 /** -781 * Parse the command line options to set parameters the conf. -782 */ -783 protected void processOptions(final String[] args) throws Exception { -784 if (args == null || args.length == 0) { -785 return; -786 } -787 Options options = new Options(); -788 addOptions(options); -789 -790 CommandLineParser parser = new DefaultParser(); -791 CommandLine cmd = parser.parse(options, args); -792 -793 if (cmd.hasOption("help")) { -794 printUsageAndExit(options, 1); -795 } -796 parseCommandLine(cmd, options); -797 } -798 -799 public void stop() { -800 if (this.infoServer != null) { -801 LOG.info("Stopping infoServer"); -802 try { -803 this.infoServer.stop(); -804 } catch (Exception ex) { -805 LOG.error("Failed to stop infoServer", ex); -806 } -807 } -808 if (pauseMonitor != null) { -809 pauseMonitor.stop(); -810 } -811 if (tserver != null) { -812 tserver.stop(); -813 tserver = null; -814 } -815 if (httpServer != null) { -816 try { -817 httpServer.stop(); -818 httpServer = null; -819 } catch (Exception e) { -820 LOG.error("Problem encountered in shutting down HTTP server", e); -821 } -822 httpServer = null; -823 } -824 } -825 -826 protected static void optionToConf(CommandLine cmd, String option, -827 Configuration conf, String destConfKey) { -828 if (cmd.hasOption(option)) { -829 String value = cmd.getOptionValue(option); -830 LOG.info("Set configuration key:" + destConfKey + " value:" + value); -831 conf.set(destConfKey, value); -832 } -833 } -834 -835 /** -836 * Run without any command line arguments -837 * @return exit code -838 * @throws Exception exception -839 */ -840 public int run() throws Exception { -841 return run(null); -842 } -843 -844 @Override -845 public int run(String[] strings) throws Exception { -846 processOptions(strings); -847 setupParamters(); -848 startInfoServer(); -849 if (httpEnabled) { -850 setupHTTPServer(); -851 httpServer.start(); -852 httpServer.join(); -853 } else { -854 setupServer(); -855 tserver.serve(); -856 } -857 return 0; -858 } -859 -860 public static void main(String [] args) throws Exception { -861 LOG.info("***** STARTING service '" + ThriftServer.class.getSimpleName() + "' *****"); -862 VersionInfo.logVersion(); -863 final Configuration conf = HBaseConfiguration.create(); -864 // for now, only time we return is on an argument error. -865 final int status = ToolRunner.run(conf, new ThriftServer(conf), args); -866 LOG.info("***** STOPPING service '" + ThriftServer.class.getSimpleName() + "' *****"); -867 System.exit(status); -868 } -869} +776 optionToConf(cmd, BIND_OPTION, conf, BIND_CONF_KEY); +777 +778 +779 ImplType.setServerImpl(cmd, conf); +780 } +781 +782 /** +783 * Parse the command line options to set parameters the conf. +784 */ +785 protected void processOptions(final String[] args) throws Exception { +786 if (args == null || args.length == 0) { +787 return; +788 } +789 Options options = new Options(); +790 addOptions(options); +791 +792 CommandLineParser parser = new DefaultParser(); +793 CommandLine cmd = parser.parse(options, args); +794 +795 if (cmd.hasOption("help")) { +796 printUsageAndExit(options, 1); +797 } +798 parseCommandLine(cmd, options); +799 } +800 +801 public void stop() { +802 if (this.infoServer != null) { +803 LOG.info("Stopping infoServer"); +804 try { +805 this.infoServer.stop(); +806 } catch (Exception ex) { +807 LOG.error("Failed to stop infoServer", ex); +808 } +809 } +810 if (pauseMonitor != null) { +811 pauseMonitor.stop(); +812 } +813 if (tserver != null) { +814 tserver.stop(); +815 tserver = null; +816 } +817 if (httpServer != null) { +818 try { +819 httpServer.stop(); +820 httpServer = null; +821 } catch (Exception e) { +822 LOG.error("Problem encountered in shutting down HTTP server", e); +823 } +824 httpServer = null; +825 } +826 } +827 +828 protected static void optionToConf(CommandLine cmd, String option, +829 Configuration conf, String destConfKey) { +830 if (cmd.hasOption(option)) { +831 String value = cmd.getOptionValue(option); +832 LOG.info("Set configuration key:" + destConfKey + " value:" + value); +833 conf.set(destConfKey, value); +834 } +835 } +836 +837 /** +838 * Run without any command line arguments +839 * @return exit code +840 * @throws Exception exception +841 */ +842 public int run() throws Exception { +843 return run(null); +844 } +845 +846 @Override +847 public int run(String[] strings) throws Exception { +848 processOptions(strings); +849 setupParamters(); +850 if (httpEnabled) { +851 setupHTTPServer(); +852 } else { +853 setupServer(); +854 } +855 serviceUGI.doAs(new PrivilegedAction<Object>() { +856 @Override +857 public Object run() { +858 try { +859 startInfoServer(); +860 if (httpEnabled) { +861 httpServer.start(); +862 httpServer.join(); +863 } else { +864 tserver.serve(); +865 } +866 } catch (Exception e) { +867 LOG.error(HBaseMarkers.FATAL, "Cannot run ThriftServer", e); +868 +869 System.exit(-1); +870 } +871 return null; +872 } +873 }); +874 return 0; +875 } +876 +877 public static void main(String [] args) throws Exception { +878 LOG.info("***** STARTING service '" + ThriftServer.class.getSimpleName() + "' *****"); +879 VersionInfo.logVersion(); +880 final Configuration conf = HBaseConfiguration.create(); +881 // for now, only time we return is on an argument error. +882 final int status = ToolRunner.run(conf, new ThriftServer(conf), args); +883 LOG.info("***** STOPPING service '" + ThriftServer.class.getSimpleName() + "' *****"); +884 System.exit(status); +885 } +886} diff --git a/downloads.html b/downloads.html index 640f3ae..9afb6ef 100644 --- a/downloads.html +++ b/downloads.html @@ -466,7 +466,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/export_control.html b/export_control.html index 1859a10..00974b0 100644 --- a/export_control.html +++ b/export_control.html @@ -197,7 +197,7 @@ for more details.

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/index.html b/index.html index cbd6c2f..ea38165 100644 --- a/index.html +++ b/index.html @@ -275,7 +275,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/issue-tracking.html b/issue-tracking.html index 1327fd1..dfa1ed8 100644 --- a/issue-tracking.html +++ b/issue-tracking.html @@ -169,7 +169,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/mail-lists.html b/mail-lists.html index fca5495..1edaf87 100644 --- a/mail-lists.html +++ b/mail-lists.html @@ -215,7 +215,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/metrics.html b/metrics.html index 05d7a87..f22bf26 100644 --- a/metrics.html +++ b/metrics.html @@ -325,7 +325,7 @@ export HBASE_REGIONSERVER_OPTS="$HBASE_JMX_OPTS -Dcom.sun.management.jmxrem

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/old_news.html b/old_news.html index 3fa9f2a..72f757b 100644 --- a/old_news.html +++ b/old_news.html @@ -316,7 +316,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/plugin-management.html b/plugin-management.html index 28ce0eb..391391c 100644 --- a/plugin-management.html +++ b/plugin-management.html @@ -321,7 +321,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/plugins.html b/plugins.html index 91fb595..db493c8 100644 --- a/plugins.html +++ b/plugins.html @@ -248,7 +248,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/poweredbyhbase.html b/poweredbyhbase.html index b7176c7..2e1dd7f 100644 --- a/poweredbyhbase.html +++ b/poweredbyhbase.html @@ -650,7 +650,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/project-info.html b/project-info.html index 9ba75fc..2ff9356 100644 --- a/project-info.html +++ b/project-info.html @@ -210,7 +210,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/project-reports.html b/project-reports.html index bbe5c89..687af19 100644 --- a/project-reports.html +++ b/project-reports.html @@ -186,7 +186,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/project-summary.html b/project-summary.html index 70c71ba..aa57015 100644 --- a/project-summary.html +++ b/project-summary.html @@ -212,7 +212,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/pseudo-distributed.html b/pseudo-distributed.html index c8d4564..3d8cd3c 100644 --- a/pseudo-distributed.html +++ b/pseudo-distributed.html @@ -174,7 +174,7 @@ Running Apache HBase (TM) in pseudo-distributed mode

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/replication.html b/replication.html index e22e931..76afd62 100644 --- a/replication.html +++ b/replication.html @@ -169,7 +169,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/resources.html b/resources.html index 0b4bbb3..63e722c 100644 --- a/resources.html +++ b/resources.html @@ -197,7 +197,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/source-repository.html b/source-repository.html index d9da826..ed62b80 100644 --- a/source-repository.html +++ b/source-repository.html @@ -180,7 +180,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/sponsors.html b/sponsors.html index cdec41c..3e5cca5 100644 --- a/sponsors.html +++ b/sponsors.html @@ -199,7 +199,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/supportingprojects.html b/supportingprojects.html index 9635a88..8bb4682 100644 --- a/supportingprojects.html +++ b/supportingprojects.html @@ -390,7 +390,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven diff --git a/team-list.html b/team-list.html index 859dc44..b90bda1 100644 --- a/team-list.html +++ b/team-list.html @@ -731,7 +731,7 @@

      Copyright ©2007–2021 The Apache Software Foundation. -All rights reserved.

    • Last Published: 2021-06-03
    • +All rights reserved.
    • Last Published: 2021-06-04
    • Built by Maven