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]
