ARTEMIS-4762 NPE when running 'artemis queue stat' against older server

This commit is contained in:
Clebert Suconic 2024-05-06 15:10:09 -04:00 committed by clebertsuconic
parent eac816f6bd
commit f9e2f09207
3 changed files with 118 additions and 3 deletions

View File

@ -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 the queue name OR using a full filter '--field NAME --operation EQUALS --value X'.")
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);
}

View File

@ -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())

View File

@ -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) {
}
}
}
}