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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]