This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 9ca907c37b1 HDDS-13883. Support HTTPS with ozone insight command
(#9285)
9ca907c37b1 is described below
commit 9ca907c37b17dfc8f52029aa7a0e0788ec106154
Author: Sarveksha Yeshavantha Raju
<[email protected]>
AuthorDate: Wed Nov 19 13:36:43 2025 +0530
HDDS-13883. Support HTTPS with ozone insight command (#9285)
---
.../src/main/compose/ozonesecure/docker-config | 1 +
.../dist/src/main/compose/ozonesecure/test.sh | 1 +
.../dist/src/main/smoketest/cli/envvars.robot | 19 ++++
.../src/main/smoketest/cli/ozone-insight.robot | 59 +++++++++++
hadoop-ozone/insight/pom.xml | 11 +-
.../ozone/insight/BaseInsightSubCommand.java | 105 +++++++++++++++---
.../hadoop/ozone/insight/InsightHttpUtils.java | 118 +++++++++++++++++++++
.../apache/hadoop/ozone/insight/LogSubcommand.java | 41 +++----
.../hadoop/ozone/insight/MetricsSubCommand.java | 30 ++----
.../ozone/insight/TestBaseInsightSubCommand.java | 102 ++++++++++++++++++
10 files changed, 427 insertions(+), 60 deletions(-)
diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
index 5daf6c11fc9..6880613a67c 100644
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
@@ -82,6 +82,7 @@
OZONE-SITE.XML_hdds.scm.replication.over.replicated.interval=5s
OZONE-SITE.XML_hdds.scm.wait.time.after.safemode.exit=30s
OZONE-SITE.XML_ozone.scm.stale.node.interval=30s
OZONE-SITE.XML_ozone.scm.dead.node.interval=45s
+OZONE-SITE.XML_hdds.heartbeat.interval=5s
OZONE-SITE.XML_hdds.container.report.interval=60s
OZONE-SITE.XML_ozone.scm.close.container.wait.duration=5s
diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure/test.sh
b/hadoop-ozone/dist/src/main/compose/ozonesecure/test.sh
index 42653795522..637268b59e5 100755
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/test.sh
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/test.sh
@@ -35,6 +35,7 @@ execute_command_in_container kms hadoop key create
${OZONE_BUCKET_KEY_NAME}
execute_robot_test scm kinit.robot
+execute_robot_test scm cli/ozone-insight.robot
execute_robot_test scm basic
execute_robot_test scm security
diff --git a/hadoop-ozone/dist/src/main/smoketest/cli/envvars.robot
b/hadoop-ozone/dist/src/main/smoketest/cli/envvars.robot
index b36513b07e7..e875108d504 100644
--- a/hadoop-ozone/dist/src/main/smoketest/cli/envvars.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/cli/envvars.robot
@@ -16,12 +16,31 @@
*** Settings ***
Documentation Test ozone envvars command
Library BuiltIn
+Library OperatingSystem
Resource ../commonlib.robot
Test Timeout 5 minutes
+Suite Setup Save Environment
+Suite Teardown Restore Environment
*** Variables ***
${OZONE_HOME} /opt/hadoop
+*** Keywords ***
+Save Environment
+ ${saved} = Get Environment Variables
+ Set Suite Variable ${SAVED_ENV} ${saved}
+
+Restore Environment
+ FOR ${key} IN
+ ... HADOOP_HOME HADOOP_CONF_DIR HADOOP_LIBEXEC_DIR
+ ... OZONE_HOME OZONE_CONF_DIR OZONE_LIBEXEC_DIR
OZONE_DEPRECATION_WARNING
+ IF '${key}' in ${SAVED_ENV}
+ Set Environment Variable ${key} ${SAVED_ENV}[${key}]
+ ELSE
+ Run Keyword And Ignore Error Remove Environment Variable
${key}
+ END
+ END
+
*** Test Cases ***
Ignores deprecated vars if new ones are set
Set Environment Variable HADOOP_HOME /usr/local/hadoop
diff --git a/hadoop-ozone/dist/src/main/smoketest/cli/ozone-insight.robot
b/hadoop-ozone/dist/src/main/smoketest/cli/ozone-insight.robot
new file mode 100644
index 00000000000..f9c42fef19a
--- /dev/null
+++ b/hadoop-ozone/dist/src/main/smoketest/cli/ozone-insight.robot
@@ -0,0 +1,59 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+*** Settings ***
+Documentation Test ozone insight command with HTTP/HTTPS and SPNEGO
+Library BuiltIn
+Resource ../lib/os.robot
+Resource ../commonlib.robot
+Suite Setup Kinit test user testuser testuser.keytab
+Test Timeout 5 minutes
+
+*** Keywords ***
+Should Not Have Connection Errors
+ [Arguments] ${output}
+ Should Not Contain ${output} Connection Refused
+ Should Not Contain ${output} UnknownHostException
+ Should Not Contain ${output} Authentication Failed
+ Should Not Contain ${output} 0.0.0.0
+
+*** Test Cases ***
+List Insight Points
+ ${output} = Execute ozone insight list
+ Should Contain ${output} scm.node-manager
+ Should Contain ${output} om.key-manager
+ Should Contain ${output} datanode.dispatcher
+
+Test SCM Metrics Retrieval
+ ${output} = Execute ozone insight metrics scm.node-manager
+
+ Should Contain ${output} Metrics for `scm.node-manager`
+ Should Contain ${output} Node counters
+ Should Contain ${output} HB processing stats
+ Should Not Have Connection Errors ${output}
+
+Test OM Metrics Retrieval
+ ${output} = Execute ozone insight metrics om.key-manager
+
+ Should Contain ${output} Metrics for `om.key-manager`
+ Should Contain ${output} Key related metrics
+ Should Contain ${output} Key operation stats
+ Should Not Have Connection Errors ${output}
+
+Test SCM Log Streaming
+ ${output} = Execute And Ignore Error timeout 10 ozone insight log
scm.node-manager 2>&1 || true
+
+ Should Contain Any ${output} [SCM] SCMNodeManager
+ Should Not Have Connection Errors ${output}
diff --git a/hadoop-ozone/insight/pom.xml b/hadoop-ozone/insight/pom.xml
index fd64cd841f6..75e6ee1410e 100644
--- a/hadoop-ozone/insight/pom.xml
+++ b/hadoop-ozone/insight/pom.xml
@@ -16,8 +16,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.ozone</groupId>
- <artifactId>ozone</artifactId>
+ <artifactId>hdds-hadoop-dependency-client</artifactId>
<version>2.2.0-SNAPSHOT</version>
+ <relativePath>../../hadoop-hdds/hadoop-dependency-client</relativePath>
</parent>
<artifactId>ozone-insight</artifactId>
<version>2.2.0-SNAPSHOT</version>
@@ -35,12 +36,12 @@
<artifactId>picocli</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-common</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpcore</artifactId>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-hdfs-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.ozone</groupId>
diff --git
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/BaseInsightSubCommand.java
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/BaseInsightSubCommand.java
index 5a5e059689e..3d5ff688e65 100644
---
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/BaseInsightSubCommand.java
+++
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/BaseInsightSubCommand.java
@@ -17,13 +17,26 @@
package org.apache.hadoop.ozone.insight;
+import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HTTPS_ADDRESS_KEY;
+import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HTTPS_BIND_PORT_DEFAULT;
+import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HTTP_ADDRESS_KEY;
+import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HTTP_BIND_HOST_DEFAULT;
+import static
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_HTTP_BIND_PORT_DEFAULT;
+import static org.apache.hadoop.hdds.server.http.HttpServer2.HTTPS_SCHEME;
+import static org.apache.hadoop.hdds.server.http.HttpServer2.HTTP_SCHEME;
+import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_HTTPS_ADDRESS_KEY;
+import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_HTTPS_BIND_PORT_DEFAULT;
+import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_HTTP_ADDRESS_KEY;
+import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_HTTP_BIND_HOST_DEFAULT;
+import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_HTTP_BIND_PORT_DEFAULT;
+
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
-import org.apache.hadoop.ozone.insight.Component.Type;
+import org.apache.hadoop.hdds.server.http.HttpConfig;
import org.apache.hadoop.ozone.insight.datanode.DatanodeDispatcherInsight;
import org.apache.hadoop.ozone.insight.datanode.RatisInsight;
import org.apache.hadoop.ozone.insight.om.KeyManagerInsight;
@@ -62,25 +75,85 @@ public InsightPoint getInsight(OzoneConfiguration
configuration,
* Utility to get the host base on a component.
*/
public String getHost(OzoneConfiguration conf, Component component) {
+ HttpConfig.Policy policy = HttpConfig.getHttpPolicy(conf);
+ String protocol = policy.isHttpsEnabled() ? HTTPS_SCHEME : HTTP_SCHEME;
+
if (component.getHostname() != null) {
- return "http://" + component.getHostname() + ":" + component.getPort();
- } else if (component.getName() == Type.SCM) {
- Optional<String> scmHost =
- HddsUtils.getHostNameFromConfigKeys(conf,
- ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_ADDRESS_KEY,
- ScmConfigKeys.OZONE_SCM_CLIENT_ADDRESS_KEY);
-
- return "http://" + scmHost.get() + ":9876";
- } else if (component.getName() == Type.OM) {
- Optional<String> omHost =
- HddsUtils.getHostNameFromConfigKeys(conf,
- OMConfigKeys.OZONE_OM_ADDRESS_KEY);
- return "http://" + omHost.get() + ":9874";
- } else {
+ return protocol + "://" + component.getHostname() + ":" +
component.getPort();
+ }
+
+ String address = getComponentAddress(conf, component.getName(), policy);
+ return protocol + "://" + address;
+ }
+
+ /**
+ * Get the component address based on HTTP policy.
+ */
+ private String getComponentAddress(OzoneConfiguration conf,
+ Component.Type componentType, HttpConfig.Policy policy) {
+ boolean isHttpsEnabled = policy.isHttpsEnabled();
+ String address;
+
+ switch (componentType) {
+ case SCM:
+ if (isHttpsEnabled) {
+ address = conf.get(OZONE_SCM_HTTPS_ADDRESS_KEY,
OZONE_SCM_HTTP_BIND_HOST_DEFAULT + ":" +
+ OZONE_SCM_HTTPS_BIND_PORT_DEFAULT);
+ } else {
+ address = conf.get(OZONE_SCM_HTTP_ADDRESS_KEY,
OZONE_SCM_HTTP_BIND_HOST_DEFAULT + ":" +
+ OZONE_SCM_HTTP_BIND_PORT_DEFAULT);
+ }
+
+ // Fallback to RPC hostname
+ if (getHostOnly(address).equals(OZONE_SCM_HTTP_BIND_HOST_DEFAULT)) {
+ Optional<String> scmHost = HddsUtils.getHostNameFromConfigKeys(conf,
+ ScmConfigKeys.OZONE_SCM_BLOCK_CLIENT_ADDRESS_KEY,
+ ScmConfigKeys.OZONE_SCM_CLIENT_ADDRESS_KEY);
+ if (scmHost.isPresent()) {
+ return scmHost.get() + ":" + getPort(address);
+ }
+ }
+ return address;
+
+ case OM:
+ if (isHttpsEnabled) {
+ address = conf.get(OZONE_OM_HTTPS_ADDRESS_KEY,
OZONE_OM_HTTP_BIND_HOST_DEFAULT + ":" +
+ OZONE_OM_HTTPS_BIND_PORT_DEFAULT);
+ } else {
+ address = conf.get(OZONE_OM_HTTP_ADDRESS_KEY,
OZONE_OM_HTTP_BIND_HOST_DEFAULT + ":" +
+ OZONE_OM_HTTP_BIND_PORT_DEFAULT);
+ }
+
+ // Fallback to RPC hostname
+ if (getHostOnly(address).equals(OZONE_OM_HTTP_BIND_HOST_DEFAULT)) {
+ Optional<String> omHost = HddsUtils.getHostNameFromConfigKeys(conf,
+ OMConfigKeys.OZONE_OM_ADDRESS_KEY);
+ if (omHost.isPresent()) {
+ return omHost.get() + ":" + getPort(address);
+ }
+ }
+ return address;
+
+ default:
throw new IllegalArgumentException(
- "Component type is not supported: " + component.getName());
+ "Component type is not supported: " + componentType);
}
+ }
+ /**
+ * Extract hostname from address string.
+ * e.g. Input: "0.0.0.0:9876" -> Output: "0.0.0.0"
+ */
+ private String getHostOnly(String address) {
+ return address.split(":", 2)[0];
+ }
+
+ /**
+ * Extract port from address string.
+ * e.g. Input: "0.0.0.0:9876" -> Output: "9876"
+ */
+ private String getPort(String address) {
+ return address.split(":", 2)[1];
}
public Map<String, InsightPoint> createInsightPoints(
diff --git
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/InsightHttpUtils.java
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/InsightHttpUtils.java
new file mode 100644
index 00000000000..1e193478eaa
--- /dev/null
+++
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/InsightHttpUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.insight;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+import javax.security.sasl.AuthenticationException;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdfs.web.URLConnectionFactory;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+
+/**
+ * Utility class for making HTTP/HTTPS calls with SPNEGO authentication
support.
+ */
+public final class InsightHttpUtils {
+
+ private InsightHttpUtils() {
+
+ }
+
+ /**
+ * Check if SPNEGO authentication is enabled.
+ */
+ public static boolean isSpnegoEnabled(OzoneConfiguration conf) {
+ String authType = conf.get(OzoneConfigKeys.OZONE_HTTP_SECURITY_ENABLED_KEY,
+
String.valueOf(OzoneConfigKeys.OZONE_HTTP_SECURITY_ENABLED_DEFAULT));
+ return "kerberos".equalsIgnoreCase(authType) ||
"true".equalsIgnoreCase(authType);
+ }
+
+ /**
+ * Make an HTTP/HTTPS call with SPNEGO authentication support.
+ *
+ * @param url The URL to connect to
+ * @param conf The Ozone configuration
+ * @return HttpURLConnection or null if connection failed
+ * @throws IOException if connection fails
+ */
+ public static HttpURLConnection openConnection(String url,
OzoneConfiguration conf) throws IOException {
+ try {
+ final URLConnectionFactory connectionFactory =
+ URLConnectionFactory.newDefaultURLConnectionFactory(conf);
+
+ boolean isSpnegoEnabled = isSpnegoEnabled(conf);
+
+ return (HttpURLConnection)
+ connectionFactory.openConnection(new URL(url), isSpnegoEnabled);
+ } catch (ConnectException ex) {
+ System.err.println("Connection Refused: " + url);
+ return null;
+ } catch (AuthenticationException authEx) {
+ System.err.println("Authentication Failed. Please make sure you " +
+ "have logged in with kinit or disable Ozone security settings.");
+ return null;
+ } catch (Exception ex) {
+ throw new IOException("Failed to connect to " + url, ex);
+ }
+ }
+
+ /**
+ * Read the response from an HttpURLConnection as a String.
+ */
+ public static String readResponse(HttpURLConnection httpURLConnection)
throws IOException {
+ if (httpURLConnection == null) {
+ return null;
+ }
+
+ int responseCode = httpURLConnection.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("HTTP " + responseCode + ": " +
httpURLConnection.getResponseMessage());
+ }
+
+ try (InputStream inputStream = httpURLConnection.getInputStream();
+ InputStreamReader reader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
+ BufferedReader bufferedReader = new BufferedReader(reader)) {
+ return bufferedReader.lines().collect(Collectors.joining("\n"));
+ }
+ }
+
+ /**
+ * Read response as a stream of lines (for streaming endpoints like
/logstream).
+ */
+ public static BufferedReader getResponseReader(HttpURLConnection
httpURLConnection) throws IOException {
+ if (httpURLConnection == null) {
+ return null;
+ }
+
+ int responseCode = httpURLConnection.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ throw new IOException("HTTP " + responseCode + ": " +
httpURLConnection.getResponseMessage());
+ }
+
+ return new BufferedReader(new InputStreamReader(
+ httpURLConnection.getInputStream(), StandardCharsets.UTF_8));
+ }
+}
+
diff --git
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/LogSubcommand.java
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/LogSubcommand.java
index ea3ac7533b7..ab73de69099 100644
---
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/LogSubcommand.java
+++
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/LogSubcommand.java
@@ -21,8 +21,7 @@
import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
+import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -37,10 +36,6 @@
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.ozone.insight.LoggerSource.Level;
import org.apache.hadoop.ozone.util.ShutdownHookManager;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClientBuilder;
import picocli.CommandLine;
/**
@@ -120,14 +115,18 @@ private void streamLog(OzoneConfiguration conf,
Set<Component> sources,
private void streamLog(OzoneConfiguration conf, Component logComponent,
List<LoggerSource> loggers, Predicate<String> filter) {
- HttpClient client = HttpClientBuilder.create().build();
-
- HttpGet get = new HttpGet(getHost(conf, logComponent) + "/logstream");
+ String url = getHost(conf, logComponent) + "/logstream";
try {
- HttpResponse execute = client.execute(get);
- try (BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(execute.getEntity().getContent(),
- StandardCharsets.UTF_8))) {
+ HttpURLConnection httpURLConnection =
InsightHttpUtils.openConnection(url, conf);
+ if (httpURLConnection == null) {
+ throw new RuntimeException("Failed to connect to " + url);
+ }
+
+ try (BufferedReader bufferedReader =
+ InsightHttpUtils.getResponseReader(httpURLConnection)) {
+ if (bufferedReader == null) {
+ throw new RuntimeException("Failed to get response from " + url);
+ }
bufferedReader.lines()
.filter(line -> {
for (LoggerSource logger : loggers) {
@@ -168,19 +167,21 @@ private void setLogLevels(OzoneConfiguration conf,
List<LoggerSource> loggers,
private void setLogLevel(OzoneConfiguration conf, String name,
Component component, LoggerSource.Level level) {
- HttpClient client = HttpClientBuilder.create().build();
-
String request = String
.format("/logLevel?log=%s&level=%s", name,
level);
String hostName = getHost(conf, component);
- HttpGet get = new HttpGet(hostName + request);
+ String url = hostName + request;
try {
- HttpResponse execute = client.execute(get);
- if (execute.getStatusLine().getStatusCode() != 200) {
+ HttpURLConnection httpURLConnection =
InsightHttpUtils.openConnection(url, conf);
+ if (httpURLConnection == null) {
+ throw new RuntimeException("Failed to connect to " + url);
+ }
+
+ int responseCode = httpURLConnection.getResponseCode();
+ if (responseCode != 200) {
throw new RuntimeException(
- "Can't set the log level: " + hostName + " -> HTTP " + execute
- .getStatusLine().getStatusCode());
+ "Can't set the log level: " + hostName + " -> HTTP " +
responseCode);
}
} catch (IOException e) {
throw new RuntimeException(e);
diff --git
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/MetricsSubCommand.java
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/MetricsSubCommand.java
index 6cfb4fb020b..35619f54e67 100644
---
a/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/MetricsSubCommand.java
+++
b/hadoop-ozone/insight/src/main/java/org/apache/hadoop/ozone/insight/MetricsSubCommand.java
@@ -17,10 +17,9 @@
package org.apache.hadoop.ozone.insight;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
+import java.net.HttpURLConnection;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -31,10 +30,6 @@
import java.util.stream.Collectors;
import org.apache.hadoop.hdds.cli.HddsVersionProvider;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClientBuilder;
import picocli.CommandLine;
/**
@@ -117,22 +112,19 @@ private String selectValue(List<String> metrics,
private List<String> getMetrics(OzoneConfiguration conf,
Component component) {
- HttpClient client = HttpClientBuilder.create().build();
- HttpGet get = new HttpGet(getHost(conf, component) + "/prom");
+ String url = getHost(conf, component) + "/prom";
try {
- HttpResponse execute = client.execute(get);
- if (execute.getStatusLine().getStatusCode() != 200) {
- throw new RuntimeException(
- "Can't read prometheus metrics endpoint" + execute.getStatusLine()
- .getStatusCode());
+ HttpURLConnection httpURLConnection =
InsightHttpUtils.openConnection(url, conf);
+ if (httpURLConnection == null) {
+ throw new RuntimeException("Failed to connect to " + url);
}
- try (BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(execute.getEntity().getContent(),
- StandardCharsets.UTF_8))) {
- return bufferedReader.lines().collect(Collectors.toList());
+ String response = InsightHttpUtils.readResponse(httpURLConnection);
+ if (response == null) {
+ throw new RuntimeException("Empty response from " + url);
}
+ return Arrays.asList(response.split("\\r?\\n"));
} catch (IOException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Can't read prometheus metrics endpoint: " +
e.getMessage(), e);
}
}
diff --git
a/hadoop-ozone/insight/src/test/java/org/apache/hadoop/ozone/insight/TestBaseInsightSubCommand.java
b/hadoop-ozone/insight/src/test/java/org/apache/hadoop/ozone/insight/TestBaseInsightSubCommand.java
new file mode 100644
index 00000000000..9b7e6ef075d
--- /dev/null
+++
b/hadoop-ozone/insight/src/test/java/org/apache/hadoop/ozone/insight/TestBaseInsightSubCommand.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.insight;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.scm.ScmConfigKeys;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.insight.Component.Type;
+import org.apache.hadoop.ozone.om.OMConfigKeys;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for host resolution logic in BaseInsightSubCommand.
+ */
+public class TestBaseInsightSubCommand {
+
+ @Test
+ public void testHttpOnly() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ conf.set(OzoneConfigKeys.OZONE_HTTP_POLICY_KEY, "HTTP_ONLY");
+ conf.set(ScmConfigKeys.OZONE_SCM_HTTP_ADDRESS_KEY, "scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTP_BIND_PORT_DEFAULT);
+ conf.set(OMConfigKeys.OZONE_OM_HTTP_ADDRESS_KEY, "om-host:" +
OMConfigKeys.OZONE_OM_HTTP_BIND_PORT_DEFAULT);
+
+ BaseInsightSubCommand command = new BaseInsightSubCommand();
+
+ assertEquals("http://scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTP_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.SCM, null)));
+
+ assertEquals("http://om-host:" +
OMConfigKeys.OZONE_OM_HTTP_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.OM, null)));
+ }
+
+ @Test
+ public void testHttpsOnly() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ conf.set(OzoneConfigKeys.OZONE_HTTP_POLICY_KEY, "HTTPS_ONLY");
+ conf.set(ScmConfigKeys.OZONE_SCM_HTTPS_ADDRESS_KEY, "scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTPS_BIND_PORT_DEFAULT);
+ conf.set(OMConfigKeys.OZONE_OM_HTTPS_ADDRESS_KEY, "om-host:" +
OMConfigKeys.OZONE_OM_HTTPS_BIND_PORT_DEFAULT);
+
+ BaseInsightSubCommand command = new BaseInsightSubCommand();
+
+ assertEquals("https://scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTPS_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.SCM, null)));
+
+ assertEquals("https://om-host:" +
OMConfigKeys.OZONE_OM_HTTPS_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.OM, null)));
+ }
+
+ @Test
+ public void testHttpAndHttpsPrefersHttps() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ conf.set(OzoneConfigKeys.OZONE_HTTP_POLICY_KEY, "HTTP_AND_HTTPS");
+ conf.set(ScmConfigKeys.OZONE_SCM_HTTPS_ADDRESS_KEY,
+ "scm-host:" + ScmConfigKeys.OZONE_SCM_HTTPS_BIND_PORT_DEFAULT);
+
+ BaseInsightSubCommand command = new BaseInsightSubCommand();
+
+ String scmHost = command.getHost(conf, new Component(Type.SCM, null));
+ assertTrue(scmHost.startsWith("https://"));
+ }
+
+ @Test
+ public void testFallbackToRpcAddress() {
+ OzoneConfiguration conf = new OzoneConfiguration();
+ conf.set(OzoneConfigKeys.OZONE_HTTP_POLICY_KEY, "HTTP_ONLY");
+ conf.set(ScmConfigKeys.OZONE_SCM_CLIENT_ADDRESS_KEY, "scm-host:9860");
+ conf.set(OMConfigKeys.OZONE_OM_ADDRESS_KEY, "om-host:9862");
+
+ BaseInsightSubCommand command = new BaseInsightSubCommand();
+
+ // Should fallback to hostname from RPC address with default HTTP port
+ assertEquals("http://scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTP_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.SCM, null)));
+ assertEquals("http://om-host:" +
OMConfigKeys.OZONE_OM_HTTP_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.OM, null)));
+
+ // Should fallback to hostname from RPC address with default HTTPS port
+ conf.set(OzoneConfigKeys.OZONE_HTTP_POLICY_KEY, "HTTPS_ONLY");
+ assertEquals("https://scm-host:" +
ScmConfigKeys.OZONE_SCM_HTTPS_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.SCM, null)));
+ assertEquals("https://om-host:" +
OMConfigKeys.OZONE_OM_HTTPS_BIND_PORT_DEFAULT,
+ command.getHost(conf, new Component(Type.OM, null)));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]