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

chia7712 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 123356bad50 MINOR: Scala to Java migration. Migrated some tests from 
PlaintextAdminIntegrationTest to a new java class. (#22290)
123356bad50 is described below

commit 123356bad50da1418f42f2f675c963156d4bb78c
Author: Nikita Shupletsov <[email protected]>
AuthorDate: Sun Jul 26 05:46:16 2026 -0700

    MINOR: Scala to Java migration. Migrated some tests from 
PlaintextAdminIntegrationTest to a new java class. (#22290)
    
    Contributing to the bigger effort of migrating scala to java
    
    Reviewers: Sushant Mahajan <[email protected]>, Ken Huang
    <[email protected]>, Chia-Ping Tsai <[email protected]>
---
 .../kafka/clients/admin/AdminMetadataTest.java     | 247 +++++++++++++++++++++
 .../kafka/api/PlaintextAdminIntegrationTest.scala  | 155 +------------
 2 files changed, 248 insertions(+), 154 deletions(-)

diff --git 
a/clients/clients-integration-tests/src/test/java/org/apache/kafka/clients/admin/AdminMetadataTest.java
 
b/clients/clients-integration-tests/src/test/java/org/apache/kafka/clients/admin/AdminMetadataTest.java
new file mode 100644
index 00000000000..239c8e31d50
--- /dev/null
+++ 
b/clients/clients-integration-tests/src/test/java/org/apache/kafka/clients/admin/AdminMetadataTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.kafka.clients.admin;
+
+import org.apache.kafka.clients.consumer.Consumer;
+import org.apache.kafka.common.KafkaFuture;
+import org.apache.kafka.common.Node;
+import org.apache.kafka.common.TopicCollection;
+import org.apache.kafka.common.Uuid;
+import org.apache.kafka.common.errors.TimeoutException;
+import org.apache.kafka.common.errors.UnknownTopicIdException;
+import org.apache.kafka.common.errors.UnknownTopicOrPartitionException;
+import org.apache.kafka.common.internals.Topic;
+import org.apache.kafka.common.test.ClusterInstance;
+import org.apache.kafka.common.test.api.ClusterTest;
+import org.apache.kafka.common.test.api.ClusterTestDefaults;
+import org.apache.kafka.common.test.api.Type;
+import org.apache.kafka.test.TestUtils;
+
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import static org.apache.kafka.test.TestUtils.assertFutureThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ClusterTestDefaults(brokers = 3, types = {Type.KRAFT})
+public class AdminMetadataTest {
+
+    // Incorrect broker port which can used by kafka clients in tests. This 
port should not be used
+    // by any other service and hence we use a reserved port.
+    private static final int INCORRECT_BROKER_PORT = 225;
+
+    private final ClusterInstance clusterInstance;
+
+    AdminMetadataTest(ClusterInstance clusterInstance) {
+        this.clusterInstance = clusterInstance;
+    }
+
+    @ClusterTest
+    public void testListNodes() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            List<String> brokerStrs = 
Arrays.stream(clusterInstance.bootstrapServers().split(","))
+                    .sorted()
+                    .toList();
+            TestUtils.waitForCondition(
+                    () -> admin.describeCluster().nodes().get().size() >= 
brokerStrs.size(),
+                    "Timed out waiting for all brokers to be discovered");
+            List<String> nodeStrs = 
admin.describeCluster().nodes().get().stream()
+                    .map(node -> node.host() + ":" + node.port())
+                    .sorted()
+                    .toList();
+            assertEquals(String.join(",", brokerStrs), String.join(",", 
nodeStrs));
+        }
+    }
+
+    @ClusterTest
+    public void testListNodesWithFencedBroker() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            int fencedBrokerId = Collections.max(clusterInstance.brokerIds());
+            int totalBrokers = clusterInstance.brokerIds().size();
+            clusterInstance.shutdownBroker(fencedBrokerId);
+
+            // It takes a few seconds for a broker to get fenced after being 
killed,
+            // so we retry until only the non-fenced brokers are returned.
+            TestUtils.waitForCondition(
+                    () -> admin.describeCluster().nodes().get().size() == 
totalBrokers - 1,
+                    20_000,
+                    "Timed out waiting for broker " + fencedBrokerId + " to be 
fenced");
+
+            // List nodes again but this time include the fenced broker.
+            Collection<Node> nodes = admin.describeCluster(
+                    new 
DescribeClusterOptions().includeFencedBrokers(true)).nodes().get();
+            assertEquals(totalBrokers, nodes.size());
+            for (Node node : nodes) {
+                if (node.id() == fencedBrokerId) {
+                    assertTrue(node.isFenced());
+                } else {
+                    assertFalse(node.isFenced());
+                }
+            }
+        }
+    }
+
+    @ClusterTest
+    public void testDescribeCluster() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            DescribeClusterResult result = admin.describeCluster();
+            Collection<Node> nodes = result.nodes().get();
+            assertEquals(clusterInstance.clusterId(), 
result.clusterId().get());
+
+            // In KRaft, we return a random brokerId as the current controller.
+            Node controller = result.controller().get();
+            assertTrue(clusterInstance.brokerIds().contains(controller.id()));
+
+            Set<String> brokerEndpoints = 
Set.of(clusterInstance.bootstrapServers().split(","));
+            assertEquals(brokerEndpoints.size(), nodes.size());
+            for (Node node : nodes) {
+                String hostStr = node.host() + ":" + node.port();
+                assertTrue(brokerEndpoints.contains(hostStr),
+                        "Unknown host:port pair " + hostStr + " in 
brokerVersionInfos");
+            }
+        }
+    }
+
+    @ClusterTest
+    public void testListTopicsWithOptionTimeoutMs() {
+        Admin admin = createInvalidAdminClient();
+        try {
+            ListTopicsOptions timeoutOption = new 
ListTopicsOptions().timeoutMs(0);
+            ExecutionException exception = 
assertThrows(ExecutionException.class,
+                    () -> admin.listTopics(timeoutOption).names().get());
+            assertInstanceOf(TimeoutException.class, exception.getCause());
+        } finally {
+            admin.close(Duration.ZERO);
+        }
+    }
+
+    @ClusterTest
+    public void testListTopicsWithOptionListInternal() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            String topic = "test-topic";
+            admin.createTopics(List.of(new NewTopic(topic, 1, (short) 
1))).all().get();
+            clusterInstance.waitTopicCreation(topic, 1);
+
+            try (Consumer<byte[], byte[]> consumer = 
clusterInstance.consumer()) {
+                consumer.subscribe(List.of(topic));
+                consumer.poll(Duration.ofMillis(100));
+            }
+
+            TestUtils.waitForCondition(() -> {
+                Set<String> topicNames = admin.listTopics(new 
ListTopicsOptions().listInternal(true)).names().get();
+                return topicNames.contains(Topic.GROUP_METADATA_TOPIC_NAME);
+            }, "Expected to see internal topic " + 
Topic.GROUP_METADATA_TOPIC_NAME);
+        }
+    }
+
+    @ClusterTest
+    public void testDescribeTopicsWithOptionPartitionSizeLimitPerResponse() 
throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            String testTopic = "test-topic";
+            admin.createTopics(List.of(new NewTopic(testTopic, 3, (short) 
1))).all().get();
+            clusterInstance.waitTopicCreation(testTopic, 3);
+
+            Map<String, TopicDescription> topics = 
admin.describeTopics(List.of(testTopic),
+                    new 
DescribeTopicsOptions().partitionSizeLimitPerResponse(1)).allTopicNames().get();
+            assertEquals(1, topics.size());
+            assertEquals(3, topics.get(testTopic).partitions().size());
+        }
+    }
+
+    @ClusterTest
+    public void testDescribeTopicsWithOptionTimeoutMs() {
+        Admin admin = createInvalidAdminClient();
+        try {
+            DescribeTopicsOptions timeoutOption = new 
DescribeTopicsOptions().timeoutMs(0);
+            ExecutionException exception = 
assertThrows(ExecutionException.class,
+                    () -> admin.describeTopics(List.of("test-topic"), 
timeoutOption).allTopicNames().get());
+            assertInstanceOf(TimeoutException.class, exception.getCause());
+        } finally {
+            admin.close(Duration.ZERO);
+        }
+    }
+
+    /**
+     * describe should not auto create topics.
+     */
+    @ClusterTest
+    public void testDescribeNonExistingTopic() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            String existingTopic = "existing-topic";
+            admin.createTopics(List.of(new NewTopic(existingTopic, 1, (short) 
1))).all().get();
+            clusterInstance.waitTopicCreation(existingTopic, 1);
+
+            String nonExistingTopic = "non-existing";
+            Map<String, KafkaFuture<TopicDescription>> results =
+                    admin.describeTopics(List.of(nonExistingTopic, 
existingTopic)).topicNameValues();
+            assertEquals(existingTopic, 
results.get(existingTopic).get().name());
+            assertFutureThrows(UnknownTopicOrPartitionException.class, 
results.get(nonExistingTopic));
+        }
+    }
+
+    @ClusterTest
+    public void testDescribeTopicsWithIds() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            String existingTopic = "existing-topic";
+            CreateTopicsResult createResult = admin.createTopics(List.of(new 
NewTopic(existingTopic, 1, (short) 1)));
+            createResult.all().get();
+            clusterInstance.waitTopicCreation(existingTopic, 1);
+            clusterInstance.ensureConsistentMetadata();
+
+            Uuid existingTopicId = createResult.topicId(existingTopic).get();
+            Uuid nonExistingTopicId = Uuid.randomUuid();
+
+            Map<Uuid, KafkaFuture<TopicDescription>> results = 
admin.describeTopics(
+                    TopicCollection.ofTopicIds(List.of(existingTopicId, 
nonExistingTopicId))).topicIdValues();
+            assertEquals(existingTopicId, 
results.get(existingTopicId).get().topicId());
+            assertFutureThrows(UnknownTopicIdException.class, 
results.get(nonExistingTopicId));
+        }
+    }
+
+    @ClusterTest
+    public void testDescribeTopicsWithNames() throws Exception {
+        try (Admin admin = clusterInstance.admin()) {
+            String existingTopic = "existing-topic";
+            CreateTopicsResult createResult = admin.createTopics(List.of(new 
NewTopic(existingTopic, 1, (short) 1)));
+            createResult.all().get();
+            clusterInstance.waitTopicCreation(existingTopic, 1);
+            clusterInstance.ensureConsistentMetadata();
+
+            Uuid existingTopicId = createResult.topicId(existingTopic).get();
+            Map<String, KafkaFuture<TopicDescription>> results = 
admin.describeTopics(
+                    
TopicCollection.ofTopicNames(List.of(existingTopic))).topicNameValues();
+            assertEquals(existingTopicId, 
results.get(existingTopic).get().topicId());
+        }
+    }
+
+    private Admin createInvalidAdminClient() {
+        Map<String, Object> config = Map.of(
+                AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:" + 
INCORRECT_BROKER_PORT
+        );
+        return Admin.create(config);
+    }
+}
diff --git 
a/core/src/test/scala/integration/kafka/api/PlaintextAdminIntegrationTest.scala 
b/core/src/test/scala/integration/kafka/api/PlaintextAdminIntegrationTest.scala
index 5b92f13c74c..4e8fcf7698e 100644
--- 
a/core/src/test/scala/integration/kafka/api/PlaintextAdminIntegrationTest.scala
+++ 
b/core/src/test/scala/integration/kafka/api/PlaintextAdminIntegrationTest.scala
@@ -48,7 +48,7 @@ import org.apache.kafka.common.requests.DeleteRecordsRequest
 import org.apache.kafka.common.resource.{PatternType, ResourcePattern, 
ResourceType}
 import org.apache.kafka.common.serialization.{ByteArrayDeserializer, 
ByteArraySerializer}
 import org.apache.kafka.common.utils.{Time, Utils}
-import org.apache.kafka.common.{ConsumerGroupState, ElectionType, GroupState, 
GroupType, IsolationLevel, TopicCollection, TopicPartition, TopicPartitionInfo, 
TopicPartitionReplica, Uuid}
+import org.apache.kafka.common.{ConsumerGroupState, ElectionType, GroupState, 
GroupType, IsolationLevel, TopicCollection, TopicPartition, TopicPartitionInfo, 
TopicPartitionReplica}
 import 
org.apache.kafka.controller.ControllerRequestContextUtil.ANONYMOUS_CONTEXT
 import org.apache.kafka.coordinator.group.{GroupConfig, GroupCoordinatorConfig}
 import org.apache.kafka.network.SocketServerConfigs
@@ -630,41 +630,6 @@ class PlaintextAdminIntegrationTest extends 
BaseAdminIntegrationTest {
     client.close() // double close has no effect
   }
 
-  @Test
-  def testListNodes(): Unit = {
-    client = createAdminClient
-    val brokerStrs = bootstrapServers().split(",").toList.sorted
-    var nodeStrs: List[String] = null
-    do {
-      val nodes = client.describeCluster().nodes().get().asScala
-      nodeStrs = nodes.map(node => s"${node.host}:${node.port}").toList.sorted
-    } while (nodeStrs.size < brokerStrs.size)
-    assertEquals(brokerStrs.mkString(","), nodeStrs.mkString(","))
-  }
-
-  @Test
-  def testListNodesWithFencedBroker(): Unit = {
-    client = createAdminClient
-    val fencedBrokerId = brokers.last.config.brokerId
-    killBroker(fencedBrokerId, JDuration.ofMillis(0))
-    // It takes a few seconds for a broker to get fenced after being killed
-    // So we retry until only 2 of 3 brokers returned in the result or the max 
wait is reached
-    TestUtils.retry(20000) {
-      
assertTrue(client.describeCluster().nodes().get().asScala.size.equals(brokers.size
 - 1))
-    }
-
-    // List nodes again but this time include the fenced broker
-    val nodes = client.describeCluster(new 
DescribeClusterOptions().includeFencedBrokers(true)).nodes().get().asScala
-    assertTrue(nodes.size.equals(brokers.size))
-    nodes.foreach(node => {
-      if (node.id().equals(fencedBrokerId)) {
-        assertTrue(node.isFenced)
-      } else {
-        assertFalse(node.isFenced)
-      }
-    })
-  }
-
   @Test
   def testAdminClientHandlingBadIPWithoutTimeout(): Unit = {
     val config = createConfig
@@ -725,124 +690,6 @@ class PlaintextAdminIntegrationTest extends 
BaseAdminIntegrationTest {
     } finally client.close(time.Duration.ZERO)
   }
 
-  @Test
-  def testListTopicsWithOptionTimeoutMs(): Unit = {
-    client = createInvalidAdminClient()
-
-    try {
-      val timeoutOption = new ListTopicsOptions().timeoutMs(0)
-      val exception = assertThrows(classOf[ExecutionException], () =>
-        client.listTopics(timeoutOption).names().get())
-      assertInstanceOf(classOf[TimeoutException], exception.getCause)
-    } finally client.close(time.Duration.ZERO)
-  }
-
-  @Test
-  def testListTopicsWithOptionListInternal(): Unit = {
-    client = createAdminClient
-
-    val topicNames = client.listTopics(new 
ListTopicsOptions().listInternal(true)).names().get()
-    assertFalse(topicNames.isEmpty, "Expected to see internal topics")
-  }
-
-  @Test
-  def testDescribeTopicsWithOptionPartitionSizeLimitPerResponse(): Unit = {
-    client = createAdminClient
-
-    val testTopics = Seq("test-topic")
-    client.createTopics(testTopics.map(new NewTopic(_, 3, 
1.toShort)).asJava).all.get()
-    waitForTopics(client, testTopics, List())
-
-    val topics = client.describeTopics(testTopics.asJava, new 
DescribeTopicsOptions().partitionSizeLimitPerResponse(1)).allTopicNames().get()
-    assertEquals(1, topics.size())
-    assertEquals(3, topics.get("test-topic").partitions().size())
-
-    client.deleteTopics(testTopics.asJava).all().get()
-    waitForTopics(client, List(), testTopics)
-  }
-
-  @Test
-  def testDescribeTopicsWithOptionTimeoutMs(): Unit = {
-    client = createInvalidAdminClient()
-
-    try {
-      val timeoutOption = new DescribeTopicsOptions().timeoutMs(0)
-      val exception = assertThrows(classOf[ExecutionException], () =>
-        client.describeTopics(util.List.of("test-topic"), 
timeoutOption).allTopicNames().get())
-      assertInstanceOf(classOf[TimeoutException], exception.getCause)
-    } finally client.close(time.Duration.ZERO)
-  }
-
-  /**
-    * describe should not auto create topics
-    */
-  @Test
-  def testDescribeNonExistingTopic(): Unit = {
-    client = createAdminClient
-
-    val existingTopic = "existing-topic"
-    client.createTopics(Seq(existingTopic).map(new NewTopic(_, 1, 
1.toShort)).asJava).all.get()
-    waitForTopics(client, Seq(existingTopic), List())
-
-    val nonExistingTopic = "non-existing"
-    val results = client.describeTopics(util.List.of(nonExistingTopic, 
existingTopic)).topicNameValues()
-    assertEquals(existingTopic, results.get(existingTopic).get.name)
-    assertFutureThrows(classOf[UnknownTopicOrPartitionException], 
results.get(nonExistingTopic))
-  }
-
-  @Test
-  def testDescribeTopicsWithIds(): Unit = {
-    client = createAdminClient
-
-    val existingTopic = "existing-topic"
-    client.createTopics(Seq(existingTopic).map(new NewTopic(_, 1, 
1.toShort)).asJava).all.get()
-    waitForTopics(client, Seq(existingTopic), List())
-    ensureConsistentKRaftMetadata()
-
-    val existingTopicId = brokers.head.metadataCache.getTopicId(existingTopic)
-
-    val nonExistingTopicId = Uuid.randomUuid()
-
-    val results = 
client.describeTopics(TopicCollection.ofTopicIds(util.List.of(existingTopicId, 
nonExistingTopicId))).topicIdValues()
-    assertEquals(existingTopicId, results.get(existingTopicId).get.topicId())
-    assertFutureThrows(classOf[UnknownTopicIdException], 
results.get(nonExistingTopicId))
-  }
-
-  @Test
-  def testDescribeTopicsWithNames(): Unit = {
-    client = createAdminClient
-
-    val existingTopic = "existing-topic"
-    client.createTopics(Seq(existingTopic).map(new NewTopic(_, 1, 
1.toShort)).asJava).all.get()
-    waitForTopics(client, Seq(existingTopic), List())
-    ensureConsistentKRaftMetadata()
-
-    val existingTopicId = brokers.head.metadataCache.getTopicId(existingTopic)
-    val results = 
client.describeTopics(TopicCollection.ofTopicNames(util.List.of(existingTopic))).topicNameValues()
-    assertEquals(existingTopicId, results.get(existingTopic).get.topicId())
-  }
-
-  @Test
-  def testDescribeCluster(): Unit = {
-    client = createAdminClient
-    val result = client.describeCluster
-    val nodes = result.nodes.get()
-    val clusterId = result.clusterId().get()
-    assertEquals(brokers.head.dataPlaneRequestProcessor.clusterId, clusterId)
-    val controller = result.controller().get()
-
-    // In KRaft, we return a random brokerId as the current controller.
-    val brokerIds = brokers.map(_.config.brokerId).toSet
-    assertTrue(brokerIds.contains(controller.id))
-
-    val brokerEndpoints = bootstrapServers().split(",")
-    assertEquals(brokerEndpoints.size, nodes.size)
-    for (node <- nodes.asScala) {
-      val hostStr = s"${node.host}:${node.port}"
-      assertTrue(brokerEndpoints.contains(hostStr), s"Unknown host:port pair 
$hostStr in brokerVersionInfos")
-    }
-  }
-
   @Test
   def testDescribeLogDirs(): Unit = {
     client = createAdminClient

Reply via email to