From 21b58bfea84c984fd2065abdbd3fcb05dba23b54 Mon Sep 17 00:00:00 2001 From: Stanislav Knot Date: Thu, 4 Jan 2018 16:25:46 +0100 Subject: [PATCH] ARTEMIS-1579 browsing messages in hawtio console --- .../api/core/management/QueueControl.java | 10 ++-- .../src/main/webapp/plugin/js/browse.js | 21 ++++++++- .../management/impl/QueueControlImpl.java | 46 +++++++++++++++++++ .../management/QueueControlUsingCoreTest.java | 15 ++++++ 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java index d678977032..9eec8e0130 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java @@ -223,6 +223,9 @@ public interface QueueControl { @Operation(desc = "Returns the number of the messages in the queue matching the given filter", impact = MBeanOperationInfo.INFO) long countMessages(@Parameter(name = "filter", desc = "A message filter (can be empty)") String filter) throws Exception; + @Operation(desc = "Returns the number of the messages in the queue", impact = MBeanOperationInfo.INFO) + long countMessages() throws Exception; + /** * Removes the message corresponding to the specified message ID. * @@ -464,12 +467,13 @@ public interface QueueControl { @Operation(desc = "Browse Messages", impact = MBeanOperationInfo.ACTION) CompositeData[] browse() throws Exception; - /** - * Resets the MessagesAdded property - */ @Operation(desc = "Browse Messages", impact = MBeanOperationInfo.ACTION) CompositeData[] browse(@Parameter(name = "filter", desc = "A message filter (can be empty)") String filter) throws Exception; + @Operation(desc = "Browse Messages", impact = MBeanOperationInfo.ACTION) + CompositeData[] browse(@Parameter(name = "page", desc = "Current page") int page, + @Parameter(name = "pageSize", desc = "Page size") int pageSize) throws Exception; + /** * Resets the MessagesAdded property */ diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/browse.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/browse.js index 7e06b1722c..a58d9eb2c9 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/browse.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/browse.js @@ -20,6 +20,12 @@ var ARTEMIS = (function(ARTEMIS) { ARTEMIS.BrowseQueueController = function ($scope, workspace, ARTEMISService, jolokia, localStorage, artemisMessage, $location, $timeout) { + $scope.pagingOptions = { + pageSizes: [50, 100, 200], + pageSize: 100, + currentPage: 1 + }; + $scope.totalServerItems = 0; $scope.searchText = ''; $scope.allMessages = []; $scope.messages = []; @@ -28,6 +34,10 @@ var ARTEMIS = (function(ARTEMIS) { $scope.deleteDialog = false; $scope.moveDialog = false; $scope.gridOptions = { + pagingOptions: $scope.pagingOptions, + enablePaging: true, + totalServerItems: 'totalServerItems', + showFooter: true, selectedItems: [], data: 'messages', displayFooter: false, @@ -102,6 +112,14 @@ var ARTEMIS = (function(ARTEMIS) { $scope.$watch('gridOptions.filterOptions.filterText', function (filterText) { filterMessages(filterText); }); + $scope.$watch('pagingOptions', function (newVal, oldVal) { + if (parseInt(newVal.currentPage) && newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) { + loadTable(); + } + if (parseInt(newVal.pageSize) && newVal !== oldVal && newVal.pageSize !== oldVal.pageSize) { + $scope.pagingOptions.currentPage = 1; + } + }, true); $scope.openMessageDialog = function (message) { ARTEMIS.selectCurrentMessage(message, "messageID", $scope); if ($scope.row) { @@ -362,7 +380,8 @@ var ARTEMIS = (function(ARTEMIS) { else { onDlq(false); } - ARTEMISService.artemisConsole.browse(objName, jolokia, onSuccess(populateTable)); + jolokia.request({ type: 'exec', mbean: objName, operation: 'countMessages()'}, onSuccess(function(response) {$scope.totalServerItems = response.value;})); + jolokia.request({ type: 'exec', mbean: objName, operation: 'browse(int, int)', arguments: [$scope.pagingOptions.currentPage, $scope.pagingOptions.pageSize] }, onSuccess(populateTable)); } } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java index 6f75297499..9f051fd99e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java @@ -544,6 +544,11 @@ public class QueueControlImpl extends AbstractControl implements QueueControl { return now - firstMessageTimestamp.longValue(); } + @Override + public long countMessages() throws Exception { + return countMessages(null); + } + @Override public long countMessages(final String filterStr) throws Exception { checkStarted(); @@ -960,6 +965,47 @@ public class QueueControlImpl extends AbstractControl implements QueueControl { } } + @Override + public CompositeData[] browse(int page, int pageSize) throws Exception { + String filter = null; + checkStarted(); + + clearIO(); + try { + long index = 0; + long start = (page - 1) * pageSize; + long end = Math.min((long)(page * pageSize), queue.getMessageCount()); + + ArrayList c = new ArrayList<>(); + Filter thefilter = FilterImpl.createFilter(filter); + queue.flushExecutor(); + + try (LinkedListIterator iterator = queue.browserIterator()) { + try { + while (iterator.hasNext() && index < end) { + MessageReference ref = iterator.next(); + if (thefilter == null || thefilter.match(ref.getMessage())) { + if (index >= start) { + c.add(OpenTypeSupport.convert(ref)); + } + } + index++; + } + } catch (NoSuchElementException ignored) { + // this could happen through paging browsing + } + + CompositeData[] rc = new CompositeData[c.size()]; + c.toArray(rc); + return rc; + } + } catch (ActiveMQException e) { + throw new IllegalStateException(e.getMessage()); + } finally { + blockOnIO(); + } + } + @Override public CompositeData[] browse() throws Exception { return browse(null); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java index 3ea65ccc5b..82c7a472cc 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java @@ -56,6 +56,11 @@ public class QueueControlUsingCoreTest extends QueueControlTest { return (Long) proxy.invokeOperation(Long.class, "countMessages", filter); } + @Override + public long countMessages() throws Exception { + return (Long) proxy.invokeOperation(Long.class, "countMessages"); + } + @Override public boolean expireMessage(final long messageID) throws Exception { return (Boolean) proxy.invokeOperation("expireMessage", messageID); @@ -385,6 +390,16 @@ public class QueueControlUsingCoreTest extends QueueControlTest { return compositeDatas; } + @Override + public CompositeData[] browse(int page, int pageSize) throws Exception { + Map map = (Map) proxy.invokeOperation("browse", page, pageSize); + CompositeData[] compositeDatas = (CompositeData[]) map.get(CompositeData.class.getName()); + if (compositeDatas == null) { + compositeDatas = new CompositeData[0]; + } + return compositeDatas; + } + @Override public CompositeData[] browse(String filter) throws Exception {