From be09f2c86ebc0e1df8b40dc03c88a9319a09106f Mon Sep 17 00:00:00 2001 From: Pat Fox Date: Sun, 5 Nov 2017 14:03:58 +0100 Subject: [PATCH] ARTEMIS-1502 Added addressMemorySize, isPaging, numberOfPages, BytesPerPage to the address summary in the addresses panel in the web console --- .../src/main/webapp/plugin/js/addresses.js | 24 +++ .../impl/ActiveMQServerControlImpl.java | 6 +- .../management/impl/view/AddressView.java | 57 ++++++- .../predicate/AddressFilterPredicate.java | 27 +++- .../management/ActiveMQServerControlTest.java | 148 ++++++++++++++++++ 5 files changed, 248 insertions(+), 14 deletions(-) diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/addresses.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/addresses.js index fd535541f07..5e4af7ca7a9 100644 --- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/addresses.js +++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/addresses.js @@ -55,6 +55,26 @@ var ARTEMIS = (function(ARTEMIS) { field: 'queueCount', displayName: 'Queue Count', width: '*' + }, + { + field: 'addressMemorySize', + displayName: 'Memory Size', + width: '*' + }, + { + field: 'paging', + displayName: 'Paging', + width: '*' + }, + { + field: 'numberOfPages', + displayName: 'Number Of Pages', + width: '*' + }, + { + field: 'numberOfBytesPerPage', + displayName: 'Bytes Per Page', + width: '*' } ]; $scope.filter = { @@ -63,6 +83,10 @@ var ARTEMIS = (function(ARTEMIS) { {id: 'NAME', name: 'Name'}, {id: 'ROUTING_TYPES', name: 'Routing Types'}, {id: 'QUEUE_COUNT', name: 'Queue Count'}, + {id: 'ADDRESS_MEMORY_SIZE', name: 'Memory Size'}, + {id: 'PAGING', name: 'Paging'}, + {id: 'NUMBER_OF_PAGES', name: 'Number Of Pages'}, + {id: 'NUMBER_OF_BYTES_PER_PAGE', name: 'Bytes Per Page'} ], operationOptions: [ {id: 'EQUALS', name: 'Equals'}, diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java index a235a53689f..c374b5a809e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java @@ -1736,7 +1736,11 @@ public String listAddresses(String options, int page, int pageSize) throws Excep clearIO(); try { - final Set addresses = server.getPostOffice().getAddresses(); + List addresses = new ArrayList<>(); + Object[] addressControls = server.getManagementService().getResources(AddressControl.class); + for (int i = 0; i < addressControls.length; i++) { + addresses.add((AddressControl) addressControls[i]); + } AddressView view = new AddressView(server); view.setCollection(addresses); view.setOptions(options); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/AddressView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/AddressView.java index fcc34648e45..8837117d0df 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/AddressView.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/AddressView.java @@ -19,12 +19,16 @@ import javax.json.JsonObjectBuilder; import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.management.AddressControl; import org.apache.activemq.artemis.core.management.impl.view.predicate.AddressFilterPredicate; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.impl.AddressInfo; import org.apache.activemq.artemis.utils.JsonLoader; +import org.jboss.logging.Logger; -public class AddressView extends ActiveMQAbstractView { +public class AddressView extends ActiveMQAbstractView { + + private static final Logger logger = Logger.getLogger(AddressView.class); private static final String defaultSortColumn = "creationTime"; @@ -42,17 +46,56 @@ public Class getClassT() { } @Override - public JsonObjectBuilder toJson(SimpleString addressName) { + public JsonObjectBuilder toJson(AddressControl addressControl) { + + AddressInfo address = server.getAddressInfo(new SimpleString(addressControl.getAddress())); + JsonObjectBuilder obj = JsonLoader.createObjectBuilder().add("id", toString(address.getId())).add("name", addressControl.getAddress()).add("routingTypes", toString(address.getRoutingTypes())); + + try { + obj.add("queueCount", toString(addressControl.getQueueNames().length)); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("setting queueCount", e); + } + obj.add("queueCount", "0"); + } + + try { + obj.add("addressMemorySize", toString(addressControl.getAddressSize())); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("setting addressMemorySize", e); + } + obj.add("addressMemorySize", "0"); + } - AddressInfo address = server.getAddressInfo(addressName); - JsonObjectBuilder obj = JsonLoader.createObjectBuilder().add("id", toString(address.getId())).add("name", toString(address.getName())).add("routingTypes", toString(address.getRoutingTypes())); + try { + obj.add("paging", toString(addressControl.isPaging())); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("setting paging", e); + } + obj.add("paging", "false"); + } try { - obj.add("queueCount", toString(server.bindingQuery(address.getName()).getQueueNames().size())); - return obj; + obj.add("numberOfPages", toString(addressControl.getNumberOfPages())); } catch (Exception e) { - obj.add("queueCount", 0); + if (logger.isDebugEnabled()) { + logger.debug("setting numberOfPages", e); + } + obj.add("numberOfPages", "0"); } + + try { + obj.add("numberOfBytesPerPage", toString(addressControl.getNumberOfBytesPerPage())); + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("setting numberOfBytesPerPage", e); + } + obj.add("numberOfBytesPerPage", "0"); + } + return obj; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/AddressFilterPredicate.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/AddressFilterPredicate.java index 76e7c7124c6..688969567e7 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/AddressFilterPredicate.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/AddressFilterPredicate.java @@ -17,13 +17,14 @@ package org.apache.activemq.artemis.core.management.impl.view.predicate; import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.api.core.management.AddressControl; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.impl.AddressInfo; -public class AddressFilterPredicate extends ActiveMQFilterPredicate { +public class AddressFilterPredicate extends ActiveMQFilterPredicate { enum Field { - ID, NAME, ROUTING_TYPES, PRODUCER_ID, QUEUE_COUNT + ID, NAME, ROUTING_TYPES, PRODUCER_ID, QUEUE_COUNT, ADDRESS_MEMORY_SIZE, PAGING, NUMBER_OF_PAGES, NUMBER_OF_BYTES_PER_PAGE } private Field f; @@ -36,8 +37,14 @@ public AddressFilterPredicate(ActiveMQServer server) { } @Override - public boolean apply(SimpleString addressName) { - AddressInfo address = server.getAddressInfo(addressName); + public boolean apply(AddressControl addressControl) { + AddressInfo address = server.getAddressInfo(new SimpleString(addressControl.getAddress())); + + //should not happen but just in case... + if (address == null) { + return false; + } + if (f == null) return true; try { @@ -45,13 +52,21 @@ public boolean apply(SimpleString addressName) { case ID: return matches(address.getId()); case NAME: - return matches(address.getName()); + return matches(addressControl.getAddress()); case ROUTING_TYPES: return matchAny(address.getRoutingTypes()); case PRODUCER_ID: return matches("TODO"); case QUEUE_COUNT: - return matches(server.bindingQuery(address.getName()).getQueueNames().size()); + return matches(addressControl.getQueueNames().length); + case ADDRESS_MEMORY_SIZE: + return matches(addressControl.getAddressSize()); + case PAGING: + return matches(addressControl.isPaging()); + case NUMBER_OF_PAGES: + return matches(addressControl.getNumberOfPages()); + case NUMBER_OF_BYTES_PER_PAGE: + return matches(addressControl.getNumberOfBytesPerPage()); } } catch (Exception e) { return false; diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java index 8c2b6c25c19..116b1a339d8 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java @@ -67,6 +67,9 @@ import org.apache.activemq.artemis.core.server.ServerConsumer; import org.apache.activemq.artemis.core.server.ServerSession; import org.apache.activemq.artemis.core.server.impl.AddressInfo; +import org.apache.activemq.artemis.core.settings.HierarchicalRepository; +import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy; +import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.core.settings.impl.SlowConsumerPolicy; import org.apache.activemq.artemis.core.transaction.impl.XidImpl; import org.apache.activemq.artemis.jlibaio.LibaioContext; @@ -1794,6 +1797,8 @@ public void testListAddresses() throws Exception { Assert.assertEquals("number of addresses returned from query", 1, array.size()); Assert.assertEquals("address name check", addressName1.toString(), array.getJsonObject(0).getString("name")); + Assert.assertEquals("check if address is paging", "false", array.getJsonObject(0).getString("paging")); + Assert.assertEquals("check numberOfPages", "0", array.getJsonObject(0).getString("numberOfPages")); //test with empty filter - all addresses should be returned filterString = createJsonFilter("", "", ""); @@ -1829,6 +1834,149 @@ public void testListAddresses() throws Exception { } + @Test + public void testListAddressesFilteredByPaging() throws Exception { + SimpleString queueName1 = new SimpleString("my_queue_one"); + SimpleString queueName2 = new SimpleString("my_queue_two"); + SimpleString queueName3 = new SimpleString("other_queue_three"); + SimpleString queueName4 = new SimpleString("other_queue_four"); + + SimpleString addressName1 = new SimpleString("small.my_address_one"); + SimpleString addressName2 = new SimpleString("small.my_address_two"); + SimpleString addressName3 = new SimpleString("small.other_address_three"); + + ActiveMQServerControl serverControl = createManagementControl(); + + // add config for "small.*" to ensure paging kicks in. + AddressSettings addressSettings = new AddressSettings().setMaxSizeBytes(20480).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE).setPageSizeBytes(10240); + HierarchicalRepository repos = server.getAddressSettingsRepository(); + repos.addMatch("small.*", addressSettings); + + server.addAddressInfo(new AddressInfo(addressName1, RoutingType.ANYCAST)); + server.createQueue(addressName1, RoutingType.ANYCAST, queueName1, null, false, false); + server.addAddressInfo(new AddressInfo(addressName2, RoutingType.ANYCAST)); + server.createQueue(addressName2, RoutingType.ANYCAST, queueName2, null, false, false); + server.addAddressInfo(new AddressInfo(addressName3, RoutingType.ANYCAST)); + server.createQueue(addressName3, RoutingType.ANYCAST, queueName3, null, false, false); + server.createQueue(addressName3, RoutingType.ANYCAST, queueName4, null, false, false); + + //test addresses are NOT paging + String filterString = createJsonFilter("paging", "EQUALS", "false"); + String addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + JsonObject addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + JsonArray array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertTrue("number of addresses NOT paging", 3 <= array.size()); + //check the first value for consistency + Assert.assertEquals("address paging value", "false", array.getJsonObject(0).getString("paging")); + Assert.assertEquals("address number of pages", "0", array.getJsonObject(0).getString("numberOfPages")); + + //send messages to address1 + try (ServerLocator locator = createInVMNonHALocator(); ClientSessionFactory csf = createSessionFactory(locator); ClientSession session = csf.createSession()) { + ClientProducer producer1 = session.createProducer(addressName1); + //send 25KiB + sendMessagesWithPredefinedSize(25, session, producer1, 1024); + } + + //test to ensure one address is paging + filterString = createJsonFilter("paging", "EQUALS", "true"); + addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("number of addresses paging", 1, array.size()); + Assert.assertEquals("address paging name check", addressName1.toString(), array.getJsonObject(0).getString("name")); + Assert.assertEquals("address paging value", "true", array.getJsonObject(0).getString("paging")); + Assert.assertEquals("address number of pages", "2", array.getJsonObject(0).getString("numberOfPages")); + //10 KiB + Assert.assertEquals("address number of bytes per page", "10240", array.getJsonObject(0).getString("numberOfBytesPerPage")); + + //ensure one address returned when filtered by "numberOfPages" + filterString = createJsonFilter("number_of_pages", "GREATER_THAN", "0"); + addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("number of addresses paging", 1, array.size()); + Assert.assertEquals("address paging name check", addressName1.toString(), array.getJsonObject(0).getString("name")); + Assert.assertEquals("address paging value", "true", array.getJsonObject(0).getString("paging")); + Assert.assertEquals("address number of pages", "2", array.getJsonObject(0).getString("numberOfPages")); + //10 KiB + Assert.assertEquals("address number of bytes per page", "10240", array.getJsonObject(0).getString("numberOfBytesPerPage")); + + //ensure correct addresss returned when filtered by "numberOfBytesPerPage" + filterString = createJsonFilter("number_of_bytes_per_page", "EQUALS", "10240"); + addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("number of addresses paging", 3, array.size()); + Assert.assertTrue("address name check", array.getJsonObject(0).getString("name").startsWith("small.")); + Assert.assertTrue("address name check", array.getJsonObject(1).getString("name").startsWith("small.")); + Assert.assertTrue("address name check", array.getJsonObject(2).getString("name").startsWith("small.")); + } + + @Test + public void testListAddressesFilteredByMemorySize() throws Exception { + SimpleString queueName1 = new SimpleString("my_queue_one"); + SimpleString queueName2 = new SimpleString("my_queue_two"); + SimpleString queueName3 = new SimpleString("other_queue_three"); + + SimpleString addressName1 = new SimpleString("my_address_one"); + SimpleString addressName2 = new SimpleString("my_address_two"); + SimpleString addressName3 = new SimpleString("other_address_three"); + + ActiveMQServerControl serverControl = createManagementControl(); + + server.addAddressInfo(new AddressInfo(addressName1, RoutingType.ANYCAST)); + server.createQueue(addressName1, RoutingType.ANYCAST, queueName1, null, false, false); + server.addAddressInfo(new AddressInfo(addressName2, RoutingType.ANYCAST)); + server.createQueue(addressName2, RoutingType.ANYCAST, queueName2, null, false, false); + server.addAddressInfo(new AddressInfo(addressName3, RoutingType.ANYCAST)); + server.createQueue(addressName3, RoutingType.ANYCAST, queueName3, null, false, false); + + //test addresses are not using any memory before messages sent + String filterString = createJsonFilter("address_Memory_Size", "GREATER_THAN", "0"); + String addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + JsonObject addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + JsonArray array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("address before messages sent", 0, array.size()); + + //send messages to address1 & address2 + try (ServerLocator locator = createInVMNonHALocator(); ClientSessionFactory csf = createSessionFactory(locator); ClientSession session = csf.createSession()) { + ClientProducer producer1 = session.createProducer(addressName1); + //send more than 10KiB + sendMessagesWithPredefinedSize(11, session, producer1, 1024); + + ClientProducer producer2 = session.createProducer(addressName2); + //send more than 20KiB + sendMessagesWithPredefinedSize(21, session, producer2, 1024); + } + + //test to ensure two address is using more than X bytes + filterString = createJsonFilter("address_Memory_Size", "GREATER_THAN", "10000"); + addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("number of addresses paging", 2, array.size()); + Assert.assertTrue("address name check", array.getJsonObject(0).getString("name").startsWith("my_address")); + Assert.assertTrue("address name check", array.getJsonObject(1).getString("name").startsWith("my_address")); + + //test to ensure one address is using more than X bytes + filterString = createJsonFilter("address_Memory_Size", "GREATER_THAN", "20000"); + addressesAsJsonString = serverControl.listAddresses(filterString, 1, 50); + addressesAsJsonObject = JsonUtil.readJsonObject(addressesAsJsonString); + array = (JsonArray) addressesAsJsonObject.get("data"); + + Assert.assertEquals("number of addresses paging", 1, array.size()); + Assert.assertEquals("address with highest memory size", addressName2.toString(), array.getJsonObject(0).getString("name")); + + // memory_size > 20 KiB + Assert.assertTrue("address memory Size", 20480 < Long.parseLong(array.getJsonObject(0).getString("addressMemorySize"))); + } + @Test public void testListConsumers() throws Exception { SimpleString queueName1 = new SimpleString("my_queue_one");