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

anmolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new afe8f08b6d ZOOKEEPER-5029: Port unification for 
PrometheusMetricsProvider
afe8f08b6d is described below

commit afe8f08b6d369a4670a794443d5efcbfbb79ddc9
Author: Dávid Paksy <[email protected]>
AuthorDate: Tue Apr 28 17:31:56 2026 +0200

    ZOOKEEPER-5029: Port unification for PrometheusMetricsProvider
    
    Reviewers: meszibalu, anmolnar
    Author: PDavid
    Closes #2362 from 
PDavid/ZOOKEEPER-5029-PrometheusMetricsProvider-portUnification
---
 .../prometheus/PrometheusMetricsProvider.java      | 72 ++++++++++++++++++----
 .../PrometheusHttpsMetricsProviderTest.java        |  8 +--
 .../PrometheusMetricsProviderConfigTest.java       | 16 +++++
 3 files changed, 79 insertions(+), 17 deletions(-)

diff --git 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java
 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java
index 8ae6178e0f..dc7828ddb3 100644
--- 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java
+++ 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java
@@ -41,6 +41,11 @@
 import org.apache.zookeeper.metrics.MetricsProviderLifeCycleException;
 import org.apache.zookeeper.metrics.Summary;
 import org.apache.zookeeper.metrics.SummarySet;
+import org.apache.zookeeper.server.admin.UnifiedConnectionFactory;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
 import org.eclipse.jetty.servlet.ServletContextHandler;
@@ -84,6 +89,7 @@ public class PrometheusMetricsProvider implements 
MetricsProvider {
     private boolean wantClientAuth = true; // Secure default
     private String enabledProtocols;
     private String cipherSuites;
+    private int httpVersion;
 
     // Constants for configuration
     public static final String HTTP_HOST = "httpHost";
@@ -101,7 +107,14 @@ public class PrometheusMetricsProvider implements 
MetricsProvider {
     public static final String SSL_WANT_CLIENT_AUTH = "ssl.want.client.auth";
     public static final String SSL_ENABLED_PROTOCOLS = "ssl.enabledProtocols";
     public static final String SSL_ENABLED_CIPHERS = "ssl.ciphersuites";
+    public static final String HTTP_VERSION = "httpVersion";
     public static final int SCAN_INTERVAL = 60 * 10; // 10 minutes
+    public static final int DEFAULT_HTTP_VERSION = 11;  // based on 
HttpVersion.java in jetty
+    /**
+     * The time, in seconds, that the browser should remember that a host is 
only to be accessed using HTTPS.
+     * Seconds in a day.
+     */
+    public static final int DEFAULT_STS_MAX_AGE = 1 * 24 * 60 * 60;
 
     /**
      * Custom servlet to disable the TRACE method for security reasons.
@@ -139,6 +152,7 @@ public void configure(Properties configuration) throws 
MetricsProviderLifeCycleE
             this.wantClientAuth = 
Boolean.parseBoolean(configuration.getProperty(SSL_WANT_CLIENT_AUTH, "true"));
             this.enabledProtocols = 
configuration.getProperty(SSL_ENABLED_PROTOCOLS);
             this.cipherSuites = configuration.getProperty(SSL_ENABLED_CIPHERS);
+            this.httpVersion = Integer.getInteger(HTTP_VERSION, 
DEFAULT_HTTP_VERSION);
         }
 
         // Validate that at least one port is configured.
@@ -171,23 +185,49 @@ public void start() throws 
MetricsProviderLifeCycleException {
             int acceptors = 1;
             int selectors = 1;
 
-            // Configure HTTP connector if enabled
-            if (this.httpPort != -1) {
-                ServerConnector httpConnector = new ServerConnector(server, 
acceptors, selectors);
-                httpConnector.setPort(this.httpPort);
-                httpConnector.setHost(this.host);
-                server.addConnector(httpConnector);
-            }
+            ServerConnector connector = null;
+
+            if (this.httpPort != -1 && this.httpsPort != -1 && this.httpPort 
== this.httpsPort) {
+                // Set Strict-Transport-Security HTTP response header.
+                SecureRequestCustomizer customizer = new 
SecureRequestCustomizer();
+                customizer.setStsMaxAge(DEFAULT_STS_MAX_AGE);
+                // Strict-Transport-Security HTTP header should apply to all 
subdomains of the host's domain as well.
+                customizer.setStsIncludeSubDomains(true);
+
+                HttpConfiguration config = new HttpConfiguration();
+                config.setSecureScheme("https");
+                config.addCustomizer(customizer);
 
-            // Configure HTTPS connector if enabled
-            if (this.httpsPort != -1) {
                 SslContextFactory.Server sslContextFactory = 
createSslContextFactory();
-                KeyStoreScanner keystoreScanner = new 
KeyStoreScanner(sslContextFactory);
-                keystoreScanner.setScanInterval(SCAN_INTERVAL);
-                server.addBean(keystoreScanner);
-                server.addConnector(createSslConnector(server, acceptors, 
selectors, sslContextFactory));
+                setKeyStoreScanner(sslContextFactory);
+
+                String nextProtocol = 
HttpVersion.fromVersion(httpVersion).asString();
+                connector = new ServerConnector(server,
+                        new UnifiedConnectionFactory(sslContextFactory, 
nextProtocol),
+                        new HttpConnectionFactory(config));
+                connector.setPort(this.httpPort);
+                connector.setHost(this.host);
+                LOG.info("Created unified ServerConnector for host: {}, 
httpPort: {}", host, httpPort);
+            } else {
+                // Configure HTTP connector if enabled
+                if (this.httpPort != -1) {
+                    connector = new ServerConnector(server, acceptors, 
selectors);
+                    connector.setPort(this.httpPort);
+                    connector.setHost(this.host);
+                    LOG.info("Created HTTP ServerConnector for host: {}, 
httpPort: {}", host, httpPort);
+                }
+
+                // Configure HTTPS connector if enabled
+                if (this.httpsPort != -1) {
+                    SslContextFactory.Server sslContextFactory = 
createSslContextFactory();
+                    setKeyStoreScanner(sslContextFactory);
+                    connector = createSslConnector(server, acceptors, 
selectors, sslContextFactory);
+                    LOG.info("Created HTTPS ServerConnector for host: {}, 
httpsPort: {}", host, httpsPort);
+                }
             }
 
+            server.addConnector(connector);
+
             // Set up the servlet context handler
             ServletContextHandler context = new ServletContextHandler();
             context.setContextPath("/");
@@ -207,6 +247,12 @@ public void start() throws 
MetricsProviderLifeCycleException {
         }
     }
 
+    private void setKeyStoreScanner(SslContextFactory.Server 
sslContextFactory) {
+        KeyStoreScanner keystoreScanner = new 
KeyStoreScanner(sslContextFactory);
+        keystoreScanner.setScanInterval(SCAN_INTERVAL);
+        server.addBean(keystoreScanner);
+    }
+
     /**
      * Creates and configures the SslContextFactory for the server.
      *
diff --git 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusHttpsMetricsProviderTest.java
 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusHttpsMetricsProviderTest.java
index c091934709..f730b4dbe0 100644
--- 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusHttpsMetricsProviderTest.java
+++ 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusHttpsMetricsProviderTest.java
@@ -43,10 +43,10 @@
 public class PrometheusHttpsMetricsProviderTest extends 
PrometheusMetricsTestBase {
 
     private PrometheusMetricsProvider provider;
-    private String httpHost = "127.0.0.1";
-    private int httpsPort = 4443;
-    private int httpPort = 4000;
-    private String testDataPath = System.getProperty("test.data.dir", 
"src/test/resources/data");
+    private final String httpHost = "127.0.0.1";
+    private final int httpsPort = 4443;
+    private final int httpPort = 4000;
+    private final String testDataPath = System.getProperty("test.data.dir", 
"src/test/resources/data");
 
     public void initializeProviderWithCustomConfig(Properties 
inputConfiguration) throws Exception {
         provider = new PrometheusMetricsProvider();
diff --git 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java
 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java
index bb24ab75d2..66a01fb95e 100644
--- 
a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java
+++ 
b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java
@@ -292,4 +292,20 @@ public void checkServerTrusted(X509Certificate[] certs, 
String authType) {
                 }
         };
     }
+
+    @Test
+    public void testPortUnification() throws Exception {
+        int unifiedPort = 5400;
+        Properties configuration = new Properties();
+        configuration.setProperty("httpsPort", String.valueOf(unifiedPort));
+        configuration.setProperty("httpPort", String.valueOf(unifiedPort));
+        String testDataPath = System.getProperty("test.data.dir", 
"src/test/resources/data");
+        configuration.setProperty("ssl.keyStore.location", testDataPath + 
"/ssl/server_keystore.jks");
+        configuration.setProperty("ssl.keyStore.password", "testpass");
+        configuration.setProperty("ssl.trustStore.location", testDataPath + 
"/ssl/server_truststore.jks");
+        configuration.setProperty("ssl.trustStore.password", "testpass");
+        PrometheusMetricsProvider provider = new PrometheusMetricsProvider();
+        provider.configure(configuration);
+        provider.start();
+    }
 }

Reply via email to