ARTEMIS-4169 Auto detect dead-letter and expiry queues in the console

This commit is contained in:
Domenico Francesco Bruscino 2023-02-15 13:20:27 +01:00 committed by Justin Bertram
parent 038d25064a
commit 648faf58cc
7 changed files with 113 additions and 81 deletions

View File

@ -209,26 +209,27 @@ var Artemis;
ctrl.allMessages = [];
ctrl.messages = [];
var objName;
ctrl.objName = '';
if (workspace.selection) {
objName = workspace.selection.objectName;
ctrl.objName = workspace.selection.objectName;
} else {
// in case of refresh
var key = location.search()['nid'];
var node = workspace.keyToNodeMap[key];
objName = node.objectName;
ctrl.objName = node.objectName;
}
var artemisDLQ = localStorage['artemisDLQ'] || "^DLQ$";
var artemisExpiryQueue = localStorage['artemisExpiryQueue'] || "^ExpiryQueue$";
Artemis.log.debug("loading table" + artemisExpiryQueue);
if (objName) {
ctrl.dlq = false;
var addressName = jolokia.getAttribute(objName, "Address");
if (addressName.match(artemisDLQ) != null || addressName.match(artemisExpiryQueue) != null) {
ctrl.dlq = true;
}
if (ctrl.objName) {
ctrl.addressName = jolokia.getAttribute(ctrl.objName, "Address");
Artemis.log.debug("addressName: " + ctrl.addressName);
}
ctrl.artemisDLQ = localStorage['artemisDLQ'] || "^DLQ$";
Artemis.log.debug("artemisDLQ: " + ctrl.artemisDLQ);
ctrl.artemisExpiryQueue = localStorage['artemisExpiryQueue'] || "^ExpiryQueue$";
Artemis.log.debug("artemisExpiryQueue: " + ctrl.artemisExpiryQueue);
ctrl.originalQueueColumn = { name: "Original Queue", visible: false };
ctrl.dtOptions = {
// turn of ordering as we do it ourselves
ordering: false,
@ -244,7 +245,8 @@ var Artemis;
{name: "Large", visible: true},
{name: "Persistent Size", visible: true},
{name: "User ID", visible: true},
{name: "Validated User", visible: false}
{name: "Validated User", visible: false},
ctrl.originalQueueColumn
]
};
@ -331,23 +333,17 @@ var Artemis;
if (!value) return undefined;
return value._AMQ_VALIDATED_USER;
}
}
];
if (ctrl.dlq) {
origQueue = {
},
{
itemField: 'StringProperties',
header: 'Original Queue',
templateFn: function(value) {
if (!value) return undefined;
return (value['_AMQ_ORIG_QUEUE'] ? value['_AMQ_ORIG_QUEUE'] : value['extraProperties._AMQ_ORIG_QUEUE']);
}
};
ctrl.tableColumns.push(origQueue);
}
ctrl.dtOptions.columns.push({name: "Original Queue", visible: true});
}
];
var resendConfig = {
name: 'Resend',
@ -684,7 +680,12 @@ var Artemis;
ctrl.allMessages = data;
}
idx = 0;
ctrl.dlq = ctrl.addressName.match(ctrl.artemisDLQ) != null ||
ctrl.addressName.match(ctrl.artemisExpiryQueue) != null;
angular.forEach(ctrl.allMessages, function(message) {
ctrl.dlq = ctrl.dlq || (message['StringProperties'] ? (message['StringProperties']['_AMQ_ORIG_QUEUE'] ? true : (message['StringProperties']['extraProperties._AMQ_ORIG_QUEUE'] ? true : false)) : false);
message.bodyText = createBodyText(message);
if (idx == 0 && !ctrl.loadPrevousPage) {
//always load n the first message for paination when viewing message details
@ -701,6 +702,7 @@ var Artemis;
message.idx = idx;
idx++;
});
ctrl.originalQueueColumn.visible = ctrl.dlq;
ctrl.messages = ctrl.allMessages;
ctrl.isLoading = false;
Core.$apply($scope);
@ -886,44 +888,20 @@ var Artemis;
ctrl.loadTable = function() {
Artemis.log.debug("loading table")
ctrl.dlq = false;
ctrl.isLoading = true;
var objName;
if (workspace.selection) {
objName = workspace.selection.objectName;
} else {
// in case of refresh
var key = location.search()['nid'];
var node = workspace.keyToNodeMap[key];
objName = node.objectName;
}
if (objName) {
ctrl.dlq = false;
var addressName = jolokia.getAttribute(objName, "Address");
var artemisDLQ = localStorage['artemisDLQ'] || "^DLQ$";
var artemisExpiryQueue = localStorage['artemisExpiryQueue'] || "^ExpiryQueue$";
Artemis.log.debug("loading table" + artemisExpiryQueue);
if (addressName.match(artemisDLQ) != null || addressName.match(artemisExpiryQueue) != null) {
onDlq(true);
} else {
onDlq(false);
}
if (ctrl.objName) {
//make sure to count only filtered messages
if (ctrl.filter) {
jolokia.request({ type: 'exec', mbean: objName, operation: 'countMessages(java.lang.String)', arguments: [ctrl.filter] }, Core.onSuccess(function(response) { ctrl.pagination.page(response.value); }));
jolokia.request({ type: 'exec', mbean: ctrl.objName, operation: 'countMessages(java.lang.String)', arguments: [ctrl.filter] }, Core.onSuccess(function(response) { ctrl.pagination.page(response.value); }));
} else {
jolokia.request({ type: 'exec', mbean: objName, operation: 'countMessages()'}, Core.onSuccess(function(response) { ctrl.pagination.page(response.value); }));
jolokia.request({ type: 'exec', mbean: ctrl.objName, operation: 'countMessages()'}, Core.onSuccess(function(response) { ctrl.pagination.page(response.value); }));
}
jolokia.request({ type: 'exec', mbean: objName, operation: 'browse(int, int, java.lang.String)', arguments: [ctrl.pagination.pageNumber, ctrl.pagination.pageSize, ctrl.filter] }, Core.onSuccess(populateTable));
jolokia.request({ type: 'exec', mbean: ctrl.objName, operation: 'browse(int, int, java.lang.String)', arguments: [ctrl.pagination.pageNumber, ctrl.pagination.pageSize, ctrl.filter] }, Core.onSuccess(populateTable));
}
}
function onDlq(response) {
Artemis.log.debug("onDLQ=" + response);
ctrl.dlq = response;
Core.$apply($scope);
}
function operationSuccess() {
ctrl.messageDialog = false;
Core.notification("success", ctrl.message);

View File

@ -114,16 +114,6 @@ var Artemis;
title=""
ng-click="$ctrl.reset()">Reset
</button>
<button ng-show="$ctrl.dlq" class="btn btn-default primary-action ng-binding ng-scope"
type="button"
title=""
ng-click="$ctrl.retry()">Retry Messages
</button>
<button ng-show="$ctrl.dlq" class="btn btn-default primary-action ng-binding ng-scope"
type="button"
title=""
ng-click="$ctrl.retry()">Move Messages
</button>
</div>
</form>
</div>

View File

@ -110,10 +110,33 @@ public class QueuesTest extends ConsoleTest {
}
@Test
public void testExpiryQueue() throws Exception {
final int messages = 1;
final String expiryQueueName = "ExpiryQueue";
final String testQueueName = "TEST";
public void testDefaultExpiryQueue() throws Exception {
testExpiryQueue("TEST", "ExpiryQueue");
}
@Test
public void testCustomExpiryQueue() throws Exception {
final ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(null, "0.0.0.0", true);
final ObjectName activeMQServerObjectName = objectNameBuilder.getActiveMQServerObjectName();
driver.get(serverUrl + "/console");
LoginPage loginPage = new LoginPage(driver);
StatusPage statusPage = loginPage.loginValidUser(
SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, DEFAULT_TIMEOUT);
Assert.assertTrue(statusPage.postJolokiaExecRequest(activeMQServerObjectName.getCanonicalName(),
"createQueue(java.lang.String,java.lang.String,java.lang.String)",
"\"foo\",\"foo\",\"ANYCAST\"").toString().contains("\"status\":200"));
Assert.assertTrue(statusPage.postJolokiaExecRequest(activeMQServerObjectName.getCanonicalName(),
"addAddressSettings(java.lang.String,java.lang.String,java.lang.String,long,boolean,int,long,int,int,long,double,long,long,boolean,java.lang.String,long,long,java.lang.String,boolean,boolean,boolean,boolean)",
"\"bar\",\"DLA\",\"foo\",-1,false,0,0,0,0,0,\"0\",0,0,false,\"\",-1,0,\"\",false,false,false,false").toString().contains("\"status\":200"));
statusPage.logout(DEFAULT_TIMEOUT);
testExpiryQueue("bar", "foo");
}
private void testExpiryQueue(String queueName, String expiryQueueName) throws Exception {
final String messageText = "TEST";
final ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(null, "0.0.0.0", true);
final ObjectName expiryQueueObjectName = objectNameBuilder.getQueueObjectName(
@ -121,8 +144,8 @@ public class QueuesTest extends ConsoleTest {
SimpleString.toSimpleString(expiryQueueName),
RoutingType.ANYCAST);
final ObjectName testQueueObjectName = objectNameBuilder.getQueueObjectName(
SimpleString.toSimpleString(testQueueName),
SimpleString.toSimpleString(testQueueName),
SimpleString.toSimpleString(queueName),
SimpleString.toSimpleString(queueName),
RoutingType.ANYCAST);
driver.get(serverUrl + "/console");
@ -133,14 +156,14 @@ public class QueuesTest extends ConsoleTest {
"removeAllMessages()", "").toString().contains("\"status\":200"));
QueuesPage beforeQueuesPage = statusPage.getQueuesPage(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue("ExpiryQueue"));
Wait.assertEquals(0, () -> beforeQueuesPage.countQueue(testQueueName));
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(expiryQueueName));
Wait.assertEquals(0, () -> beforeQueuesPage.countQueue(queueName));
Producer producer = new Producer();
producer.setUser(SERVER_ADMIN_USERNAME);
producer.setPassword(SERVER_ADMIN_PASSWORD);
producer.setDestination(testQueueName);
producer.setMessageCount(messages);
producer.setDestination(queueName);
producer.setMessageCount(1);
producer.setMessage(messageText);
producer.setSilentInput(true);
producer.setProtocol("amqp");
@ -149,21 +172,28 @@ public class QueuesTest extends ConsoleTest {
beforeQueuesPage.refresh(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(expiryQueueName));
assertEquals(0, beforeQueuesPage.getMessagesCount(expiryQueueName));
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(testQueueName));
assertEquals(messages, beforeQueuesPage.getMessagesCount(testQueueName));
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(queueName));
assertEquals(1, beforeQueuesPage.getMessagesCount(queueName));
QueuePage queuePage = beforeQueuesPage.getQueuePage(testQueueName, DEFAULT_TIMEOUT);
SendMessagePage sendMessagePage = beforeQueuesPage.getAddressSendMessagePage(queueName, DEFAULT_TIMEOUT);
sendMessagePage.appendMessageText("xxx");
sendMessagePage.sendMessage();
QueuePage queuePage = sendMessagePage.getQueuesPage(DEFAULT_TIMEOUT).getQueuePage(queueName, DEFAULT_TIMEOUT);
Assert.assertTrue(queuePage.postJolokiaExecRequest(testQueueObjectName.getCanonicalName(), "expireMessage(long)",
String.valueOf(queuePage.getMessageId(0))).toString().contains("\"status\":200"));
Assert.assertTrue(queuePage.postJolokiaExecRequest(testQueueObjectName.getCanonicalName(), "expireMessage(long)",
String.valueOf(queuePage.getMessageId(1))).toString().contains("\"status\":200"));
QueuesPage afterQueuesPage = queuePage.getQueuesPage(DEFAULT_TIMEOUT);
Wait.assertEquals(1, () -> afterQueuesPage.countQueue(expiryQueueName));
assertEquals(messages, afterQueuesPage.getMessagesCount(expiryQueueName));
Wait.assertEquals(1, () -> beforeQueuesPage.countQueue(testQueueName));
assertEquals(0, afterQueuesPage.getMessagesCount(testQueueName));
assertEquals(2, afterQueuesPage.getMessagesCount(expiryQueueName));
Wait.assertEquals(1, () -> afterQueuesPage.countQueue(queueName));
assertEquals(0, afterQueuesPage.getMessagesCount(queueName));
QueuePage dlqPage = afterQueuesPage.getQueuePage(expiryQueueName, DEFAULT_TIMEOUT);
assertEquals(testQueueName, dlqPage.getMessageOriginalQueue(0));
QueuePage expiryPage = afterQueuesPage.getQueuePage(expiryQueueName, DEFAULT_TIMEOUT);
assertEquals(queueName, expiryPage.getMessageOriginalQueue(0));
assertEquals(queueName, expiryPage.getMessageOriginalQueue(1));
}
@Test

View File

@ -57,6 +57,14 @@ public abstract class ArtemisPage extends ConsolePage {
return null;
}
public SendMessagePage getAddressSendMessagePage(String address, int timeout) {
driver.get(getServerUrl() + "/console/artemis/artemisAddressSendMessage?nid=root-org.apache.activemq.artemis-0.0.0.0-addresses-" + address);
waitForElementToBeVisible(By.xpath("//h1[contains(text(),'Send Message')]"), timeout);
return new SendMessagePage(driver);
}
public QueuesPage getQueuesPage(int timeout) {
WebElement queuesMenuItem = driver.findElement(queuesMenuItemLocator);
@ -77,6 +85,19 @@ public abstract class ArtemisPage extends ConsolePage {
return new QueuesPage(driver);
}
public LoginPage logout(int timeout) {
WebElement logoutWebElement = driver.findElement(logoutLocator);
WebElement userDropdownMenuWebElement = driver.findElement(userDropdownMenuLocator);
if (!logoutWebElement.isDisplayed()) {
userDropdownMenuWebElement.click();
}
logoutWebElement.click();
return new LoginPage(driver);
}
public Object postJolokiaExecRequest(String mbean, String operation, String arguments) {
Object response = ((JavascriptExecutor) driver).executeAsyncScript(
"var callback = arguments[arguments.length - 1];" +

View File

@ -16,6 +16,8 @@
*/
package org.apache.activemq.artemis.tests.smoke.console.pages;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.By;
@ -32,6 +34,15 @@ public abstract class ConsolePage {
this.driver = driver;
}
public String getServerUrl() {
try {
URL currentUrl = new URL(driver.getCurrentUrl());
return currentUrl.getProtocol() + "://" + currentUrl.getAuthority();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public void refresh(int timeout) {
driver.navigate().refresh();

View File

@ -23,7 +23,7 @@ import org.openqa.selenium.WebElement;
import java.util.List;
public class QueuePage extends ArtemisPage {
private By messageRowLocator = By.cssSelector("tr[role='row'][class='ng-scope odd']");
private By messageRowLocator = By.cssSelector("tr[role='row'][class]");
public QueuePage(WebDriver driver) {
super(driver);

View File

@ -69,5 +69,7 @@ public class SendMessagePage extends ArtemisPage {
public void sendMessage() {
driver.findElement(By.xpath("//button[contains(text(),'Send Message')]")).click();
driver.findElement(By.xpath("//button[@class='close']")).click();
}
}