diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2009-10-05 09:51:53 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2009-10-05 09:51:53 +0000 |
commit | 2a40f697eaef97b68619eaf7491f1df7084a8754 (patch) | |
tree | f4d8a9884f81fa2e90b2931c6fc402b46894a7b1 | |
parent | bede462542128d1bb0060bc5bec8f31e3f2b5aff (diff) | |
download | qpid-python-2a40f697eaef97b68619eaf7491f1df7084a8754.tar.gz |
Merged from trunk up to r796645
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-0-10@821730 13f79535-47bb-0310-9956-ffa450edef68
15 files changed, 798 insertions, 256 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index ac0363e76a..164db6d679 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -122,6 +122,17 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue> List<Long> getMessagesOnTheQueue(int num, int offest); QueueEntry getMessageOnTheQueue(long messageId); + + /** + * Returns a list of QueEntries from a given range of queue positions, eg messages 5 to 10 on the queue. + * + * The 'queue position' index starts from 1. Using 0 in 'from' will be ignored and continue from 1. + * Using 0 in the 'to' field will return an empty list regardless of the 'from' value. + * @param fromPosition + * @param toPosition + * @return + */ + public List<QueueEntry> getMessagesRangeOnTheQueue(final long fromPosition, final long toPosition); void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index 049b6b7604..ac927f2821 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -397,32 +397,52 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que /** * Returns the header contents of the messages stored in this queue in tabular form. + * Deprecated as of Qpid JMX API 1.3 */ + @Deprecated public TabularData viewMessages(int beginIndex, int endIndex) throws JMException { - if ((beginIndex > endIndex) || (beginIndex < 1)) + return viewMessages((long)beginIndex,(long)endIndex); + } + + + /** + * Returns the header contents of the messages stored in this queue in tabular form. + * @param startPosition The queue position of the first message to be viewed + * @param endPosition The queue position of the last message to be viewed + */ + public TabularData viewMessages(long startPosition, long endPosition) throws JMException + { + if ((startPosition > endPosition) || (startPosition < 1)) { - throw new OperationsException("From Index = " + beginIndex + ", To Index = " + endIndex + throw new OperationsException("From Index = " + startPosition + ", To Index = " + endPosition + "\n\"From Index\" should be greater than 0 and less than \"To Index\""); } + + if ((endPosition - startPosition) > Integer.MAX_VALUE) + { + throw new OperationsException("Specified MessageID interval is too large. Intervals must be less than 2^31 in size"); + } - List<QueueEntry> list = _queue.getMessagesOnTheQueue(); + List<QueueEntry> list = _queue.getMessagesRangeOnTheQueue(startPosition,endPosition); TabularDataSupport _messageList = new TabularDataSupport(_messagelistDataType); try { // Create the tabular list of message header contents - for (int i = beginIndex; (i <= endIndex) && (i <= list.size()); i++) + int size = list.size(); + + for (int i = 0; i < size ; i++) { - long position = i; - ServerMessage serverMsg = list.get(i - 1).getMessage(); + long position = startPosition + i; + ServerMessage serverMsg = list.get(i).getMessage(); if(serverMsg instanceof AMQMessage) { AMQMessage msg = (AMQMessage) serverMsg; ContentHeaderBody headerBody = msg.getContentHeaderBody(); // Create header attributes list String[] headerAttributes = getMessageHeaderProperties(headerBody); - Object[] itemValues = { msg.getMessageId(), headerAttributes, headerBody.bodySize, msg.isRedelivered(), position }; + Object[] itemValues = { msg.getMessageId(), headerAttributes, headerBody.bodySize, msg.isRedelivered(), position}; CompositeData messageData = new CompositeDataSupport(_messageDataType, VIEW_MSGS_COMPOSITE_ITEM_NAMES, itemValues); _messageList.put(messageData); } @@ -483,13 +503,46 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que { if ((fromMessageId > toMessageId) || (fromMessageId < 1)) { - throw new OperationsException("\"From MessageId\" should be greater then 0 and less then \"To MessageId\""); + throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\""); } _queue.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, _storeContext); } /** + * @see ManagedQueue#deleteMessages + * @param fromMessageId + * @param toMessageId + * @throws JMException + */ + public void deleteMessages(long fromMessageId, long toMessageId) throws JMException + { + if ((fromMessageId > toMessageId) || (fromMessageId < 1)) + { + throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\""); + } + + _queue.removeMessagesFromQueue(fromMessageId, toMessageId, _storeContext); + } + + /** + * @see ManagedQueue#copyMessages + * @param fromMessageId + * @param toMessageId + * @param toQueueName + * @throws JMException + */ + public void copyMessages(long fromMessageId, long toMessageId, String toQueueName) throws JMException + { + if ((fromMessageId > toMessageId) || (fromMessageId < 1)) + { + throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\""); + } + + _queue.copyMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, _storeContext); + } + + /** * returns Notifications sent by this MBean. */ @Override diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java index 9f8a956448..1fce03b1c3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java @@ -871,6 +871,43 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener return entryList; } + + /** + * Returns a list of QueEntries from a given range of queue positions, eg messages 5 to 10 on the queue. + * + * The 'queue position' index starts from 1. Using 0 in 'from' will be ignored and continue from 1. + * Using 0 in the 'to' field will return an empty list regardless of the 'from' value. + * @param fromPosition + * @param toPosition + * @return + */ + public List<QueueEntry> getMessagesRangeOnTheQueue(final long fromPosition, final long toPosition) + { + List<QueueEntry> queueEntries = new ArrayList<QueueEntry>(); + + QueueEntryIterator it = _entries.iterator(); + + long index = 1; + for ( ; index < fromPosition && !it.atTail(); index++) + { + it.advance(); + } + + if(index < fromPosition) + { + //The queue does not contain enough entries to reach our range. + //return the empty list. + return queueEntries; + } + + for ( ; index <= toPosition && !it.atTail(); index++) + { + it.advance(); + queueEntries.add(it.getNode()); + } + + return queueEntries; + } public void moveMessagesToAnotherQueue(final long fromMessageId, final long toMessageId, diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java index ce986cf55b..1138b465cd 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java @@ -108,6 +108,52 @@ public class AMQQueueMBeanTest extends TestCase //Ensure that the data has been removed from the Store verifyBrokerState(); } + + public void testDeleteMessages() throws Exception + { + int messageCount = 10; + sendMessages(messageCount, true); + assertEquals("", messageCount, _queueMBean.getMessageCount().intValue()); + assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); + long queueDepth = (messageCount * MESSAGE_SIZE); + assertTrue(_queueMBean.getQueueDepth() == queueDepth); + + //delete first message + _queueMBean.deleteMessages(1L,1L); + assertTrue(_queueMBean.getMessageCount() == (messageCount - 1)); + assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); + try + { + _queueMBean.viewMessageContent(1L); + fail("Message should no longer be on the queue"); + } + catch(Exception e) + { + + } + + //delete last message, leaving 2nd to 9th + _queueMBean.deleteMessages(10L,10L); + assertTrue(_queueMBean.getMessageCount() == (messageCount - 2)); + assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); + try + { + _queueMBean.viewMessageContent(10L); + fail("Message should no longer be on the queue"); + } + catch(Exception e) + { + + } + + //delete remaining messages, leaving none + _queueMBean.deleteMessages(2L,9L); + assertTrue(_queueMBean.getMessageCount() == (0)); + assertTrue(_queueMBean.getReceivedMessageCount() == messageCount); + + //Ensure that the data has been removed from the Store + verifyBrokerState(); + } // todo: collect to a general testing class -duplicated from Systest/MessageReturntest private void verifyBrokerState() @@ -187,7 +233,7 @@ public class AMQQueueMBeanTest extends TestCase { try { - _queueMBean.viewMessages(0, 3); + _queueMBean.viewMessages(0L, 3L); fail(); } catch (JMException ex) @@ -197,7 +243,7 @@ public class AMQQueueMBeanTest extends TestCase try { - _queueMBean.viewMessages(2, 1); + _queueMBean.viewMessages(2L, 1L); fail(); } catch (JMException ex) @@ -207,13 +253,25 @@ public class AMQQueueMBeanTest extends TestCase try { - _queueMBean.viewMessages(-1, 1); + _queueMBean.viewMessages(-1L, 1L); fail(); } catch (JMException ex) { } + + try + { + long end = Integer.MAX_VALUE; + end+=2; + _queueMBean.viewMessages(1L, end); + fail("Expected Exception due to oversized(> 2^31) message range"); + } + catch (JMException ex) + { + + } IncomingMessage msg = message(false, false); long id = msg.getMessageId(); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java index 2cdc002f27..d7bd297998 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java @@ -218,6 +218,11 @@ public class MockAMQQueue implements AMQQueue { return null; //To change body of implemented methods use File | Settings | File Templates. } + + public List<QueueEntry> getMessagesRangeOnTheQueue(long fromPosition, long toPosition) + { + return null; + } public void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, StoreContext storeContext) { diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java index cc2a56e1d2..f0a4838cae 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java @@ -335,6 +335,69 @@ public class SimpleAMQQueueTest extends TestCase assertEquals("Message ID was wrong", messageId, msgids.get(i)); } } + + public void testGetMessagesRangeOnTheQueue() throws Exception + { + for (int i = 1 ; i <= 10; i++) + { + // Create message + Long messageId = new Long(i); + AMQMessage message = createMessage(messageId); + // Put message on queue + _queue.enqueue(message); + } + + // Get non-existent 0th QueueEntry & check returned list was empty + // (the position parameters in this method are indexed from 1) + List<QueueEntry> entries = _queue.getMessagesRangeOnTheQueue(0, 0); + assertTrue(entries.size() == 0); + + // Check that when 'from' is 0 it is ignored and the range continues from 1 + entries = _queue.getMessagesRangeOnTheQueue(0, 2); + assertTrue(entries.size() == 2); + long msgID = entries.get(0).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 1L); + msgID = entries.get(1).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 2L); + + // Check that when 'from' is greater than 'to' the returned list is empty + entries = _queue.getMessagesRangeOnTheQueue(5, 4); + assertTrue(entries.size() == 0); + + // Get first QueueEntry & check id + entries = _queue.getMessagesRangeOnTheQueue(1, 1); + assertTrue(entries.size() == 1); + msgID = entries.get(0).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 1L); + + // Get 5th,6th,7th entries and check id's + entries = _queue.getMessagesRangeOnTheQueue(5, 7); + assertTrue(entries.size() == 3); + msgID = entries.get(0).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 5L); + msgID = entries.get(1).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 6L); + msgID = entries.get(2).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 7L); + + // Get 10th QueueEntry & check id + entries = _queue.getMessagesRangeOnTheQueue(10, 10); + assertTrue(entries.size() == 1); + msgID = entries.get(0).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 10L); + + // Get non-existent 11th QueueEntry & check returned set was empty + entries = _queue.getMessagesRangeOnTheQueue(11, 11); + assertTrue(entries.size() == 0); + + // Get 9th,10th, and non-existent 11th entries & check result is of size 2 with correct IDs + entries = _queue.getMessagesRangeOnTheQueue(9, 11); + assertTrue(entries.size() == 2); + msgID = entries.get(0).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 9L); + msgID = entries.get(1).getMessage().getMessageNumber(); + assertEquals("Message ID was wrong", msgID, 10L); + } public void testEnqueueDequeueOfPersistentMessageToNonDurableQueue() throws AMQException { diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java index 9c21d64cdf..9046d7fcb7 100644 --- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java +++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedQueue.java @@ -207,18 +207,42 @@ public interface ManagedQueue /** * Returns a subset of all the messages stored in the queue. The messages * are returned based on the given index numbers. + * + * Deprecated as of Qpid JMX API 1.3 * @param fromIndex * @param toIndex * @return * @throws IOException * @throws JMException */ + @Deprecated @MBeanOperation(name="viewMessages", description="Message headers for messages in this queue within given index range. eg. from index 1 - 100") TabularData viewMessages(@MBeanOperationParameter(name="from index", description="from index")int fromIndex, @MBeanOperationParameter(name="to index", description="to index")int toIndex) throws IOException, JMException; + + /** + * Returns a subset (up to 2^31 messages at a time) of all the messages stored on the queue. + * The messages are returned based on the given queue position range. + * @param startPosition + * @param endPosition + * @return + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="viewMessages", + description="Message headers for messages in this queue within given queue positions range. eg. from index 1 - 100") + TabularData viewMessages(@MBeanOperationParameter(name="start position", description="start position")long startPosition, + @MBeanOperationParameter(name="end position", description="end position")long endPosition) + throws IOException, JMException; + /** + * Returns the content for the given AMQ Message ID. + * + * @throws IOException + * @throws JMException + */ @MBeanOperation(name="viewMessageContent", description="The message content for given Message Id") CompositeData viewMessageContent(@MBeanOperationParameter(name="Message Id", description="Message Id")long messageId) throws IOException, JMException; @@ -260,4 +284,34 @@ public interface ManagedQueue @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId, @MBeanOperationParameter(name= ManagedQueue.TYPE, description="to Queue Name")String toQueue) throws IOException, JMException; + + /** + * Deletes the messages in given range of AMQ message Ids in the given Queue. + * @param fromMessageId first in the range of message ids + * @param toMessageId last in the range of message ids + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="deleteMessages", + description="Delete a range of messages from a specified queue", + impact= MBeanOperationInfo.ACTION) + void deleteMessages(@MBeanOperationParameter(name="from MessageId", description="from MessageId")long fromMessageId, + @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId) + throws IOException, JMException; + + /** + * Copies the messages in given range of AMQ message Ids to a given Queue. + * @param fromMessageId first in the range of message ids + * @param toMessageId last in the range of message ids + * @param toQueue where the messages are to be copied + * @throws IOException + * @throws JMException + */ + @MBeanOperation(name="copyMessages", + description="Copies a range of messages to a specified queue", + impact= MBeanOperationInfo.ACTION) + void copyMessages(@MBeanOperationParameter(name="from MessageId", description="from MessageId")long fromMessageId, + @MBeanOperationParameter(name="to MessageId", description="to MessageId")long toMessageId, + @MBeanOperationParameter(name= ManagedQueue.TYPE, description="to Queue Name")String toQueue) + throws IOException, JMException; } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java index cada746b29..ae60467bf5 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java @@ -106,21 +106,24 @@ public class RefreshIntervalComboPanel extends WorkbenchWindowControlContributio @Override public void run() { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - final MBeanView mbView = (MBeanView)window.getActivePage().findView(MBeanView.ID); - - final NavigationView navView = (NavigationView)window.getActivePage().findView(NavigationView.ID); - try - { - mbView.refresh(); - navView.refresh(); - } - catch (Exception ex) + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if(window != null) { - MBeanUtility.handleException(ex); - } + final MBeanView mbView = (MBeanView)window.getActivePage().findView(MBeanView.ID); - _display.timerExec(1000 * seconds, this); + final NavigationView navView = (NavigationView)window.getActivePage().findView(NavigationView.ID); + try + { + mbView.refresh(); + navView.refresh(); + } + catch (Exception ex) + { + MBeanUtility.handleException(ex); + } + + _display.timerExec(1000 * seconds, this); + } } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java index cc44a19781..23879a779c 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java @@ -169,6 +169,8 @@ public abstract class ServerRegistry public abstract List<NotificationObject> getNotifications(ManagedBean mbean); + public abstract List<NotificationObject> getNotifications(String virtualhost); + public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type); public abstract void clearNotifications(ManagedBean mbean, List<NotificationObject> list); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java index bf3e95e308..f280e20fdd 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -248,6 +248,33 @@ public class JMXServerRegistry extends ServerRegistry } } + public List<NotificationObject> getNotifications(String virtualhost) + { + List<NotificationObject> vhostNotificationsList = new ArrayList<NotificationObject>(); + + //iterate over all the notification lists for mbeans with subscribed notifications + for (List<NotificationObject> list : _notificationsMap.values()) + { + //Check the source vhost of the first notification + NotificationObject notification = list.get(0); + + if (notification != null) + { + String sourceVhost = notification.getSourceVirtualHost(); + if(sourceVhost != null) + { + if(sourceVhost.equalsIgnoreCase(virtualhost)) + { + //If it matches, add the entire list as they are from the same vhost (same source mbean) + vhostNotificationsList.addAll(list); + } + } + } + } + + return vhostNotificationsList; + } + public void clearNotifications(ManagedBean mbean, List<NotificationObject> list) { if (mbean == null) diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java index 926e5f0a24..e42b3c53b6 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java @@ -26,6 +26,8 @@ import java.util.TimeZone; import javax.management.ObjectName; +import static org.apache.qpid.management.ui.Constants.VIRTUAL_HOST; + public class NotificationObject { @@ -65,6 +67,16 @@ public class NotificationObject return null; } + public String getSourceVirtualHost() + { + if (_source instanceof ObjectName) + { + return ((ObjectName)_source).getKeyProperty(VIRTUAL_HOST); + } + + return null; + } + public String getMessage() { return _message; diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java index bd808922f4..a185467e2d 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java @@ -233,7 +233,7 @@ public class MBeanTabFolderFactory return; } - NotificationsTabControl controller = new NotificationsTabControl(tabFolder); + NotificationsTabControl controller = new NotificationsTabControl(tabFolder, mbean); TabItem tab = new TabItem(tabFolder, SWT.NONE); tab.setText(NOTIFICATIONS); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java index 6894080859..516b0b3bbf 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java @@ -21,7 +21,6 @@ package org.apache.qpid.management.ui.views; import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR; -import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH; import static org.apache.qpid.management.ui.Constants.DESCRIPTION; import static org.apache.qpid.management.ui.Constants.FONT_BOLD; import static org.apache.qpid.management.ui.Constants.FONT_BUTTON; @@ -50,7 +49,6 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TabFolder; @@ -65,23 +63,25 @@ public class NotificationsTabControl extends VHNotificationsTabControl private SelectionListener selectionListener; private SelectionListener comboListener; - private Combo notificationNameCombo = null; - private Combo typesCombo = null; - private Label descriptionLabel = null; - private Button _subscribeButton = null; - private Button _unsubscribeButton = null; + private Combo _notificationNameCombo; + private Combo _typesCombo; + private Label _descriptionLabel; + private Button _subscribeButton; + private Button _unsubscribeButton; - public NotificationsTabControl(TabFolder tabFolder) + public NotificationsTabControl(TabFolder tabFolder, ManagedBean mbean) { super(tabFolder); + _mbean = mbean; + + populateNotificationInfo(); } protected void createWidgets() - { + { selectionListener = new SelectionListenerImpl(); comboListener = new ComboSelectionListener(); createNotificationInfoComposite(); - //addFilterComposite(); addButtons(); createTableViewer(); } @@ -103,21 +103,21 @@ public class NotificationsTabControl extends VHNotificationsTabControl formData.left = new FormAttachment(0, 10); label.setLayoutData(formData); - notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + _notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); formData = new FormData(); formData.top = new FormAttachment(label, 10); formData.left = new FormAttachment(0, 10); formData.right = new FormAttachment(40); - notificationNameCombo.setLayoutData(formData); - notificationNameCombo.addSelectionListener(comboListener); + _notificationNameCombo.setLayoutData(formData); + _notificationNameCombo.addSelectionListener(comboListener); - typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); + _typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN); formData = new FormData(); formData.top = new FormAttachment(label, 10); - formData.left = new FormAttachment(notificationNameCombo, 5); + formData.left = new FormAttachment(_notificationNameCombo, 5); formData.right = new FormAttachment(65); - typesCombo.setLayoutData(formData); - typesCombo.addSelectionListener(comboListener); + _typesCombo.setLayoutData(formData); + _typesCombo.addSelectionListener(comboListener); _subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER); _subscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); @@ -141,30 +141,30 @@ public class NotificationsTabControl extends VHNotificationsTabControl Label fixedLabel = _toolkit.createLabel(composite, ""); formData = new FormData(); - formData.top = new FormAttachment(notificationNameCombo, 5); + formData.top = new FormAttachment(_notificationNameCombo, 5); formData.left = new FormAttachment(0, 10); fixedLabel.setLayoutData(formData); fixedLabel.setText(DESCRIPTION + " : "); fixedLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD)); - descriptionLabel = _toolkit.createLabel(composite, ""); + _descriptionLabel = _toolkit.createLabel(composite, ""); formData = new FormData(); - formData.top = new FormAttachment(notificationNameCombo, 5); + formData.top = new FormAttachment(_notificationNameCombo, 5); formData.left = new FormAttachment(fixedLabel, 10); formData.right = new FormAttachment(100); - descriptionLabel.setLayoutData(formData); - descriptionLabel.setText(" "); - descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC)); + _descriptionLabel.setLayoutData(formData); + _descriptionLabel.setText(" "); + _descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC)); } /** - * Creates clear buttin and refresh button + * Creates clear button */ protected void addButtons() { Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - composite.setLayout(new GridLayout(2, true)); + composite.setLayout(new GridLayout()); // Add Clear Button _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); @@ -182,74 +182,14 @@ public class NotificationsTabControl extends VHNotificationsTabControl IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection(); ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); serverRegistry.clearNotifications(_mbean, ss.toList()); - refresh(); - } - }); - - // Add Refresh Button - _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); - _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); - gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false); - gridData.widthHint = 80; - _refreshButton.setLayoutData(gridData); - _refreshButton.addSelectionListener(new SelectionAdapter() - { - public void widgetSelected(SelectionEvent e) - { - if (_mbean == null) - return; - - refresh(); } }); } - + @Override public void refresh(ManagedBean mbean) { - _mbean = mbean; - _notifications = null; - _table.deselectAll(); - _tableViewer.getTable().clearAll(); - - if (_mbean == null) - { - _tableViewer.getTable().clearAll(); - _subscribeButton.setEnabled(false); - _unsubscribeButton.setEnabled(false); - return; - } - - if (!doesMBeanSendsNotification()) - { - Control[] children = _form.getBody().getChildren(); - for (int i = 0; i < children.length; i++) - { - children[i].setVisible(false); - } - - String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType(); - _form.setText(name + " does not send any notification"); - return; - } - - Control[] children = _form.getBody().getChildren(); - for (int i = 0; i < children.length; i++) - { - children[i].setVisible(true); - } - - populateNotificationInfo(); - workerRunning = true; - _form.layout(true); - _form.getBody().layout(true, true); - } - - public void refresh() - { - _notifications = null; - _table.deselectAll(); - _tableViewer.getTable().clearAll(); + refresh(); } /** @@ -257,26 +197,26 @@ public class NotificationsTabControl extends VHNotificationsTabControl */ private void populateNotificationInfo() { - notificationNameCombo.removeAll(); + _notificationNameCombo.removeAll(); NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); if (items.length > 1) { - notificationNameCombo.add(SELECT_NOTIFICATIONNAME); + _notificationNameCombo.add(SELECT_NOTIFICATIONNAME); } for (int i = 0; i < items.length; i++) { - notificationNameCombo.add(items[i].getName()); - notificationNameCombo.setData(items[i].getName(), items[i]); + _notificationNameCombo.add(items[i].getName()); + _notificationNameCombo.setData(items[i].getName(), items[i]); } - notificationNameCombo.select(0); + _notificationNameCombo.select(0); - typesCombo.removeAll(); - typesCombo.add("Select Type", 0); - typesCombo.select(0); - typesCombo.setEnabled(false); + _typesCombo.removeAll(); + _typesCombo.add("Select Type", 0); + _typesCombo.select(0); + _typesCombo.setEnabled(false); - populateNotificationType(notificationNameCombo.getItem(0)); + populateNotificationType(_notificationNameCombo.getItem(0)); checkForEnablingButtons(); } @@ -285,18 +225,18 @@ public class NotificationsTabControl extends VHNotificationsTabControl */ private void checkForEnablingButtons() { - int nameIndex = notificationNameCombo.getSelectionIndex(); - int itemCount = notificationNameCombo.getItems().length; + int nameIndex = _notificationNameCombo.getSelectionIndex(); + int itemCount = _notificationNameCombo.getItems().length; if ((itemCount > 1) && (nameIndex == 0)) { _subscribeButton.setEnabled(false); _unsubscribeButton.setEnabled(false); - descriptionLabel.setText(""); + _descriptionLabel.setText(""); return; } - int typeIndex = typesCombo.getSelectionIndex(); - itemCount = typesCombo.getItems().length; + int typeIndex = _typesCombo.getSelectionIndex(); + itemCount = _typesCombo.getItems().length; if ((itemCount > 1) && (typeIndex == 0)) { _subscribeButton.setEnabled(false); @@ -304,8 +244,8 @@ public class NotificationsTabControl extends VHNotificationsTabControl return; } - String type = typesCombo.getItem(typeIndex); - String name = notificationNameCombo.getItem(nameIndex); + String type = _typesCombo.getItem(typeIndex); + String name = _notificationNameCombo.getItem(nameIndex); ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type)) @@ -320,15 +260,6 @@ public class NotificationsTabControl extends VHNotificationsTabControl } } - private boolean doesMBeanSendsNotification() - { - NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); - if (items == null || items.length == 0) - return false; - else - return true; - } - /** * Selection listener for subscribing or unsubscribing the notifications */ @@ -340,8 +271,8 @@ public class NotificationsTabControl extends VHNotificationsTabControl return; Button source = (Button)e.getSource(); - String type = typesCombo.getItem(typesCombo.getSelectionIndex()); - String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex()); + String type = _typesCombo.getItem(_typesCombo.getSelectionIndex()); + String name = _notificationNameCombo.getItem(_notificationNameCombo.getSelectionIndex()); if (source == _unsubscribeButton) { try @@ -380,7 +311,7 @@ public class NotificationsTabControl extends VHNotificationsTabControl return; Combo combo = (Combo)e.getSource(); - if (combo == notificationNameCombo) + if (combo == _notificationNameCombo) { String selectedItem = combo.getItem(combo.getSelectionIndex()); populateNotificationType(selectedItem); @@ -391,23 +322,23 @@ public class NotificationsTabControl extends VHNotificationsTabControl private void populateNotificationType(String notificationName) { - NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName); + NotificationInfoModel data = (NotificationInfoModel)_notificationNameCombo.getData(notificationName); if (data == null) { - descriptionLabel.setText(""); - typesCombo.select(0); - typesCombo.setEnabled(false); + _descriptionLabel.setText(""); + _typesCombo.select(0); + _typesCombo.setEnabled(false); return; } - descriptionLabel.setText(data.getDescription()); - typesCombo.removeAll(); - typesCombo.setItems(data.getTypes()); - if (typesCombo.getItemCount() > 1) + _descriptionLabel.setText(data.getDescription()); + _typesCombo.removeAll(); + _typesCombo.setItems(data.getTypes()); + if (_typesCombo.getItemCount() > 1) { - typesCombo.add(SELECT_NOTIFICATIONTYPE, 0); + _typesCombo.add(SELECT_NOTIFICATIONTYPE, 0); } - typesCombo.select(0); - typesCombo.setEnabled(true); + _typesCombo.select(0); + _typesCombo.setEnabled(true); } /** @@ -417,11 +348,8 @@ public class NotificationsTabControl extends VHNotificationsTabControl { ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); List<NotificationObject> newList = serverRegistry.getNotifications(_mbean); - if (newList == null) - return; - _notifications = newList; + _tableViewer.setInput(_notifications); - _tableViewer.refresh(); } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java index be25707bd3..691ceedcf4 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java @@ -22,7 +22,6 @@ package org.apache.qpid.management.ui.views; import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR; -import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH; import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE; import static org.apache.qpid.management.ui.Constants.FONT_BUTTON; @@ -35,7 +34,6 @@ import org.apache.qpid.management.ui.model.NotificationObject; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProviderListener; -import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; @@ -68,7 +66,8 @@ public class VHNotificationsTabControl extends TabControl protected Table _table = null; protected TableViewer _tableViewer = null; - protected Thread worker = null; + protected Thread _worker = null; + protected boolean _workerRunning = false; protected List<NotificationObject> _notifications = null; @@ -86,7 +85,6 @@ public class VHNotificationsTabControl extends TabControl }; protected Button _clearButton = null; - protected Button _refreshButton = null; public VHNotificationsTabControl(TabFolder tabFolder) { @@ -98,8 +96,7 @@ public class VHNotificationsTabControl extends TabControl gridLayout.marginHeight = 0; _form.getBody().setLayout(gridLayout); - worker = new Thread(new Worker()); - worker.start(); + createWidgets(); } protected void createWidgets() @@ -113,10 +110,6 @@ public class VHNotificationsTabControl extends TabControl */ public Control getControl() { - if (_table == null) - { - createWidgets(); - } return _form; } @@ -127,7 +120,7 @@ public class VHNotificationsTabControl extends TabControl { Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); - composite.setLayout(new GridLayout(2, true)); + composite.setLayout(new GridLayout()); // Add Clear Button _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); @@ -146,20 +139,6 @@ public class VHNotificationsTabControl extends TabControl refresh(); } }); - - // Add Refresh Button - _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER); - _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); - gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false); - gridData.widthHint = 80; - _refreshButton.setLayoutData(gridData); - _refreshButton.addSelectionListener(new SelectionAdapter() - { - public void widgetSelected(SelectionEvent e) - { - refresh(); - } - }); } /** @@ -201,36 +180,12 @@ public class VHNotificationsTabControl extends TabControl { createTable(); _tableViewer = new TableViewer(_table); - //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); _tableViewer.setUseHashlookup(true); _tableViewer.setContentProvider(new ContentProviderImpl()); _tableViewer.setLabelProvider(new LabelProviderImpl()); _tableViewer.setColumnProperties(_tableTitles); - /* - CellEditor[] cellEditors = new CellEditor[_tableTitles.length]; - TextCellEditor textEditor = new TextCellEditor(table); - cellEditors[0] = textEditor; - textEditor = new TextCellEditor(table); - cellEditors[1] = textEditor; - textEditor = new TextCellEditor(table); - cellEditors[2] = textEditor; - textEditor = new TextCellEditor(table); - cellEditors[3] = textEditor; - - // Assign the cell editors to the viewer - _tableViewer.setCellEditors(cellEditors); - _tableViewer.setCellModifier(new TableCellModifier()); - */ addTableListeners(); - - //_tableViewer.addSelectionChangedListener(new ); - - //_notificationDetails = new Composite(_tabControl, SWT.BORDER); - //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH)); - - //_tabControl.layout(); - //viewerComposite.layout(); } /** @@ -311,17 +266,19 @@ public class VHNotificationsTabControl extends TabControl public void refresh() { - _notifications = null; - _table.deselectAll(); - _tableViewer.getTable().clearAll(); - - Control[] children = _form.getBody().getChildren(); - for (int i = 0; i < children.length; i++) + if(_workerRunning) + { + //perform an single immediate-update + updateTableViewer(); + } + else { - children[i].setVisible(true); + //start a worker to do the update and keep going as required + _workerRunning = true; + _worker = new Thread(new Worker()); + _worker.start(); } - - workerRunning = true; + _form.layout(true); _form.getBody().layout(true, true); } @@ -413,10 +370,10 @@ public class VHNotificationsTabControl extends TabControl } } // end of LabelProviderImpl - protected boolean workerRunning = false; + protected void setWorkerRunning(boolean running) { - workerRunning = running; + _workerRunning = running; } /** @@ -424,15 +381,18 @@ public class VHNotificationsTabControl extends TabControl */ private class Worker implements Runnable { + private boolean keepGoing = true; + public void run() { - Display display = _tabFolder.getDisplay(); - while(true) + final Display display = _tabFolder.getDisplay(); + + while(keepGoing) { - if (!workerRunning || display == null) + if (display == null || display.isDisposed()) { - sleep(); - continue; + setWorkerRunning(false); + break; //stop the thread } display.syncExec(new Runnable() @@ -440,15 +400,27 @@ public class VHNotificationsTabControl extends TabControl public void run() { if (_form == null || _form.isDisposed()) - return; - setWorkerRunning(_form.isVisible()); - if (!workerRunning) return; - - updateTableViewer(); + { + setWorkerRunning(false); + keepGoing = false; //exit the loop and stop the thread + } + else + { + keepGoing = _form.isVisible(); + setWorkerRunning(keepGoing); + } + + if (keepGoing) + { + updateTableViewer(); + } } - }); + }); - sleep(); + if (keepGoing) + { + sleep(); + } } } @@ -466,18 +438,17 @@ public class VHNotificationsTabControl extends TabControl } /** - * Updates the table with new notifications received from mbean server for all mbeans + * Updates the table with new notifications received from mbean server for all mbeans in this virtual host */ protected void updateTableViewer() { - ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); - List<NotificationObject> newList = serverRegistry.getNotifications(null); - if (newList == null) - return; + String virtualhost = MBeanView.getVirtualHost(); + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + List<NotificationObject> newList = serverRegistry.getNotifications(virtualhost); _notifications = newList; + _tableViewer.setInput(_notifications); - _tableViewer.refresh(); } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java index bb934593a2..00c5b3326b 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java @@ -41,6 +41,7 @@ import org.apache.qpid.management.ui.ManagedBean; import org.apache.qpid.management.common.mbeans.ManagedQueue; import org.apache.qpid.management.ui.jmx.JMXManagedObject; import org.apache.qpid.management.ui.jmx.MBeanUtility; +import org.apache.qpid.management.ui.views.NumberVerifyListener; import org.apache.qpid.management.ui.views.TabControl; import org.apache.qpid.management.ui.views.ViewUtility; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -52,6 +53,8 @@ import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionAdapter; @@ -87,14 +90,23 @@ public class QueueOperationsTabControl extends TabControl private ApiVersion _ApiVersion; + private Text _fromMsgText; + private Text _toMsgText; + private Long _fromMsg = new Long(FROM_DEFAULT); + private Long _toMsg = new Long(TO_DEFAULT); + private TabularDataSupport _messages = null; private ManagedQueue _qmb; - static final String MSG_AMQ_ID = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[0]; - static final String MSG_HEADER = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[1]; - static final String MSG_SIZE = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[2]; - static final String MSG_REDELIVERED = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[3]; - static final String MSG_QUEUE_POS = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[4]; + private static final String FROM_DEFAULT = "1"; + private static final String TO_DEFAULT = "50"; + private long INTERVAL = 50; + + private static final String MSG_AMQ_ID = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[0]; + private static final String MSG_HEADER = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[1]; + private static final String MSG_SIZE = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[2]; + private static final String MSG_REDELIVERED = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[3]; + private static final String MSG_QUEUE_POS = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[4]; public QueueOperationsTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc) { @@ -139,19 +151,31 @@ public class QueueOperationsTabControl extends TabControl _messages = null; try { - //gather a list of all messages on the queue for display and selection - _messages = (TabularDataSupport) _qmb.viewMessages(1,Integer.MAX_VALUE); - - //TODO - viewMessages takes int args, limiting number of messages which can be viewed - //to the first 2^32 messages on the queue at the time of invocation. - //For consistency with other methods, expand values to Long by introducing a new method. - //Use AMQ ID or current 'position in queue' numbering scheme ?? + if(_ApiVersion.greaterThanOrEqualTo(1, 3)) + { //broker supports Qpid JMX API 1.3 and takes Long values + + //gather a list of all messages on the queue for display and selection + _messages = (TabularDataSupport) _qmb.viewMessages(_fromMsg,_toMsg); + } + else + { //broker supports Qpid JMX API 1.2 or below and takes int values + + if(_toMsg > Integer.MAX_VALUE || _toMsg > Integer.MAX_VALUE) + { + ViewUtility.popupErrorMessage("Error", "This broker only supports viewing up to message " + Integer.MAX_VALUE); + _tableViewer.setInput(null); + return; + } + + //gather a list of all messages on the queue for display and selection + _messages = (TabularDataSupport) _qmb.viewMessages(_fromMsg.intValue(), _toMsg.intValue()); + } } catch (Exception e) { MBeanUtility.handleException(mbean,e); } - + _tableViewer.setInput(_messages); layout(); @@ -172,6 +196,104 @@ public class QueueOperationsTabControl extends TabControl GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); messagesGroup.setLayoutData(gridData); + //from and to fields for selecting the viewing range + Composite viewMessageRangeComposite = _toolkit.createComposite(messagesGroup); + gridData = new GridData(SWT.LEFT, SWT.FILL, false, false); + viewMessageRangeComposite.setLayoutData(gridData); + viewMessageRangeComposite.setLayout(new GridLayout(8,false)); + + _toolkit.createLabel(viewMessageRangeComposite, "Queue pos: "); + _fromMsgText = new Text(viewMessageRangeComposite, SWT.BORDER); + _fromMsgText.setText(FROM_DEFAULT); + gridData = new GridData(SWT.LEFT, SWT.FILL, false, false); + gridData.widthHint = 75; + _fromMsgText.setLayoutData(gridData); + _fromMsgText.addVerifyListener(new NumberVerifyListener()); + _fromMsgText.addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.CR) + { + updateMessageInterval(); + } + } + }); + + _toolkit.createLabel(viewMessageRangeComposite, "to"); + + _toMsgText = new Text(viewMessageRangeComposite, SWT.BORDER); + _toMsgText.setText(TO_DEFAULT); + gridData = new GridData(SWT.LEFT, SWT.FILL, false, false); + gridData.widthHint = 75; + _toMsgText.setLayoutData(gridData); + _toMsgText.addVerifyListener(new NumberVerifyListener()); + _toMsgText.addKeyListener(new KeyAdapter() + { + public void keyPressed(KeyEvent event) + { + if (event.character == SWT.CR) + { + updateMessageInterval(); + } + } + }); + + final Button setButton = _toolkit.createButton(viewMessageRangeComposite, "Set", SWT.PUSH); + setButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false)); + setButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + updateMessageInterval(); + } + }); + + _toolkit.createLabel(viewMessageRangeComposite, " "); //spacer + + final Button previousButton = _toolkit.createButton(viewMessageRangeComposite, "< Prev " + INTERVAL, SWT.PUSH); + previousButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false)); + previousButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + //make 'to' be 'from - 1' unless from is 1 (ie there are no previous messages) + if(_fromMsg > 1) + { + _toMsg = _fromMsg - 1; + _toMsgText.setText(_toMsg.toString()); + } + + //make 'from' be 'from - INTERVAL', or make it 1 if that would make it 0 or less + _fromMsg = (_fromMsg - INTERVAL < 1) ? 1 : _fromMsg - INTERVAL; + _fromMsgText.setText(_fromMsg.toString()); + + refresh(_mbean); + } + }); + + final Button nextButton = _toolkit.createButton(viewMessageRangeComposite, "Next " + INTERVAL + " >", SWT.PUSH); + nextButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false)); + nextButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + //make 'from' be 'to + 1' unless 'to' is already Long.MAX_VALUE + if(_toMsg != Long.MAX_VALUE) + { + _fromMsg = _toMsg + 1; + _fromMsgText.setText(_fromMsg.toString()); + } + + //make 'to' be 'to + INTERVAL', or make it Long.MAX_VALUE if that would too large + _toMsg = (Long.MAX_VALUE - _toMsg > INTERVAL) ? _toMsg + INTERVAL : Long.MAX_VALUE; + _toMsgText.setText(_toMsg.toString()); + + refresh(_mbean); + } + }); + + //message table Composite tableAndButtonsComposite = _toolkit.createComposite(messagesGroup); gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.minimumHeight = 220; @@ -268,9 +390,57 @@ public class QueueOperationsTabControl extends TabControl return; } - moveMessages(moveMessagesButton.getShell()); + moveOrCopyMessages(moveMessagesButton.getShell(), QueueOperations.MOVE); } }); + + final Button copyMessagesButton; + if(_ApiVersion.greaterThanOrEqualTo(1, 3))//if the server supports Qpid JMX API 1.3 + { + copyMessagesButton= _toolkit.createButton(buttonsComposite, "Copy Message(s) ...", SWT.PUSH); + copyMessagesButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); + copyMessagesButton.setEnabled(false); + copyMessagesButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_table.getSelectionIndex() == -1) + { + return; + } + + moveOrCopyMessages(copyMessagesButton.getShell(), QueueOperations.COPY); + } + }); + } + else + { + copyMessagesButton = null; + } + + final Button deleteMessagesButton; + if(_ApiVersion.greaterThanOrEqualTo(1, 3))//if the server supports Qpid JMX API 1.3 + { + deleteMessagesButton = _toolkit.createButton(buttonsComposite, "Delete Message(s) ...", SWT.PUSH); + deleteMessagesButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); + deleteMessagesButton.setEnabled(false); + deleteMessagesButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + if (_table.getSelectionIndex() == -1) + { + return; + } + + deleteMessages(deleteMessagesButton.getShell()); + } + }); + } + else + { + deleteMessagesButton = null; + } final Button clearQueueButton = _toolkit.createButton(buttonsComposite, "Clear Queue", SWT.PUSH); clearQueueButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); @@ -354,12 +524,28 @@ public class QueueOperationsTabControl extends TabControl redeliveredText.setText("-"); viewSelectedMsgButton.setEnabled(false); moveMessagesButton.setEnabled(false); - + if(copyMessagesButton != null) + { + copyMessagesButton.setEnabled(false); + } + if(deleteMessagesButton != null) + { + deleteMessagesButton.setEnabled(false); + } + return; } else { moveMessagesButton.setEnabled(true); + if(copyMessagesButton != null) + { + copyMessagesButton.setEnabled(true); + } + if(deleteMessagesButton != null) + { + deleteMessagesButton.setEnabled(true); + } final CompositeData selectedMsg = (CompositeData)_table.getItem(selectionIndex).getData(); Boolean redelivered = (Boolean) selectedMsg.get(MSG_REDELIVERED); @@ -386,7 +572,6 @@ public class QueueOperationsTabControl extends TabControl }); } - /** * Content Provider class for the table viewer @@ -504,6 +689,36 @@ public class QueueOperationsTabControl extends TabControl } } + private void updateMessageInterval() + { + Long from; + try + { + from = Long.valueOf(_fromMsgText.getText()); + } + catch(Exception e1) + { + ViewUtility.popupErrorMessage("Invalid Value", "Please enter a valid 'from' number"); + return; + } + + Long to; + try + { + to = Long.valueOf(_toMsgText.getText()); + } + catch(Exception e1) + { + ViewUtility.popupErrorMessage("Invalid Value", "Please enter a valid 'to' number"); + return; + } + + _fromMsg = from; + _toMsg = to; + + refresh(_mbean); + } + private void viewMessageContent() { int selectionIndex = _table.getSelectionIndex(); @@ -546,7 +761,7 @@ public class QueueOperationsTabControl extends TabControl shell.dispose(); } - private void moveMessages(final Shell parent) + private void moveOrCopyMessages(final Shell parent, final QueueOperations op) { final ArrayList<Long> rangeStarts = new ArrayList<Long>(); final ArrayList<Long> rangeEnds = new ArrayList<Long>(); @@ -554,14 +769,34 @@ public class QueueOperationsTabControl extends TabControl gatherSelectedAMQMsgIDRanges(rangeStarts,rangeEnds); String rangeString = getRangesString(rangeStarts,rangeEnds); - final Shell shell = ViewUtility.createModalDialogShell(parent, "Move Messages"); + String windowTitle; + String dialogueMessage; + final String feedBackMessage; + final String failureFeedBackMessage; + + if(op.equals(QueueOperations.MOVE)) + { + windowTitle = "Move Messages"; + dialogueMessage = "Move message(s) with AMQ ID:"; + feedBackMessage = "Messages moved"; + failureFeedBackMessage = "Error moving messages"; + } + else + { + windowTitle = "Copy Messages"; + dialogueMessage = "Copy message(s) with AMQ ID:"; + feedBackMessage = "Messages copied"; + failureFeedBackMessage = "Error copying messages"; + } + + final Shell shell = ViewUtility.createModalDialogShell(parent, windowTitle); Composite idComposite = _toolkit.createComposite(shell, SWT.NONE); idComposite.setBackground(shell.getBackground()); idComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); idComposite.setLayout(new GridLayout()); - _toolkit.createLabel(idComposite,"Move message(s) with AMQ ID:").setBackground(shell.getBackground()); + _toolkit.createLabel(idComposite,dialogueMessage).setBackground(shell.getBackground()); _toolkit.createLabel(idComposite,rangeString).setBackground(shell.getBackground()); Composite destinationComposite = _toolkit.createComposite(shell, SWT.NONE); @@ -611,14 +846,91 @@ public class QueueOperationsTabControl extends TabControl Long from = rangeStarts.get(i); Long to = rangeEnds.get(i); - _qmb.moveMessages(Long.valueOf(from), Long.valueOf(to), destQueue); + switch(op) + { + case COPY: + _qmb.copyMessages(Long.valueOf(from), Long.valueOf(to), destQueue); + break; + case MOVE: + _qmb.moveMessages(Long.valueOf(from), Long.valueOf(to), destQueue); + break; + } } - ViewUtility.operationResultFeedback(null, "Messages moved", null); + ViewUtility.operationResultFeedback(null, feedBackMessage, null); + } + catch (Exception e4) + { + ViewUtility.operationFailedStatusBarMessage(failureFeedBackMessage); + MBeanUtility.handleException(_mbean, e4); + } + + refresh(_mbean); + } + }); + + cancelButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + shell.dispose(); + } + }); + + shell.setDefaultButton(okButton); + shell.pack(); + shell.open(); + } + + private void deleteMessages(final Shell parent) + { + final ArrayList<Long> rangeStarts = new ArrayList<Long>(); + final ArrayList<Long> rangeEnds = new ArrayList<Long>(); + + gatherSelectedAMQMsgIDRanges(rangeStarts,rangeEnds); + String rangeString = getRangesString(rangeStarts,rangeEnds); + + final Shell shell = ViewUtility.createModalDialogShell(parent, "Delete Messages"); + + Composite idComposite = _toolkit.createComposite(shell, SWT.NONE); + idComposite.setBackground(shell.getBackground()); + idComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + idComposite.setLayout(new GridLayout()); + + _toolkit.createLabel(idComposite,"Delete message(s) with AMQ ID:").setBackground(shell.getBackground()); + _toolkit.createLabel(idComposite,rangeString).setBackground(shell.getBackground()); + + Composite okCancelButtonsComp = _toolkit.createComposite(shell); + okCancelButtonsComp.setBackground(shell.getBackground()); + okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true)); + okCancelButtonsComp.setLayout(new GridLayout(2,false)); + + Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH); + okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); + Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH); + cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false)); + + okButton.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) + { + shell.dispose(); + + try + { + for(int i=0 ; i < rangeStarts.size() ; i++) + { + Long from = rangeStarts.get(i); + Long to = rangeEnds.get(i); + + _qmb.deleteMessages(Long.valueOf(from), Long.valueOf(to)); + } + + ViewUtility.operationResultFeedback(null, "Messages deleted", null); } catch (Exception e4) { - ViewUtility.operationFailedStatusBarMessage("Error moving messages"); + ViewUtility.operationFailedStatusBarMessage("Error deleting messages"); MBeanUtility.handleException(_mbean, e4); } @@ -709,4 +1021,10 @@ public class QueueOperationsTabControl extends TabControl return idRangesString.concat("."); } + + private enum QueueOperations + { + MOVE, + COPY; + } } |