Skip to content

Commit

Permalink
ARTEMIS-2541 Improve message browser of Admin UI
Browse files Browse the repository at this point in the history
  • Loading branch information
sebthom committed Nov 8, 2019
1 parent 111b9cc commit 54daa44
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 20 deletions.
Expand Up @@ -2139,6 +2139,10 @@ li.dropdown.open > a.dropdown-toggle {
color: #ffffff !important;
}

.ngRow:hover {
background-color: lightyellow;
}

.ngRow.selected {
color: #ffffff !important;
background-color: #B21054 !important;
Expand Down
105 changes: 91 additions & 14 deletions artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/browse.js
Expand Up @@ -26,44 +26,58 @@ var ARTEMIS = (function(ARTEMIS) {
displayName: 'Message ID',
cellTemplate: '<div class="ngCellText"><a ng-click="openMessageDialog(row)">{{row.entity.messageID}}</a></div>',
// for ng-grid
width: '10%'
}, {
field: 'userID',
displayName: 'User ID',
width: '10%'
width: '100px'
}, {
field: 'type',
displayName: 'Type',
width: '10%'
cellTemplate: '<div class="ngCellText" title="{{row.entity.type}}">{{formatType(row.entity.type)}}</div>',
width: '90px'
}, {
field: 'durable',
displayName: 'Durable',
width: '10%'
width: '70px'
}, {
field: 'priority',
displayName: 'Priority',
width: '7%'
width: '70px'
}, {
field: 'timestamp',
displayName: 'Timestamp',
width: '19%'
cellTemplate: '<div class="ngCellText" title="{{row.entity.timestamp}}">{{formatTimestamp(row.entity.timestamp)}}</div>',
width: '160px'
}, {
field: 'expiration',
displayName: 'Expires',
width: '10%'
cellTemplate: '<div class="ngCellText" title="{{row.entity.expiration}}">{{formatExpires(row.entity.expiration)}}</div>',
width: '160px'
}, {
field: 'redelivered',
displayName: 'Redelivered',
width: '10%'
width: '100px'
}, {
field: 'largeMessage',
displayName: 'Large',
width: '10%'
width: '50px'
}, {
field: 'persistentSize',
displayName: 'Persistent Size',
cellTemplate: '<div class="ngCellText" title="{{row.entity.persistentSize.toLocaleString()}} bytes">{{formatPersistentSize(row.entity.persistentSize)}}</div>',
width: '120px'
}, {
field: 'userID',
displayName: 'User ID',
width: '15%'
}, {
displayName: 'Validated User',
cellTemplate: '<div class="ngCellText">{{row.entity.StringProperties._AMQ_VALIDATED_USER}}</div>',
width: '*'
}];

var attributes = defaultAttributes;
if (sessionStorage.getItem('browseColumnDefs')) {
attributes = JSON.parse(sessionStorage.getItem('browseColumnDefs'));
}

$scope.$on('ngGridEventColumns', function(newColumns) {
ARTEMIS.log.debug('ngGridEventColumns:', newColumns);
var visibles = newColumns.targetScope.columns.reduce(function(visibles, column) {
Expand All @@ -76,6 +90,7 @@ var ARTEMIS = (function(ARTEMIS) {
});
sessionStorage.setItem('browseColumnDefs', JSON.stringify(attributes));
});

$scope.pagingOptions = {
pageSizes: [50, 100, 200],
pageSize: 100,
Expand Down Expand Up @@ -113,8 +128,10 @@ var ARTEMIS = (function(ARTEMIS) {
afterSelectionChange: afterSelectionChange
};
$scope.showMessageDetails = false;

var ignoreColumns = ["PropertiesText", "BodyPreview", "text"];
var flattenColumns = ["BooleanProperties", "ByteProperties", "ShortProperties", "IntProperties", "LongProperties", "FloatProperties", "DoubleProperties", "StringProperties"];

$scope.$watch('workspace.selection', function() {
if (workspace.moveIfViewInvalid()) {
return;
Expand Down Expand Up @@ -143,6 +160,61 @@ var ARTEMIS = (function(ARTEMIS) {
};
$scope.refresh = loadTable;
ARTEMIS.decorate($scope);

var MS_PER_SEC = 1000;
var MS_PER_MIN = 60 * MS_PER_SEC;
var MS_PER_HOUR = 60 * MS_PER_MIN;
var MS_PER_DAY = 24 * MS_PER_HOUR;

function pad2(value) {
return (value < 10 ? '0' : '') + value;
}

$scope.formatExpires = function(timestamp) {
if (isNaN(timestamp)) {
return timestamp;
}
var expiresIn = timestamp - Date.now();
if (Math.abs(expiresIn) < MS_PER_DAY) {
var duration = expiresIn < 0 ? -expiresIn : expiresIn;
var hours = pad2(Math.floor((duration / MS_PER_HOUR) % 24));
var mins = pad2(Math.floor((duration / MS_PER_MIN) % 60));
var secs = pad2(Math.floor((duration / MS_PER_SEC) % 60));
if (expiresIn < 0) {
// "HH:mm:ss ago"
return hours + ":" + mins + ":" + secs + " ago";
}
// "in HH:mm:ss ago"
return "in " + hours + ":" + mins + ":" + secs;
}
return $scope.formatTimestamp(timestamp);
}

$scope.formatTimestamp = function(timestamp) {
if (isNaN(timestamp)) {
return timestamp;
}
var d = new Date(timestamp);
// "yyyy-MM-dd HH:mm:ss"
return d.getFullYear() + "-" + pad2(d.getMonth()) + "-" + pad2(d.getDay()) + " " + pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds());
}

var typeLabels = ["default", "1", "object", "text", "bytes", "map", "stream", "embedded"];
$scope.formatType = function(type) {
if (isNaN(type)) {
return type;
}
return type > -1 && type < 8 ? typeLabels[type] : type
}

$scope.formatPersistentSize = function(bytes) {
if(isNaN(bytes) || bytes < 0) return "n/a";
if(bytes < 10240) return bytes.toLocaleString() + " Bytes";
if(bytes < 1048576) return (bytes / 1024).toFixed(2) + " KB";
if(bytes < 1073741824) return (bytes / 1048576).toFixed(2) + " MB";
return (bytes / 1073741824).toFixed(2) + " GB";
}

$scope.moveMessages = function() {
var selection = workspace.selection;
var mbean = selection.objectName;
Expand Down Expand Up @@ -212,6 +284,7 @@ var ARTEMIS = (function(ARTEMIS) {
return [];
}
};

function populateTable(response) {
var data = response.value;
ARTEMIS.log.info("loading data:" + data);
Expand All @@ -237,7 +310,6 @@ var ARTEMIS = (function(ARTEMIS) {
* just create the HTML in code :)
*/
function createBodyText(message) {

ARTEMIS.log.info("loading message:" + message);
if (message.text) {
var body = message.text;
Expand Down Expand Up @@ -320,6 +392,11 @@ var ARTEMIS = (function(ARTEMIS) {
if (value === null) {
value = '';
}
if (key == "expiration" || key == "timestamp") {
value = $scope.formatTimestamp(value) + " (" + value + ")";
} else if (key == "type") {
value = $scope.formatType(value) + " (" + value + ")";
}
buffer.push('<tr><td class="propertyName"><span class="green">Header</span> - ' + key + '</td><td class="property-value">' + value + '</td></tr>');
}

Expand Down Expand Up @@ -384,7 +461,7 @@ var ARTEMIS = (function(ARTEMIS) {
} else {
onDlq(false);
}
jolokia.request({ type: 'exec', mbean: objName, operation: 'countMessages()'}, onSuccess(function(response) {$scope.totalServerItems = response.value;}));
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));
}
}
Expand Down
Expand Up @@ -30,6 +30,7 @@ public interface CompositeDataConstants {
String BODY = "BodyPreview";
String TEXT_BODY = "text";
String LARGE_MESSAGE = "largeMessage";
String PERSISTENT_SIZE = "persistentSize";
String PROPERTIES = "PropertiesText";

String ADDRESS_DESCRIPTION = "The Address";
Expand All @@ -43,6 +44,7 @@ public interface CompositeDataConstants {
String TIMESTAMP_DESCRIPTION = "The message timestamp";
String BODY_DESCRIPTION = "The message body";
String LARGE_MESSAGE_DESCRIPTION = "Is the message treated as a large message";
String PERSISTENT_SIZE_DESCRIPTION = "The message size when persisted on disk";
String PROPERTIES_DESCRIPTION = "The properties text";

// User properties
Expand Down
Expand Up @@ -26,15 +26,13 @@
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.ICoreMessage;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.SimpleString;
Expand Down Expand Up @@ -107,8 +105,9 @@ protected void init() throws OpenDataException {
addItem(CompositeDataConstants.EXPIRATION, CompositeDataConstants.EXPIRATION_DESCRIPTION, SimpleType.LONG);
addItem(CompositeDataConstants.PRIORITY, CompositeDataConstants.PRIORITY_DESCRIPTION, SimpleType.BYTE);
addItem(CompositeDataConstants.REDELIVERED, CompositeDataConstants.REDELIVERED_DESCRIPTION, SimpleType.BOOLEAN);
addItem(CompositeDataConstants.TIMESTAMP, CompositeDataConstants.TIMESTAMP_DESCRIPTION, SimpleType.STRING);
addItem(CompositeDataConstants.TIMESTAMP, CompositeDataConstants.TIMESTAMP_DESCRIPTION, SimpleType.LONG);
addItem(CompositeDataConstants.LARGE_MESSAGE, CompositeDataConstants.LARGE_MESSAGE_DESCRIPTION, SimpleType.BOOLEAN);
addItem(CompositeDataConstants.PERSISTENT_SIZE, CompositeDataConstants.PERSISTENT_SIZE_DESCRIPTION, SimpleType.LONG);

addItem(CompositeDataConstants.PROPERTIES, CompositeDataConstants.PROPERTIES_DESCRIPTION, SimpleType.STRING);

Expand Down Expand Up @@ -145,11 +144,15 @@ public Map<String, Object> getFields(MessageReference ref) throws OpenDataExcept
rc.put(CompositeDataConstants.TYPE, m.getType());
rc.put(CompositeDataConstants.DURABLE, m.isDurable());
rc.put(CompositeDataConstants.EXPIRATION, m.getExpiration());
DateFormat dateFormat = new SimpleDateFormat();
rc.put(CompositeDataConstants.TIMESTAMP, dateFormat.format(new Date(m.getTimestamp())));
rc.put(CompositeDataConstants.TIMESTAMP, m.getTimestamp());
rc.put(CompositeDataConstants.PRIORITY, m.getPriority());
rc.put(CompositeDataConstants.REDELIVERED, ref.getDeliveryCount() > 1);
rc.put(CompositeDataConstants.LARGE_MESSAGE, m.isLargeMessage());
try {
rc.put(CompositeDataConstants.PERSISTENT_SIZE, m.getPersistentSize());
} catch (final ActiveMQException e1) {
rc.put(CompositeDataConstants.PERSISTENT_SIZE, -1);
}

Map<String, Object> propertyMap = m.toPropertyMap();

Expand Down

0 comments on commit 54daa44

Please sign in to comment.