You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ap...@apache.org on 2021/01/05 22:01:43 UTC

[incubator-pinot] 06/07: client-broker TLS

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

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

commit ba6eac20ea9350ee1cd829270695d10f16315cc2
Author: Alexander Pucher <al...@alexpucher.com>
AuthorDate: Tue Jan 5 13:54:52 2021 -0800

    client-broker TLS
---
 .../broker/broker/BrokerAdminApiApplication.java   | 51 ++++++++++++++++++++--
 .../broker/broker/helix/HelixBrokerStarter.java    |  2 +-
 .../api/resources/PinotQueryResource.java          | 14 +++---
 .../tools/admin/command/PostQueryCommand.java      | 15 +++++--
 4 files changed, 68 insertions(+), 14 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..f6c25ac 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,9 +27,12 @@ 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;
@@ -39,6 +42,17 @@ import org.glassfish.jersey.server.ResourceConfig;
 public class BrokerAdminApiApplication extends ResourceConfig {
   private static final String RESOURCE_PACKAGE = "org.apache.pinot.broker.api.resources";
 
+  // TODO find a permanent home for broker configuration keys
+  private static final String PINOT_BROKER_CLIENT_PROTOCOL = "pinot.broker.client.protocol";
+  private static final String PINOT_BROKER_CLIENT_TLS_KEYSTORE_PATH = "pinot.broker.client.tls.keystore.path";
+  private static final String PINOT_BROKER_CLIENT_TLS_KEYSTORE_PASSWORD = "pinot.broker.client.tls.keystore.password";
+  private static final String PINOT_BROKER_CLIENT_TLS_TRUSTSTORE_PATH = "pinot.broker.client.tls.truststore.path";
+  private static final String PINOT_BROKER_CLIENT_TLS_TRUSTSTORE_PASSWORD = "pinot.broker.client.tls.truststore.password";
+  private static final String PINOT_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH = "pinot.broker.client.tls.requires_client_auth";
+
+  private static final String PROTOCOL_HTTPS = "https";
+  private static final String PROTOCOL_HTTP = "http";
+
   private URI _baseUri;
   private HttpServer _httpServer;
 
@@ -58,13 +72,42 @@ 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);
+
+    Preconditions.checkArgument(brokerQueryPort > 0);
+    _baseUri = URI.create(String.format("%s://0.0.0.0:%d/",
+        brokerConf.getProperty(PINOT_BROKER_CLIENT_PROTOCOL, PROTOCOL_HTTP), brokerQueryPort));
+
+    _httpServer = buildHttpsServer(brokerConf);
     setupSwagger();
   }
 
+  private HttpServer buildHttpsServer(PinotConfiguration brokerConf) {
+    boolean isSecure = PROTOCOL_HTTPS.equals(brokerConf.getProperty(PINOT_BROKER_CLIENT_PROTOCOL, PROTOCOL_HTTP));
+
+    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(PINOT_BROKER_CLIENT_TLS_KEYSTORE_PATH));
+    sslContextConfigurator.setKeyStorePass(brokerConf.getProperty(PINOT_BROKER_CLIENT_TLS_KEYSTORE_PASSWORD));
+    sslContextConfigurator.setTrustStoreFile(brokerConf.getProperty(PINOT_BROKER_CLIENT_TLS_TRUSTSTORE_PATH));
+    sslContextConfigurator.setTrustStorePass(brokerConf.getProperty(PINOT_BROKER_CLIENT_TLS_TRUSTSTORE_PASSWORD));
+
+    boolean requiresClientAuth = brokerConf.getProperty(PINOT_BROKER_CLIENT_TLS_REQUIRES_CLIENT_AUTH, false);
+
+    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");
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-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..fa5d258 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
@@ -196,10 +196,12 @@ public class PinotQueryResource {
       LOGGER.error("Instance {} not found", instanceId);
       return QueryException.INTERNAL_ERROR.toString();
     }
+
+    // TODO extract protocol from Helix
+    String protocol = "http";
     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 +228,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: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org