This is an automated email from the ASF dual-hosted git repository. clebertsuconic pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
commit f9e2f0920766633b6bd85cbc4248db14f09198d5 Author: Clebert Suconic <[email protected]> AuthorDate: Mon May 6 15:10:09 2024 -0400 ARTEMIS-4762 NPE when running 'artemis queue stat' against older server --- .../artemis/cli/commands/queue/StatQueue.java | 18 ++++- .../resources/CliFunctionTest/testQueueStat.groovy | 24 +++++++ .../tests/compatibility/CLIFunctionTest.java | 79 ++++++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/StatQueue.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/StatQueue.java index 935d19b926..3f6d1175c1 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/StatQueue.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/queue/StatQueue.java @@ -38,6 +38,8 @@ import picocli.CommandLine.Option; @Command(name = "stat", description = "Print basic stats of a queue. Output includes CONSUMER_COUNT (number of consumers), MESSAGE_COUNT (current message count on the queue, including scheduled, paged and in-delivery messages), MESSAGES_ADDED (messages added to the queue), DELIVERING_COUNT (messages broker is currently delivering to consumer(s)), MESSAGES_ACKED (messages acknowledged from the consumer(s))." + " Queues can be filtered using EITHER '--queueName X' where X is contained in t [...] public class StatQueue extends ConnectionAbstract { + private static final String NOT_APPLICABLE = ""; + private static final String MANAGEMENT_QUEUE = "activemq.management"; public enum FIELD { @@ -290,8 +292,14 @@ public class StatQueue extends ConnectionAbstract { return; } for (FIELD e: FIELD.values()) { - if (jsonObject.getString(e.jsonId).length() > columnSizes[i]) { - columnSizes[i] = jsonObject.getString(e.jsonId).length(); + if (jsonObject.containsKey(e.jsonId)) { + if (jsonObject.getString(e.jsonId).length() > columnSizes[i]) { + columnSizes[i] = jsonObject.getString(e.jsonId).length(); + } + } else { + if (NOT_APPLICABLE.length() > columnSizes[i]) { + columnSizes[i] = NOT_APPLICABLE.length(); + } } // enforce max if (columnSizes[i] > maxColumnSize && maxColumnSize != -1) { @@ -325,7 +333,11 @@ public class StatQueue extends ConnectionAbstract { int i = 0; String[] columns = new String[columnSizes.length]; for (FIELD e: FIELD.values()) { - columns[i++] = jsonObject.getString(e.jsonId); + if (!jsonObject.containsKey(e.jsonId)) { + columns[i++] = NOT_APPLICABLE; + } else { + columns[i++] = jsonObject.getString(e.jsonId); + } } tableOut.print(getActionContext().out, columns, center); } diff --git a/tests/compatibility-tests/src/main/resources/CliFunctionTest/testQueueStat.groovy b/tests/compatibility-tests/src/main/resources/CliFunctionTest/testQueueStat.groovy new file mode 100644 index 0000000000..0c1a445f4a --- /dev/null +++ b/tests/compatibility-tests/src/main/resources/CliFunctionTest/testQueueStat.groovy @@ -0,0 +1,24 @@ +/* + * 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. + */ + +import org.apache.activemq.artemis.cli.commands.ActionContext +import org.apache.activemq.artemis.cli.commands.Run +import org.apache.activemq.artemis.cli.commands.queue.StatQueue + +Run.setEmbedded(true) +StatQueue statQueue = new StatQueue() +statQueue.execute(new ActionContext()) diff --git a/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/CLIFunctionTest.java b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/CLIFunctionTest.java new file mode 100644 index 0000000000..4ba969902e --- /dev/null +++ b/tests/compatibility-tests/src/test/java/org/apache/activemq/artemis/tests/compatibility/CLIFunctionTest.java @@ -0,0 +1,79 @@ +/* + * 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.activemq.artemis.tests.compatibility; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.activemq.artemis.tests.compatibility.base.ClasspathBase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.SNAPSHOT; +import static org.apache.activemq.artemis.tests.compatibility.GroovyRun.TWO_TWENTYEIGHT_ZERO; + +@RunWith(Parameterized.class) +public class CLIFunctionTest extends ClasspathBase { + + private final ClassLoader serverClassloader; + + private final ClassLoader clientClassloader; + + + @Parameterized.Parameters(name = "Server={0}, Client={1}") + public static Collection getParameters() { + List<Object[]> combinations = new ArrayList<>(); + combinations.add(new Object[]{TWO_TWENTYEIGHT_ZERO, SNAPSHOT}); + combinations.add(new Object[]{SNAPSHOT, TWO_TWENTYEIGHT_ZERO}); + // this is to validate the test + combinations.add(new Object[]{SNAPSHOT, SNAPSHOT}); + return combinations; + } + + + public CLIFunctionTest(String server, String client) throws Exception { + this.serverClassloader = getClasspath(server); + + this.clientClassloader = getClasspath(client); + } + + + @Test + public void testQueueStat() throws Throwable { + try { + setVariable(serverClassloader, "persistent", Boolean.TRUE); + startServer(serverFolder.getRoot(), serverClassloader, "server", null, + false, "servers/artemisServer.groovy", + "ARTEMIS", "ARTEMIS", "ARTEMIS"); + + + evaluate(clientClassloader, "CliFunctionTest/testQueueStat.groovy"); + + } finally { + try { + stopServer(serverClassloader); + } catch (Throwable ignored) { + } + } + + } + + +}
