diff --git a/tools/src/main/java/org/apache/kafka/tools/JmxTool.java b/tools/src/main/java/org/apache/kafka/tools/JmxTool.java index ea75748f68c..8347bffed3a 100644 --- a/tools/src/main/java/org/apache/kafka/tools/JmxTool.java +++ b/tools/src/main/java/org/apache/kafka/tools/JmxTool.java @@ -82,7 +82,7 @@ public class JmxTool { List queries = options.queries(); boolean hasPatternQueries = queries.stream().filter(Objects::nonNull).anyMatch(ObjectName::isPattern); - Set found = findObjectsIfNoPattern(options, conn, queries, hasPatternQueries); + Set found = findObjects(options, conn, queries, hasPatternQueries); Map numExpectedAttributes = findNumExpectedAttributes(conn, attributesInclude, hasPatternQueries, queries, found); @@ -113,8 +113,8 @@ public class JmxTool { } } - private static String mkString(Stream stream, String delimeter) { - return stream.filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(delimeter)); + private static String mkString(Stream stream, String delimiter) { + return stream.filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(delimiter)); } private static int sumValues(Map numExpectedAttributes) { @@ -162,26 +162,24 @@ public class JmxTool { return serverConn; } - private static Set findObjectsIfNoPattern(JmxToolOptions options, - MBeanServerConnection conn, - List queries, - boolean hasPatternQueries) throws Exception { + private static Set findObjects(JmxToolOptions options, + MBeanServerConnection conn, + List queries, + boolean hasPatternQueries) throws Exception { long waitTimeoutMs = 10_000; Set result = new HashSet<>(); Set querySet = new HashSet<>(queries); - BiPredicate, Set> foundAllObjects = (s1, s2) -> s1.containsAll(s2); - if (!hasPatternQueries) { - long start = System.currentTimeMillis(); - do { - if (!result.isEmpty()) { - System.err.println("Could not find all object names, retrying"); - TimeUnit.MILLISECONDS.sleep(100); - } - result.addAll(queryObjects(conn, queries)); - } while (options.hasWait() && System.currentTimeMillis() - start < waitTimeoutMs && !foundAllObjects.test(querySet, result)); - } + BiPredicate, Set> foundAllObjects = Set::containsAll; + long start = System.currentTimeMillis(); + do { + if (!result.isEmpty()) { + System.err.println("Could not find all object names, retrying"); + TimeUnit.MILLISECONDS.sleep(100); + } + result.addAll(queryObjects(conn, queries)); + } while (!hasPatternQueries && options.hasWait() && System.currentTimeMillis() - start < waitTimeoutMs && !foundAllObjects.test(querySet, result)); - if (options.hasWait() && !foundAllObjects.test(querySet, result)) { + if (!hasPatternQueries && options.hasWait() && !foundAllObjects.test(querySet, result)) { querySet.removeAll(result); String missing = mkString(querySet.stream().map(Object::toString), ","); throw new TerseException(String.format("Could not find all requested object names after %d ms. Missing %s", waitTimeoutMs, missing)); @@ -218,7 +216,7 @@ public class JmxTool { } }); } else { - if (!hasPatternQueries) { + if (hasPatternQueries) { found.forEach(objectName -> { try { MBeanInfo mBeanInfo = conn.getMBeanInfo(objectName); @@ -237,7 +235,7 @@ public class JmxTool { } }); } else { - queries.forEach(objectName -> result.put(objectName, attributesInclude.get().length)); + found.forEach(objectName -> result.put(objectName, attributesInclude.get().length)); } } diff --git a/tools/src/test/java/org/apache/kafka/tools/JmxToolTest.java b/tools/src/test/java/org/apache/kafka/tools/JmxToolTest.java index 8314d164058..674599edccb 100644 --- a/tools/src/test/java/org/apache/kafka/tools/JmxToolTest.java +++ b/tools/src/test/java/org/apache/kafka/tools/JmxToolTest.java @@ -174,6 +174,140 @@ public class JmxToolTest { assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); } + @Test + public void testDomainNamePattern() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.serve?:*", + "--attributes", "FifteenMinuteRate,FiveMinuteRate", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + public void testDomainNamePatternWithNoAttributes() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.serve?:*", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + public void testPropertyListPattern() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=BrokerTopicMetrics,*", + "--attributes", "FifteenMinuteRate,FiveMinuteRate", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + public void testPropertyListPatternWithNoAttributes() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=BrokerTopicMetrics,*", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + public void testPropertyValuePattern() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=BrokerTopicMetrics,name=*InPerSec", + "--attributes", "FifteenMinuteRate,FiveMinuteRate", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + public void testPropertyValuePatternWithNoAttributes() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=BrokerTopicMetrics,name=*InPerSec", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + // Combination of property-list and property-value patterns + public void testPropertyPattern() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=*,*", + "--attributes", "FifteenMinuteRate,FiveMinuteRate", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + + @Test + // Combination of property-list and property-value patterns + public void testPropertyPatternWithNoAttributes() { + String[] args = new String[]{ + "--jmx-url", jmxUrl, + "--object-name", "kafka.server:type=*,*", + "--report-format", "csv", + "--one-time" + }; + String out = executeAndGetOut(args); + assertNormalExit(); + + Map csv = parseCsv(out); + assertEquals("1.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FifteenMinuteRate")); + assertEquals("3.0", csv.get("kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec:FiveMinuteRate")); + } + @Test public void dateFormat() { String dateFormat = "yyyyMMdd-hh:mm:ss";