This is an automated email from the ASF dual-hosted git repository.

apucher pushed a commit to branch pinot-broker-https-pr
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git

commit a36446a53316b1b025fed8f317b268fa1b20f631
Author: Alexander Pucher <[email protected]>
AuthorDate: Wed Jan 6 11:31:51 2021 -0800

    client-broker TLS support
---
 .../broker/broker/BrokerAdminApiApplication.java   | 47 +++++++++++++++++++---
 .../broker/broker/helix/HelixBrokerStarter.java    |  2 +-
 .../apache/pinot/common/utils/CommonConstants.java |  9 +++++
 .../apache/pinot/controller/ControllerConf.java    | 13 ++++++
 .../api/resources/PinotQueryResource.java          | 18 ++++++---
 .../tools/admin/command/PostQueryCommand.java      | 15 +++++--
 6 files changed, 89 insertions(+), 15 deletions(-)

diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/BrokerAdminApiApplication.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/BrokerAdminApiApplication.java
index ba262fd..03d89e0 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/BrokerAdminApiApplication.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/BrokerAdminApiApplication.java
@@ -27,14 +27,20 @@ import 
org.apache.pinot.broker.requesthandler.BrokerRequestHandler;
 import org.apache.pinot.broker.routing.RoutingManager;
 import org.apache.pinot.common.metrics.BrokerMetrics;
 import org.apache.pinot.common.utils.CommonConstants;
+import org.apache.pinot.spi.env.PinotConfiguration;
 import org.glassfish.grizzly.http.server.CLStaticHttpHandler;
 import org.glassfish.grizzly.http.server.HttpHandler;
 import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.grizzly.ssl.SSLContextConfigurator;
+import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
 import org.glassfish.jersey.jackson.JacksonFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 
+import static org.apache.pinot.common.utils.CommonConstants.Broker.*;
+import static org.apache.pinot.common.utils.CommonConstants.HTTPS_PROTOCOL;
+
 
 public class BrokerAdminApiApplication extends ResourceConfig {
   private static final String RESOURCE_PACKAGE = 
"org.apache.pinot.broker.api.resources";
@@ -58,20 +64,51 @@ public class BrokerAdminApiApplication extends 
ResourceConfig {
     registerClasses(io.swagger.jaxrs.listing.SwaggerSerializers.class);
   }
 
-  public void start(int httpPort) {
-    Preconditions.checkArgument(httpPort > 0);
-    _baseUri = URI.create("http://0.0.0.0:"; + httpPort + "/");
-    _httpServer = GrizzlyHttpServerFactory.createHttpServer(_baseUri, this);
+  public void start(PinotConfiguration brokerConf) {
+    int brokerQueryPort = 
brokerConf.getProperty(CommonConstants.Helix.KEY_OF_BROKER_QUERY_PORT,
+        CommonConstants.Helix.DEFAULT_BROKER_QUERY_PORT);
+    String brokerQueryProtocol = 
brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_PROTOCOL,
+        DEFAULT_BROKER_CLIENT_PROTOCOL);
+
+    Preconditions.checkArgument(brokerQueryPort > 0);
+    _baseUri = URI.create(String.format("%s://0.0.0.0:%d/", 
brokerQueryProtocol, brokerQueryPort));
+
+    _httpServer = buildHttpsServer(brokerConf);
     setupSwagger();
   }
 
+  private HttpServer buildHttpsServer(PinotConfiguration brokerConf) {
+    boolean isSecure = 
HTTPS_PROTOCOL.equals(brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_PROTOCOL));
+
+    if (isSecure) {
+      return GrizzlyHttpServerFactory.createHttpServer(_baseUri, this, true, 
buildSSLConfig(brokerConf));
+    }
+
+    return GrizzlyHttpServerFactory.createHttpServer(_baseUri, this);
+  }
+
+  private SSLEngineConfigurator buildSSLConfig(PinotConfiguration brokerConf) {
+    SSLContextConfigurator sslContextConfigurator = new 
SSLContextConfigurator();
+
+    
sslContextConfigurator.setKeyStoreFile(brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_TLS_KEYSTORE_PATH));
+    
sslContextConfigurator.setKeyStorePass(brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_TLS_KEYSTORE_PASSWORD));
+    
sslContextConfigurator.setTrustStoreFile(brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_TLS_TRUSTSTORE_PATH));
+    
sslContextConfigurator.setTrustStorePass(brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_TLS_TRUSTSTORE_PASSWORD));
+
+    boolean requiresClientAuth = 
brokerConf.getProperty(CONFIG_OF_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH,
+        DEFAULT_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH);
+
+    return new 
SSLEngineConfigurator(sslContextConfigurator).setClientMode(false)
+        .setWantClientAuth(requiresClientAuth).setEnabledProtocols(new 
String[] { "TLSv1.2" });
+  }
+
   private void setupSwagger() {
     BeanConfig beanConfig = new BeanConfig();
     beanConfig.setTitle("Pinot Broker API");
     beanConfig.setDescription("APIs for accessing Pinot broker information");
     beanConfig.setContact("https://github.com/apache/incubator-pinot";);
     beanConfig.setVersion("1.0");
-    beanConfig.setSchemes(new String[]{CommonConstants.HTTP_PROTOCOL, 
CommonConstants.HTTPS_PROTOCOL});
+    beanConfig.setSchemes(new String[] { _baseUri.getScheme() });
     beanConfig.setBasePath(_baseUri.getPath());
     beanConfig.setResourcePackage(RESOURCE_PACKAGE);
     beanConfig.setScan(true);
diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/HelixBrokerStarter.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/HelixBrokerStarter.java
index 730076e..746bf7a 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/HelixBrokerStarter.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/HelixBrokerStarter.java
@@ -245,7 +245,7 @@ public class HelixBrokerStarter implements ServiceStartable 
{
     int brokerQueryPort = 
_brokerConf.getProperty(Helix.KEY_OF_BROKER_QUERY_PORT, 
Helix.DEFAULT_BROKER_QUERY_PORT);
     LOGGER.info("Starting broker admin application on port: {}", 
brokerQueryPort);
     _brokerAdminApplication = new BrokerAdminApiApplication(_routingManager, 
_brokerRequestHandler, _brokerMetrics);
-    _brokerAdminApplication.start(brokerQueryPort);
+    _brokerAdminApplication.start(_brokerConf);
 
     LOGGER.info("Initializing cluster change mediator");
     for (ClusterChangeHandler externalViewChangeHandler : 
_externalViewChangeHandlers) {
diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/CommonConstants.java 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/CommonConstants.java
index 9773e7e..2401af4 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/CommonConstants.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/CommonConstants.java
@@ -177,6 +177,15 @@ public class CommonConstants {
     public static final String CONFIG_OF_BROKER_GROUPBY_TRIM_THRESHOLD = 
"pinot.broker.groupby.trim.threshold";
     public static final int DEFAULT_BROKER_GROUPBY_TRIM_THRESHOLD = 1_000_000;
 
+    public static final String CONFIG_OF_BROKER_CLIENT_PROTOCOL = 
"pinot.broker.client.protocol";
+    public static final String DEFAULT_BROKER_CLIENT_PROTOCOL = "http";
+    public static final String CONFIG_OF_BROKER_CLIENT_TLS_KEYSTORE_PATH = 
"pinot.broker.client.tls.keystore.path";
+    public static final String CONFIG_OF_BROKER_CLIENT_TLS_KEYSTORE_PASSWORD = 
"pinot.broker.client.tls.keystore.password";
+    public static final String CONFIG_OF_BROKER_CLIENT_TLS_TRUSTSTORE_PATH = 
"pinot.broker.client.tls.truststore.path";
+    public static final String CONFIG_OF_BROKER_CLIENT_TLS_TRUSTSTORE_PASSWORD 
= "pinot.broker.client.tls.truststore.password";
+    public static final String 
CONFIG_OF_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH = 
"pinot.broker.client.tls.requires_client_auth";
+    public static final boolean DEFAULT_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH 
= false;
+
     public static class Request {
       public static final String PQL = "pql";
       public static final String SQL = "sql";
diff --git 
a/pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java
 
b/pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java
index 3bd2cf2..e080220 100644
--- 
a/pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java
+++ 
b/pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java
@@ -40,6 +40,7 @@ public class ControllerConf extends PinotConfiguration {
   public static final String CONTROLLER_VIP_HOST = "controller.vip.host";
   public static final String CONTROLLER_VIP_PORT = "controller.vip.port";
   public static final String CONTROLLER_VIP_PROTOCOL = 
"controller.vip.protocol";
+  public static final String CONTROLLER_BROKER_PROTOCOL = 
"controller.broker.protocol";
   public static final String CONTROLLER_HOST = "controller.host";
   public static final String CONTROLLER_PORT = "controller.port";
   public static final String CONTROLLER_ACCESS_PROTOCOLS = 
"controller.access.protocols";
@@ -234,6 +235,10 @@ public class ControllerConf extends PinotConfiguration {
     setProperty(CONTROLLER_VIP_PROTOCOL, vipProtocol);
   }
 
+  public void setControllerBrokerProtocol(String protocol) {
+    setProperty(CONTROLLER_BROKER_PROTOCOL, protocol);
+  }
+
   public void setControllerPort(String port) {
     setProperty(CONTROLLER_PORT, port);
   }
@@ -356,6 +361,14 @@ public class ControllerConf extends PinotConfiguration {
         .orElse(CommonConstants.HTTP_PROTOCOL);
   }
 
+  public String getControllerBrokerProtocol() {
+    return Optional.ofNullable(getProperty(CONTROLLER_BROKER_PROTOCOL))
+
+        .filter(protocol -> CommonConstants.HTTPS_PROTOCOL.equals(protocol))
+
+        .orElse(CommonConstants.HTTP_PROTOCOL);
+  }
+
   public int getRetentionControllerFrequencyInSeconds() {
     return 
getProperty(ControllerPeriodicTasksConf.RETENTION_MANAGER_FREQUENCY_IN_SECONDS,
         
ControllerPeriodicTasksConf.DEFAULT_RETENTION_CONTROLLER_FREQUENCY_IN_SECONDS);
diff --git 
a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotQueryResource.java
 
b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotQueryResource.java
index 004f863..d0b2781 100644
--- 
a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotQueryResource.java
+++ 
b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotQueryResource.java
@@ -46,6 +46,7 @@ import org.apache.pinot.common.Utils;
 import org.apache.pinot.common.exception.QueryException;
 import org.apache.pinot.common.request.BrokerRequest;
 import org.apache.pinot.common.utils.CommonConstants;
+import org.apache.pinot.controller.ControllerConf;
 import org.apache.pinot.controller.api.access.AccessControl;
 import org.apache.pinot.controller.api.access.AccessControlFactory;
 import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
@@ -63,12 +64,16 @@ public class PinotQueryResource {
   private static final Pql2Compiler PQL_QUERY_COMPILER = new Pql2Compiler();
   private static final CalciteSqlCompiler SQL_QUERY_COMPILER = new 
CalciteSqlCompiler();
   private static final Random RANDOM = new Random();
+
   @Inject
   PinotHelixResourceManager _pinotHelixResourceManager;
 
   @Inject
   AccessControlFactory _accessControlFactory;
 
+  @Inject
+  ControllerConf _controllerConf;
+
   @Deprecated
   @POST
   @Path("pql")
@@ -196,10 +201,11 @@ public class PinotQueryResource {
       LOGGER.error("Instance {} not found", instanceId);
       return QueryException.INTERNAL_ERROR.toString();
     }
+
+    String protocol = _controllerConf.getControllerBrokerProtocol();
     String hostNameWithPrefix = instanceConfig.getHostName();
-    String url =
-        
getQueryURL(hostNameWithPrefix.substring(hostNameWithPrefix.indexOf("_") + 1), 
instanceConfig.getPort(),
-            querySyntax);
+    String url = getQueryURL(protocol, 
hostNameWithPrefix.substring(hostNameWithPrefix.indexOf("_") + 1),
+        instanceConfig.getPort(), querySyntax);
     ObjectNode requestJson = getRequestJson(query, traceEnabled, queryOptions, 
querySyntax);
     return sendRequestRaw(url, query, requestJson);
   }
@@ -226,12 +232,12 @@ public class PinotQueryResource {
     return requestJson;
   }
 
-  private String getQueryURL(String hostName, String port, String querySyntax) 
{
+  private String getQueryURL(String protocol, String hostName, String port, 
String querySyntax) {
     switch (querySyntax) {
       case CommonConstants.Broker.Request.SQL:
-        return String.format("http://%s:%s/query/sql";, hostName, port);
+        return String.format("%s://%s:%s/query/sql", protocol, hostName, port);
       case CommonConstants.Broker.Request.PQL:
-        return String.format("http://%s:%s/query";, hostName, port);
+        return String.format("%s://%s:%s/query", protocol, hostName, port);
       default:
         throw new UnsupportedOperationException("Unsupported query syntax - " 
+ querySyntax);
     }
diff --git 
a/pinot-tools/src/main/java/org/apache/pinot/tools/admin/command/PostQueryCommand.java
 
b/pinot-tools/src/main/java/org/apache/pinot/tools/admin/command/PostQueryCommand.java
index e08aa3e..511d7e7 100644
--- 
a/pinot-tools/src/main/java/org/apache/pinot/tools/admin/command/PostQueryCommand.java
+++ 
b/pinot-tools/src/main/java/org/apache/pinot/tools/admin/command/PostQueryCommand.java
@@ -32,12 +32,15 @@ import org.slf4j.LoggerFactory;
 public class PostQueryCommand extends AbstractBaseAdminCommand implements 
Command {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(PostQueryCommand.class.getName());
 
-  @Option(name = "-brokerHost", required = false, metaVar = "<String>", usage 
= "host name for controller.")
+  @Option(name = "-brokerHost", required = false, metaVar = "<String>", usage 
= "host name for broker.")
   private String _brokerHost;
 
   @Option(name = "-brokerPort", required = false, metaVar = "<int>", usage = 
"http port for broker.")
   private String _brokerPort = 
Integer.toString(CommonConstants.Helix.DEFAULT_BROKER_QUERY_PORT);
 
+  @Option(name = "-brokerProtocol", required = false, metaVar = "<String>", 
usage = "protocol for broker.")
+  private String _brokerProtocol = "http";
+
   @Option(name = "-queryType", required = false, metaVar = "<string>", usage = 
"Query use sql or pql.")
   private String _queryType = Request.PQL;
 
@@ -59,7 +62,8 @@ public class PostQueryCommand extends 
AbstractBaseAdminCommand implements Comman
 
   @Override
   public String toString() {
-    return ("PostQuery -brokerHost " + _brokerHost + " -brokerPort " + 
_brokerPort + " -queryType " + _queryType + " -query " + _query);
+    return ("PostQuery -brokerProtocol " + _brokerProtocol + " -brokerHost " + 
_brokerHost + " -brokerPort " +
+        _brokerPort + " -queryType " + _queryType + " -query " + _query);
   }
 
   @Override
@@ -82,6 +86,11 @@ public class PostQueryCommand extends 
AbstractBaseAdminCommand implements Comman
     return this;
   }
 
+  public PostQueryCommand setBrokerProtocol(String protocol) {
+    _brokerProtocol = protocol;
+    return this;
+  }
+
   public PostQueryCommand setQueryType(String queryType) {
     _queryType = queryType;
     return this;
@@ -100,7 +109,7 @@ public class PostQueryCommand extends 
AbstractBaseAdminCommand implements Comman
     LOGGER.info("Executing command: " + toString());
 
     String request;
-    String urlString = "http://"; + _brokerHost + ":" + _brokerPort + "/query";
+    String urlString = _brokerProtocol + "://" + _brokerHost + ":" + 
_brokerPort + "/query";
     if (_queryType.toLowerCase().equals(Request.SQL)) {
       urlString += "/sql";
       request = JsonUtils.objectToString(Collections.singletonMap(Request.SQL, 
_query));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to