This is an automated email from the ASF dual-hosted git repository. vavrtom pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-broker-j.git
The following commit(s) were added to refs/heads/main by this push: new 8941b2ad40 QPID-8683 - [Broker-J] Broker GUI should reflect producer information (#256) 8941b2ad40 is described below commit 8941b2ad40e5ae2477872ed05ebdc54469c35625 Author: Daniil Kirilyuk <daniel.kiril...@gmail.com> AuthorDate: Tue Feb 18 08:25:16 2025 +0100 QPID-8683 - [Broker-J] Broker GUI should reflect producer information (#256) --- .../org/apache/qpid/server/model/Producer.java | 7 ++ .../org/apache/qpid/server/model/ProducerImpl.java | 25 ++++++- .../resources/js/qpid/management/Connection.js | 87 ++++++++++++++++++++++ .../java/resources/js/qpid/management/Exchange.js | 83 +++++++++++++++++++++ .../java/resources/js/qpid/management/Queue.js | 83 +++++++++++++++++++++ .../src/main/java/resources/showConnection.html | 3 + .../src/main/java/resources/showExchange.html | 4 + .../src/main/java/resources/showQueue.html | 4 + 8 files changed, 295 insertions(+), 1 deletion(-) diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java b/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java index f00f8c1bd1..75f7636fb9 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java +++ b/broker-core/src/main/java/org/apache/qpid/server/model/Producer.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.model; +import java.util.UUID; + import com.google.common.util.concurrent.ListenableFuture; @ManagedObject(creatable = false, amqpName = "org.apache.qpid.Producer") @@ -48,6 +50,11 @@ public interface Producer<X extends Producer<X>> extends ConfiguredObject<X> void setDestination(String destination); + @DerivedAttribute(description = "Destination id") + UUID getDestinationId(); + + void setDestinationId(UUID destinationId); + @DerivedAttribute(description = "DeliveryType type (standard or delayed)") DeliveryType getDeliveryType(); diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java b/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java index 60b00e33db..26a8b70ebc 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java +++ b/broker-core/src/main/java/org/apache/qpid/server/model/ProducerImpl.java @@ -56,6 +56,8 @@ public class ProducerImpl<X extends Producer<X>> private String _destination; + private UUID _destinationId; + public ProducerImpl(final AbstractAMQPSession<?, ?> session, final PublishingLink publishingLink, final MessageDestination messageDestination) @@ -74,7 +76,16 @@ public class ProducerImpl<X extends Producer<X>> else { _deliveryType = DeliveryType.STANDARD_DELIVERY; - _destinationType = messageDestination instanceof Exchange ? DestinationType.EXCHANGE : DestinationType.QUEUE; + if (messageDestination instanceof Exchange) + { + _destinationId = ((Exchange<?>) messageDestination).getId(); + _destinationType = DestinationType.EXCHANGE; + } + else if (messageDestination instanceof Queue) + { + _destinationId = ((Queue<?>) messageDestination).getId(); + _destinationType = DestinationType.QUEUE; + } } registerWithParents(); @@ -149,6 +160,18 @@ public class ProducerImpl<X extends Producer<X>> _destination = destination; } + @Override + public UUID getDestinationId() + { + return _destinationId; + } + + @Override + public void setDestinationId(UUID destinationId) + { + _destinationId = destinationId; + } + @Override public DestinationType getDestinationType() { diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js index 58f49f24ee..617e115831 100644 --- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js +++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Connection.js @@ -132,6 +132,7 @@ define(["dojo/parser", "transport", "protocol", "remoteProcessPid", + "remoteAddress", "createdTime", "transportInfo", "transportInfoContainer", @@ -212,12 +213,59 @@ define(["dojo/parser", })); this.consumersGrid.startup(); + this.producersGrid = new QueryGrid({ + detectChanges: true, + rowsPerPage: 10, + transformer: lang.hitch(this, this._transformProducerData), + management: this.management, + parentObject: this.modelObj, + category: "Producer", + selectClause: "id, name, deliveryType, destinationType, destination, destinationId, messagesOut, bytesOut", + where: "to_string($parent.$parent.id) = '" + this.modelObj.id + "'", + orderBy: "name", + columns: [{ + label: "Name", + field: "name" + }, { + label: "Delivery Type", + field: "deliveryType" + }, { + label: "Destination Type", + field: "destinationType" + }, { + label: "Destination Name", + field: "destination" + }, { + label: "Msgs Out", + field: "messagesOut" + }, { + label: "Bytes Out", + field: "bytesOut", + formatter: formatter.formatBytes + }, { + label: "Msgs Rate", + field: "msgOutRate" + }, { + label: "Bytes Rate", + field: "bytesOutRate" + } + ] + }, findNode("producers")); + + this.producersGrid.on('rowBrowsed', lang.hitch(this, function(event) + { + const destinationId = this.producersGrid.row(event.id).data.destinationId; + this.controller.showById(destinationId); + })); + this.producersGrid.startup(); + // Add onShow handler to work around an issue with not rendering of grid columns before first update. // It seems if dgrid is created when tab is not shown (not active) the grid columns are not rendered. this.contentPane.on("show", lang.hitch(this, function() { this.consumersGrid.resize(); + this.producersGrid.resize(); this.sessionsGrid.resize(); })); } @@ -256,6 +304,7 @@ define(["dojo/parser", this.connectionStatistics.update(this.connectionData.statistics); this.connectionStatistics.resize(); this.consumersGrid.updateData(); + this.producersGrid.updateData(); this.sessionsGrid.updateData(); }), lang.hitch(this, function (error) { @@ -332,5 +381,43 @@ define(["dojo/parser", return consumers; }; + ConnectionUpdater.prototype._transformProducerData = function (data) + { + const sampleTime = new Date(); + const producers = util.queryResultToObjects(data); + if (this._previousProducerSampleTime) + { + const samplePeriod = sampleTime.getTime() - this._previousProducerSampleTime.getTime(); + for (let i = 0; i < producers.length; i++) + { + const producer = producers[i]; + let oldProducer = null; + for (let j = 0; j < this._previousProducers.length; j++) + { + if (this._previousProducers[j].id === producer.id) + { + oldProducer = this._previousProducers[j]; + break; + } + } + let msgOutRate = 0; + let bytesOutRate = 0; + + if (oldProducer) + { + msgOutRate = (1000 * (producer.messagesOut - oldProducer.messagesOut)) / samplePeriod; + bytesOutRate = (1000 * (producer.bytesOut - oldProducer.bytesOut)) / samplePeriod; + } + + producer.msgOutRate = msgOutRate.toFixed(0) + " msg/s"; + const bytesOutRateFormat = formatter.formatBytes(bytesOutRate); + producer.bytesOutRate = bytesOutRateFormat.value + " " + bytesOutRateFormat.units + "/s"; + } + } + this._previousProducerSampleTime = sampleTime; + this._previousProducers = producers; + return producers; + }; + return Connection; }); diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js index 9d9e04cc93..d056093d2a 100644 --- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js +++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js @@ -35,6 +35,7 @@ define(["dojo/_base/xhr", "qpid/management/addBinding", "qpid/management/addExchange", "dojox/grid/EnhancedGrid", + "qpid/management/query/QueryGrid", "dojox/html/entities", "dojo/text!showExchange.html", "qpid/common/StatisticsWidget", @@ -56,6 +57,7 @@ define(["dojo/_base/xhr", addBinding, addExchange, EnhancedGrid, + QueryGrid, entities, template, StatisticsWidget) @@ -248,6 +250,47 @@ define(["dojo/_base/xhr", } }, EnhancedGrid); + + this.producersGrid = new QueryGrid({ + detectChanges: true, + rowsPerPage: 10, + transformer: lang.hitch(this, this._transformProducerData), + management: this.management, + parentObject: this.modelObj, + category: "Producer", + selectClause: "id, name, deliveryType, destinationType, destination, destinationId, messagesOut, bytesOut", + where: "to_string(destinationId) = '" + this.modelObj.id + "'", + orderBy: "name", + columns: [{ + label: "Name", + field: "name" + }, { + label: "Delivery Type", + field: "deliveryType" + }, { + label: "Destination Type", + field: "destinationType" + }, { + label: "Destination Name", + field: "destination" + }, { + label: "Msgs Out", + field: "messagesOut" + }, { + label: "Bytes Out", + field: "bytesOut", + formatter: formatter.formatBytes + }, { + label: "Msgs Rate", + field: "msgOutRate" + }, { + label: "Bytes Rate", + field: "bytesOutRate" + } + ] + }, findNode("producers")); + + this.producersGrid.startup(); } ExchangeUpdater.prototype.updateHeader = function () @@ -317,6 +360,8 @@ define(["dojo/_base/xhr", thisObj.bindingsGrid.grid.endUpdate() } + thisObj.producersGrid.updateData(); + }, function (error) { util.tabErrorHandler(error, { @@ -344,5 +389,43 @@ define(["dojo/_base/xhr", } }; + ExchangeUpdater.prototype._transformProducerData = function (data) + { + const sampleTime = new Date(); + const producers = util.queryResultToObjects(data); + if (this._previousProducerSampleTime) + { + const samplePeriod = sampleTime.getTime() - this._previousProducerSampleTime.getTime(); + for (let i = 0; i < producers.length; i++) + { + const producer = producers[i]; + let oldProducer = null; + for (let j = 0; j < this._previousProducers.length; j++) + { + if (this._previousProducers[j].id === producer.id) + { + oldProducer = this._previousProducers[j]; + break; + } + } + let msgOutRate = 0; + let bytesOutRate = 0; + + if (oldProducer) + { + msgOutRate = (1000 * (producer.messagesOut - oldProducer.messagesOut)) / samplePeriod; + bytesOutRate = (1000 * (producer.bytesOut - oldProducer.bytesOut)) / samplePeriod; + } + + producer.msgOutRate = msgOutRate.toFixed(0) + " msg/s"; + const bytesOutRateFormat = formatter.formatBytes(bytesOutRate); + producer.bytesOutRate = bytesOutRateFormat.value + " " + bytesOutRateFormat.units + "/s"; + } + } + this._previousProducerSampleTime = sampleTime; + this._previousProducers = producers; + return producers; + }; + return Exchange; }); diff --git a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js index 22b63d1606..591ce6e914 100644 --- a/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js +++ b/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js @@ -398,12 +398,54 @@ define(["dojo/_base/declare", })); this.consumersGrid.startup(); + this.producersGrid = new QueryGrid({ + detectChanges: true, + rowsPerPage: 10, + transformer: lang.hitch(this, this._transformProducerData), + management: this.management, + parentObject: this.modelObj, + category: "Producer", + selectClause: "id, name, deliveryType, destinationType, destination, destinationId, messagesOut, bytesOut", + where: "to_string(destinationId) = '" + this.modelObj.id + "'", + orderBy: "name", + columns: [{ + label: "Name", + field: "name" + }, { + label: "Delivery Type", + field: "deliveryType" + }, { + label: "Destination Type", + field: "destinationType" + }, { + label: "Destination Name", + field: "destination" + }, { + label: "Msgs Out", + field: "messagesOut" + }, { + label: "Bytes Out", + field: "bytesOut", + formatter: formatter.formatBytes + }, { + label: "Msgs Rate", + field: "msgOutRate" + }, { + label: "Bytes Rate", + field: "bytesOutRate" + } + ] + }, findNode("producers")); + + this.producersGrid.startup(); + // Add onShow handler to work around an issue with not rendering of grid columns before first update. // It seems if dgrid is created when tab is not shown (not active) the grid columns are not rendered. this.contentPane.on("show", function() { that.consumersGrid.resize(); + that.producersGrid.resize(); }); this._messagesGrid = this._buildMessagesGrid(findNode); @@ -658,6 +700,9 @@ define(["dojo/_base/declare", thisObj.consumersGrid.updateData(); thisObj.consumersGrid.resize(); + thisObj.producersGrid.updateData(); + thisObj.producersGrid.resize(); + var queuePromise = this.management.load(this.modelObj, {excludeInheritedContext: true, depth: 1 }); var publishingLinkPromise = this.management.load({type: "queue", name: "getPublishingLinks", parent: this.modelObj}); @@ -775,6 +820,44 @@ define(["dojo/_base/declare", return consumers; }; + QueueUpdater.prototype._transformProducerData = function (data) + { + const sampleTime = new Date(); + const producers = util.queryResultToObjects(data); + if (this._previousProducerSampleTime) + { + const samplePeriod = sampleTime.getTime() - this._previousProducerSampleTime.getTime(); + for (let i = 0; i < producers.length; i++) + { + const producer = producers[i]; + let oldProducer = null; + for (let j = 0; j < this._previousProducers.length; j++) + { + if (this._previousProducers[j].id === producer.id) + { + oldProducer = this._previousProducers[j]; + break; + } + } + let msgOutRate = 0; + let bytesOutRate = 0; + + if (oldProducer) + { + msgOutRate = (1000 * (producer.messagesOut - oldProducer.messagesOut)) / samplePeriod; + bytesOutRate = (1000 * (producer.bytesOut - oldProducer.bytesOut)) / samplePeriod; + } + + producer.msgOutRate = msgOutRate.toFixed(0) + " msg/s"; + const bytesOutRateFormat = formatter.formatBytes(bytesOutRate); + producer.bytesOutRate = bytesOutRateFormat.value + " " + bytesOutRateFormat.units + "/s"; + } + } + this._previousProducerSampleTime = sampleTime; + this._previousProducers = producers; + return producers; + }; + Queue.prototype.deleteQueue = function () { if (confirm("Are you sure you want to delete queue '" + this.name + "'?")) diff --git a/broker-plugins/management-http/src/main/java/resources/showConnection.html b/broker-plugins/management-http/src/main/java/resources/showConnection.html index 6b31eb391f..0f0a8776e3 100644 --- a/broker-plugins/management-http/src/main/java/resources/showConnection.html +++ b/broker-plugins/management-http/src/main/java/resources/showConnection.html @@ -90,5 +90,8 @@ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Consumers'" class="connectionConsumers"> <div class="consumers"></div> </div> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Producers'" class="connectionProducers"> + <div class="producers"></div> + </div> </div> diff --git a/broker-plugins/management-http/src/main/java/resources/showExchange.html b/broker-plugins/management-http/src/main/java/resources/showExchange.html index 0e57a40105..77e827b73c 100644 --- a/broker-plugins/management-http/src/main/java/resources/showExchange.html +++ b/broker-plugins/management-http/src/main/java/resources/showExchange.html @@ -68,4 +68,8 @@ <button data-dojo-type="dijit.form.Button" class="addBindingButton">Add Binding</button> <button data-dojo-type="dijit.form.Button" class="deleteBindingButton">Delete Binding</button> </div> + <br/> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Producers'" class="queueProducers"> + <div class="producers"></div> + </div> </div> diff --git a/broker-plugins/management-http/src/main/java/resources/showQueue.html b/broker-plugins/management-http/src/main/java/resources/showQueue.html index a4b1936635..dbd198f25d 100644 --- a/broker-plugins/management-http/src/main/java/resources/showQueue.html +++ b/broker-plugins/management-http/src/main/java/resources/showQueue.html @@ -120,6 +120,10 @@ <div class="consumers"></div> </div> <br/> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Producers'" class="queueProducers"> + <div class="producers"></div> + </div> + <br/> <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Messages'" class="queueMessages"> <div class="messagesGrid"></div> <button data-dojo-type="dijit.form.Button" class="deleteMessagesButton" type="button">Delete Messages</button> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org