diff options
| author | Martin Ritchie <ritchiem@apache.org> | 2006-10-02 09:35:48 +0000 |
|---|---|---|
| committer | Martin Ritchie <ritchiem@apache.org> | 2006-10-02 09:35:48 +0000 |
| commit | 6c9ceb7d0aa66648316b44b0bae1dc383ba04722 (patch) | |
| tree | b6b5d400eb12fe33809becad5b8a55e64a3660a5 /java/broker | |
| parent | ce57f0694a13529ab6feb8d10a7f4c8935368bb0 (diff) | |
| download | qpid-python-6c9ceb7d0aa66648316b44b0bae1dc383ba04722.tar.gz | |
Changes for JMX layer-
MBeans are decorated with descriptions using annotations for attributes, operations and operation parameters. Introspection added for management interface.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@451932 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker')
22 files changed, 1081 insertions, 265 deletions
diff --git a/java/broker/src/org/apache/qpid/server/AMQChannel.java b/java/broker/src/org/apache/qpid/server/AMQChannel.java index 7cd9277c89..f009e52488 100644 --- a/java/broker/src/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/org/apache/qpid/server/AMQChannel.java @@ -23,9 +23,6 @@ import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.ContentBody; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.server.exchange.MessageRouter; -import org.apache.qpid.server.management.DefaultManagedObject; -import org.apache.qpid.server.management.Managable; -import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; @@ -33,8 +30,6 @@ import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.TxnBuffer; import org.apache.qpid.server.txn.TxnOp; -import javax.management.JMException; -import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import java.util.Iterator; @@ -45,8 +40,7 @@ import java.util.TreeMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; - -public class AMQChannel implements Managable +public class AMQChannel { public static final int DEFAULT_PREFETCH = 5000; @@ -54,8 +48,6 @@ public class AMQChannel implements Managable private final int _channelId; - private final String _channelName; - private boolean _transactional; private long _prefetchCount; @@ -102,83 +94,6 @@ public class AMQChannel implements Managable private final TxnBuffer _txnBuffer; - private final AMQChannelMBean _managedObject; - - public ManagedObject getManagedObject() - { - return _managedObject; - } - - /** - * MBean interface for the implementation AMQChannelMBean - */ - public interface AMQChannelMBeanMBean extends ManagedChannel - { - - } - - /** - * AMQChannelMBean. It implements the management interface exposed for - * monitoring and managing the channel. - */ - public final class AMQChannelMBean extends DefaultManagedObject implements AMQChannelMBeanMBean - { - public AMQChannelMBean() - { - super(ManagedChannel.class, ManagedChannel.TYPE); - } - - public String getObjectInstanceName() - { - return _channelName; - } - - public boolean isTransactional() - { - return _transactional; - } - - public int getUnacknowledgedMessageCount() - { - return _unacknowledgedMessageMap.size(); - } - - public void commitTransactions() throws JMException - { - try - { - if (_transactional) - { - _txnBuffer.commit(); - } - } - catch (AMQException ex) - { - throw new MBeanException(ex, ex.toString()); - } - } - - public void rollbackTransactions() throws JMException - { - if (_transactional) - { - synchronized(_txnBuffer) - { - try - { - _txnBuffer.rollback(); - } - catch (AMQException ex) - { - throw new MBeanException(ex, ex.toString()); - } - } - } - } - - } // End of MBean class - - public static class UnacknowledgedMessage { public final AMQMessage message; @@ -206,14 +121,10 @@ public class AMQChannel implements Managable throws AMQException { _channelId = channelId; - _channelName = _channelId + "-" + this.hashCode(); _prefetchCount = DEFAULT_PREFETCH; _messageStore = messageStore; _exchanges = exchanges; _txnBuffer = new TxnBuffer(_messageStore); - - _managedObject = new AMQChannelMBean(); - _managedObject.register(); } public int getChannelId() @@ -370,7 +281,6 @@ public class AMQChannel implements Managable } unsubscribeAllConsumers(session); requeue(); - _managedObject.unregister(); } private void unsubscribeAllConsumers(AMQProtocolSession session) throws AMQException diff --git a/java/broker/src/org/apache/qpid/server/Main.java b/java/broker/src/org/apache/qpid/server/Main.java index dee6f76334..13dc5fbca6 100644 --- a/java/broker/src/org/apache/qpid/server/Main.java +++ b/java/broker/src/org/apache/qpid/server/Main.java @@ -26,9 +26,7 @@ import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.management.DefaultManagedObject; -import org.apache.qpid.server.management.ManagedBroker; -import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.management.*; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.exchange.ExchangeRegistry; @@ -48,10 +46,12 @@ import org.apache.mina.common.SimpleByteBufferAllocator; import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig; -import javax.management.ObjectName; -import javax.management.MalformedObjectNameException; import javax.management.JMException; import javax.management.MBeanException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.management.MalformedObjectNameException; + import java.io.File; import java.io.IOException; import java.net.InetAddress; @@ -430,32 +430,33 @@ public class Main implements ProtocolVersionList } } - private void createAndRegisterBrokerMBean() - throws AMQException + private void createAndRegisterBrokerMBean() throws AMQException { - new AMQBrokerManager().register(); + try + { + new AMQBrokerManager().register(); + } + catch (NotCompliantMBeanException ex) + { + throw new AMQException("Exception occured in creating AMQBrokerManager MBean."); + } } /** - * MBean interface for the implementation AMQBrokerManager. - */ - public interface AMQBrokerManagerMBean extends ManagedBroker - { - - } - /** * AMQPBrokerMBean implements the broker management interface and exposes the * Broker level management features like creating and deleting exchanges and queue. */ - private final class AMQBrokerManager extends DefaultManagedObject - implements AMQBrokerManagerMBean + @MBeanDescription("This MBean exposes the broker level management features") + private final class AMQBrokerManager extends AMQManagedObject + implements ManagedBroker { private final QueueRegistry _queueRegistry; private final ExchangeRegistry _exchangeRegistry; private final ExchangeFactory _exchangeFactory; private final MessageStore _messageStore; - protected AMQBrokerManager() + @MBeanConstructor("Creates the Broker Manager MBean") + protected AMQBrokerManager() throws NotCompliantMBeanException { super(ManagedBroker.class, ManagedBroker.TYPE); diff --git a/java/broker/src/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/org/apache/qpid/server/exchange/AbstractExchange.java index e11de152d0..cf787b4739 100644 --- a/java/broker/src/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/java/broker/src/org/apache/qpid/server/exchange/AbstractExchange.java @@ -18,10 +18,12 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; -import org.apache.qpid.server.management.DefaultManagedObject; +import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; +import javax.management.NotCompliantMBeanException; + public abstract class AbstractExchange implements Exchange, Managable { private String _name; @@ -42,9 +44,9 @@ public abstract class AbstractExchange implements Exchange, Managable * management intrerface for exchanges. Any implementaion of an * Exchange MBean should extend this class. */ - protected abstract class ExchangeMBean extends DefaultManagedObject implements ManagedExchange + protected abstract class ExchangeMBean extends AMQManagedObject implements ManagedExchange { - public ExchangeMBean() + public ExchangeMBean() throws NotCompliantMBeanException { super(ManagedExchange.class, ManagedExchange.TYPE); } @@ -59,7 +61,7 @@ public abstract class AbstractExchange implements Exchange, Managable return _name; } - public int getTicketNo() + public Integer getTicketNo() { return _ticket; } @@ -86,7 +88,7 @@ public abstract class AbstractExchange implements Exchange, Managable * called during initialisation (template method pattern). * @return the MBean */ - protected abstract ExchangeMBean createMBean(); + protected abstract ExchangeMBean createMBean() throws AMQException; public void initialise(String name, boolean durable, int ticket, boolean autoDelete) throws AMQException { diff --git a/java/broker/src/org/apache/qpid/server/exchange/DestNameExchange.java b/java/broker/src/org/apache/qpid/server/exchange/DestNameExchange.java index a703595cc4..f89223825f 100644 --- a/java/broker/src/org/apache/qpid/server/exchange/DestNameExchange.java +++ b/java/broker/src/org/apache/qpid/server/exchange/DestNameExchange.java @@ -21,15 +21,17 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.MBeanConstructor; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import javax.management.JMException; import javax.management.MBeanException; +import javax.management.NotCompliantMBeanException; import javax.management.openmbean.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -45,6 +47,7 @@ public class DestNameExchange extends AbstractExchange /** * MBean class implementing the management interfaces. */ + @MBeanDescription("Management Bean for Direct Exchange") private final class DestNameExchangeMBean extends ExchangeMBean { private String[] _bindingItemNames = {"BindingKey", "QueueNames"}; @@ -56,7 +59,8 @@ public class DestNameExchange extends AbstractExchange private TabularType _bindinglistDataType = null; private TabularDataSupport _bindingList = null; - public DestNameExchangeMBean() + @MBeanConstructor("Creates an MBean for AMQ direct exchange") + public DestNameExchangeMBean() throws NotCompliantMBeanException { super(); init(); @@ -142,9 +146,17 @@ public class DestNameExchange extends AbstractExchange }// End of MBean class - protected ExchangeMBean createMBean() + protected ExchangeMBean createMBean() throws AMQException { - return new DestNameExchangeMBean(); + try + { + return new DestNameExchangeMBean(); + } + catch (NotCompliantMBeanException ex) + { + _logger.error("Exception occured in creating the DestNameExchenge", ex); + throw new AMQException("Exception occured in creating the DestNameExchenge", ex); + } } public void registerQueue(String routingKey, AMQQueue queue, FieldTable args) throws AMQException diff --git a/java/broker/src/org/apache/qpid/server/exchange/DestWildExchange.java b/java/broker/src/org/apache/qpid/server/exchange/DestWildExchange.java index 16b35cf6fa..25d91027e9 100644 --- a/java/broker/src/org/apache/qpid/server/exchange/DestWildExchange.java +++ b/java/broker/src/org/apache/qpid/server/exchange/DestWildExchange.java @@ -24,10 +24,13 @@ import org.apache.qpid.framing.BasicPublishBody; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQMessage; import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.MBeanConstructor; import javax.management.openmbean.*; import javax.management.JMException; import javax.management.MBeanException; +import javax.management.NotCompliantMBeanException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -44,6 +47,7 @@ public class DestWildExchange extends AbstractExchange * DestWildExchangeMBean class implements the management interface for the * Topic exchanges. */ + @MBeanDescription("Management Bean for Topic Exchange") private final class DestWildExchangeMBean extends ExchangeMBean { private String[] _bindingItemNames = {"BindingKey", "QueueNames"}; @@ -55,7 +59,8 @@ public class DestWildExchange extends AbstractExchange private TabularType _bindinglistDataType = null; private TabularDataSupport _bindingList = null; - public DestWildExchangeMBean() + @MBeanConstructor("Creates an MBean for AMQ topic exchange") + public DestWildExchangeMBean() throws NotCompliantMBeanException { super(); init(); @@ -203,8 +208,16 @@ public class DestWildExchange extends AbstractExchange } } - protected ExchangeMBean createMBean() + protected ExchangeMBean createMBean() throws AMQException { - return new DestWildExchangeMBean(); + try + { + return new DestWildExchangeMBean(); + } + catch (NotCompliantMBeanException ex) + { + _logger.error("Exception occured in creating the DestWildExchenge", ex); + throw new AMQException("Exception occured in creating the DestWildExchenge", ex); + } } } diff --git a/java/broker/src/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/org/apache/qpid/server/exchange/HeadersExchange.java index 83475f87f2..1167d05875 100644 --- a/java/broker/src/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/org/apache/qpid/server/exchange/HeadersExchange.java @@ -22,9 +22,12 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.*; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.MBeanConstructor; import javax.management.openmbean.*; import javax.management.ServiceNotFoundException; +import javax.management.NotCompliantMBeanException; import java.util.concurrent.CopyOnWriteArrayList; import java.util.ArrayList; import java.util.Iterator; @@ -68,6 +71,7 @@ public class HeadersExchange extends AbstractExchange * HeadersExchangeMBean class implements the management interface for the * Header Exchanges. */ + @MBeanDescription("Management Bean for Headers Exchange") private final class HeadersExchangeMBean extends ExchangeMBean { private String[] _bindingItemNames = {"Queue", "HeaderBinding"}; @@ -79,7 +83,8 @@ public class HeadersExchange extends AbstractExchange private TabularType _bindinglistDataType = null; private TabularDataSupport _bindingList = null; - public HeadersExchangeMBean() + @MBeanConstructor("Creates an MBean for AMQ Headers exchange") + public HeadersExchangeMBean() throws NotCompliantMBeanException { super(); init(); @@ -197,9 +202,17 @@ public class HeadersExchange extends AbstractExchange return ((BasicContentHeaderProperties) contentHeaderFrame.properties).getHeaders(); } - protected ExchangeMBean createMBean() + protected ExchangeMBean createMBean() throws AMQException { - return new HeadersExchangeMBean(); + try + { + return new HeadersExchangeMBean(); + } + catch (NotCompliantMBeanException ex) + { + _logger.error("Exception occured in creating the HeadersExchangeMBean", ex); + throw new AMQException("Exception occured in creating the HeadersExchangeMBean", ex); + } } private static class Registration diff --git a/java/broker/src/org/apache/qpid/server/exchange/ManagedExchange.java b/java/broker/src/org/apache/qpid/server/exchange/ManagedExchange.java index a434ecb443..bd02910d0a 100644 --- a/java/broker/src/org/apache/qpid/server/exchange/ManagedExchange.java +++ b/java/broker/src/org/apache/qpid/server/exchange/ManagedExchange.java @@ -17,8 +17,13 @@ */ package org.apache.qpid.server.exchange; +import org.apache.qpid.server.management.MBeanAttribute; +import org.apache.qpid.server.management.MBeanOperation; +import org.apache.qpid.server.management.MBeanOperationParameter; + import javax.management.openmbean.TabularData; import javax.management.JMException; +import javax.management.MBeanOperationInfo; import java.io.IOException; /** @@ -36,13 +41,18 @@ public interface ManagedExchange * @return the name of the exchange. * @throws IOException */ + @MBeanAttribute(name="Name", description="Name of exchange") String getName() throws IOException; + @MBeanAttribute(name="TicketNo", description="Exchange Ticket No") + Integer getTicketNo() throws IOException; + /** * Tells if the exchange is durable or not. * @return true if the exchange is durable. * @throws IOException */ + @MBeanAttribute(name="Durable", description="true if Exchange is durable") boolean isDurable() throws IOException; /** @@ -50,11 +60,9 @@ public interface ManagedExchange * @return true if the exchange is set as autodelete. * @throws IOException */ + @MBeanAttribute(name="AutoDelete", description="true if Exchange is AutoDelete") boolean isAutoDelete() throws IOException; - int getTicketNo() throws IOException; - - // Operations /** @@ -63,16 +71,20 @@ public interface ManagedExchange * @throws IOException * @throws JMException */ - TabularData viewBindings() - throws IOException, JMException; + @MBeanOperation(name="viewBindings", description="view the queue bindings for this exchange") + TabularData viewBindings() throws IOException, JMException; /** * Creates new binding with the given queue and binding. - * @param QueueName + * @param queueName * @param binding * @throws JMException */ - void createBinding(String QueueName, String binding) + @MBeanOperation(name="createBinding", + description="create a new binding with this exchange", + impact= MBeanOperationInfo.ACTION) + void createBinding(@MBeanOperationParameter(name="queue name", description="queue name") String queueName, + @MBeanOperationParameter(name="binding", description="queue binding")String binding) throws JMException; }
\ No newline at end of file diff --git a/java/broker/src/org/apache/qpid/server/management/AMQManagedObject.java b/java/broker/src/org/apache/qpid/server/management/AMQManagedObject.java index fea955b93b..a5733ed4ef 100644 --- a/java/broker/src/org/apache/qpid/server/management/AMQManagedObject.java +++ b/java/broker/src/org/apache/qpid/server/management/AMQManagedObject.java @@ -18,6 +18,9 @@ package org.apache.qpid.server.management; import javax.management.ListenerNotFoundException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.NotCompliantMBeanException; import javax.management.NotificationBroadcaster; import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationFilter; @@ -42,11 +45,32 @@ public abstract class AMQManagedObject extends DefaultManagedObject */ protected long _notificationSequenceNumber = 0; + protected MBeanInfo _mbeanInfo; + protected AMQManagedObject(Class<?> managementInterface, String typeName) + throws NotCompliantMBeanException { - super(managementInterface, typeName); + super(managementInterface, typeName); + buildMBeanInfo(); + } + + @Override + public MBeanInfo getMBeanInfo() + { + return _mbeanInfo; } + private void buildMBeanInfo() throws NotCompliantMBeanException + { + _mbeanInfo = new MBeanInfo(this.getClass().getName(), + MBeanIntrospector.getMBeanDescription(this.getClass()), + MBeanIntrospector.getMBeanAttributesInfo(getManagementInterface()), + MBeanIntrospector.getMBeanConstructorsInfo(this.getClass()), + MBeanIntrospector.getMBeanOperationsInfo(getManagementInterface()), + this.getNotificationInfo()); + } + + // notification broadcaster implementation @@ -62,4 +86,9 @@ public abstract class AMQManagedObject extends DefaultManagedObject { _broadcaster.removeNotificationListener(listener); } + + public MBeanNotificationInfo[] getNotificationInfo() + { + return null; + } } diff --git a/java/broker/src/org/apache/qpid/server/management/DefaultManagedObject.java b/java/broker/src/org/apache/qpid/server/management/DefaultManagedObject.java index bb8603f8b4..cd0d58acdb 100644 --- a/java/broker/src/org/apache/qpid/server/management/DefaultManagedObject.java +++ b/java/broker/src/org/apache/qpid/server/management/DefaultManagedObject.java @@ -20,22 +20,27 @@ package org.apache.qpid.server.management; import org.apache.qpid.AMQException; import org.apache.qpid.server.registry.ApplicationRegistry; -import javax.management.ObjectName; +import javax.management.JMException; import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.management.StandardMBean; /** * Provides implementation of the boilerplate ManagedObject interface. Most managed objects should find it useful * to extend this class rather than implementing ManagedObject from scratch. * */ -public abstract class DefaultManagedObject implements ManagedObject +public abstract class DefaultManagedObject extends StandardMBean implements ManagedObject { private Class<?> _managementInterface; private String _typeName; protected DefaultManagedObject(Class<?> managementInterface, String typeName) + throws NotCompliantMBeanException { + super(managementInterface); _managementInterface = managementInterface; _typeName = typeName; } @@ -50,13 +55,18 @@ public abstract class DefaultManagedObject implements ManagedObject return _managementInterface; } + public ManagedObject getParentObject() + { + return null; + } + public void register() throws AMQException { try { ApplicationRegistry.getInstance().getManagedObjectRegistry().registerObject(this); } - catch (Exception e) + catch (JMException e) { throw new AMQException("Error registering managed object " + this + ": " + e, e); } @@ -68,7 +78,7 @@ public abstract class DefaultManagedObject implements ManagedObject { ApplicationRegistry.getInstance().getManagedObjectRegistry().unregisterObject(this); } - catch (Exception e) + catch (JMException e) { throw new AMQException("Error unregistering managed object: " + this + ": " + e, e); } @@ -87,15 +97,47 @@ public abstract class DefaultManagedObject implements ManagedObject public ObjectName getObjectName() throws MalformedObjectNameException { - String name = jmxEncode(new StringBuffer(getObjectInstanceName()), 0).toString(); + String name = getObjectInstanceName(); StringBuffer objectName = new StringBuffer(ManagedObject.DOMAIN); - objectName.append(":type=").append(getType()); - objectName.append(",name=").append(name); + + objectName.append(":type="); + objectName.append(getHierarchicalType(this)); + + objectName.append(","); + objectName.append(getHierarchicalName(this)); + objectName.append("name=").append(name); return new ObjectName(objectName.toString()); } - private static StringBuffer jmxEncode(StringBuffer jmxName, int attrPos) + private String getHierarchicalType(ManagedObject obj) + { + String parentType = null; + if (obj.getParentObject() != null) + { + parentType = getHierarchicalType(obj.getParentObject()).toString(); + return parentType + "." + obj.getType(); + } + else + return obj.getType(); + } + + private String getHierarchicalName(ManagedObject obj) + { + String parentName = null; + if (obj.getParentObject() != null) + { + parentName = obj.getParentObject().getType() + "=" + + obj.getParentObject().getObjectInstanceName() + ","+ + getHierarchicalName(obj.getParentObject()); + + return parentName; + } + else + return ""; + } + + protected static StringBuffer jmxEncode(StringBuffer jmxName, int attrPos) { for (int i = attrPos; i < jmxName.length(); i++) { diff --git a/java/broker/src/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/java/broker/src/org/apache/qpid/server/management/JMXManagedObjectRegistry.java index d556973970..0cd43cecac 100644 --- a/java/broker/src/org/apache/qpid/server/management/JMXManagedObjectRegistry.java +++ b/java/broker/src/org/apache/qpid/server/management/JMXManagedObjectRegistry.java @@ -21,8 +21,6 @@ import org.apache.log4j.Logger; import javax.management.JMException; import javax.management.MBeanServer; -import javax.management.NotCompliantMBeanException; -import javax.management.StandardMBean; import java.lang.management.ManagementFactory; public class JMXManagedObjectRegistry implements ManagedObjectRegistry @@ -40,22 +38,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry public void registerObject(ManagedObject managedObject) throws JMException { - try - { - _mbeanServer.registerMBean(managedObject, managedObject.getObjectName()); - } - catch(NotCompliantMBeanException ex) - { - // The following is a hack due to a silly change to StandardMBean in JDK 1.6 - // They have added in generics to get compile time safety which reduces the - // flexibility - Object o = managedObject; - Class<Object> clazz = (Class<Object>) managedObject.getManagementInterface(); - StandardMBean mbean = new StandardMBean(o, clazz); - - _mbeanServer.registerMBean(mbean, managedObject.getObjectName()); - } - + _mbeanServer.registerMBean(managedObject, managedObject.getObjectName()); } public void unregisterObject(ManagedObject managedObject) throws JMException diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanAttribute.java b/java/broker/src/org/apache/qpid/server/management/MBeanAttribute.java new file mode 100644 index 0000000000..595c97dd76 --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanAttribute.java @@ -0,0 +1,39 @@ +package org.apache.qpid.server.management; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Annotation for MBean attributes. This should be used with getter or setter + * methods of attributes. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Inherited +public @interface MBeanAttribute +{ + String name(); + String description(); +} diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanConstructor.java b/java/broker/src/org/apache/qpid/server/management/MBeanConstructor.java new file mode 100644 index 0000000000..2ce275d50d --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanConstructor.java @@ -0,0 +1,37 @@ +package org.apache.qpid.server.management; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Annotation for MBean constructors. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.CONSTRUCTOR) +@Inherited +public @interface MBeanConstructor +{ + String value(); +} diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanDescription.java b/java/broker/src/org/apache/qpid/server/management/MBeanDescription.java new file mode 100644 index 0000000000..ef6993036f --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanDescription.java @@ -0,0 +1,36 @@ +package org.apache.qpid.server.management; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Annotation for MBean class. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface MBeanDescription { + String value(); +} diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanIntrospector.java b/java/broker/src/org/apache/qpid/server/management/MBeanIntrospector.java new file mode 100644 index 0000000000..dcf05fa6fe --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanIntrospector.java @@ -0,0 +1,385 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.server.management; + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.NotCompliantMBeanException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * This class is a utility class to introspect the MBean class and the management + * interface class for various purposes. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +class MBeanIntrospector { + + private static final String _defaultAttributeDescription = "Management attribute"; + private static final String _defaultOerationDescription = "Management operation"; + private static final String _defaultConstructorDescription = "MBean constructor"; + private static final String _defaultMbeanDescription = "Management interface of the MBean"; + + /** + * Introspects the management interface class for MBean attributes. + * @param interfaceClass + * @return MBeanAttributeInfo[] + * @throws NotCompliantMBeanException + */ + static MBeanAttributeInfo[] getMBeanAttributesInfo(Class interfaceClass) + throws NotCompliantMBeanException + { + List<MBeanAttributeInfo> attributesList = new ArrayList<MBeanAttributeInfo>(); + + /** + * Using reflection, all methods of the managemetn interface will be analysed, + * and MBeanInfo will be created. + */ + for (Method method : interfaceClass.getMethods()) + { + int argCount = method.getParameterTypes().length; + String name = method.getName(); + Class<?> resultType = method.getReturnType(); + MBeanAttributeInfo attributeInfo = null; + + if (isAttributeGetterMethod(method)) + { + String desc = getAttributeDescription(method); + attributeInfo = new MBeanAttributeInfo(name.substring(3), + resultType.getName(), + desc, + true, + false, + false); + int index = getIndexIfAlreadyExists(attributeInfo, attributesList); + if (index == -1) + { + attributesList.add(attributeInfo); + } + else + { + attributeInfo = new MBeanAttributeInfo(name.substring(3), + resultType.getName(), + desc, + true, + true, + false); + attributesList.set(index, attributeInfo); + } + } + else if (isAttributeSetterMethod(method)) + { + String desc = getAttributeDescription(method); + attributeInfo = new MBeanAttributeInfo(name.substring(3), + method.getParameterTypes()[0].getName(), + desc, + false, + true, + false); + int index = getIndexIfAlreadyExists(attributeInfo, attributesList); + if (index == -1) + { + attributesList.add(attributeInfo); + } + else + { + attributeInfo = new MBeanAttributeInfo(name.substring(3), + method.getParameterTypes()[0].getName(), + desc, + true, + true, + false); + attributesList.set(index, attributeInfo); + } + } + else if (isAttributeBoolean(method)) + { + attributeInfo = new MBeanAttributeInfo(name.substring(2), + resultType.getName(), + getAttributeDescription(method), + true, + false, + true); + attributesList.add(attributeInfo); + } + } + + return attributesList.toArray(new MBeanAttributeInfo[0]); + } + + /** + * Introspects the management interface class for management operations. + * @param interfaceClass + * @return MBeanOperationInfo[] + */ + static MBeanOperationInfo[] getMBeanOperationsInfo(Class interfaceClass) + { + List<MBeanOperationInfo> operationsList = new ArrayList<MBeanOperationInfo>(); + + for (Method method : interfaceClass.getMethods()) + { + if (!isAttributeGetterMethod(method) && + !isAttributeSetterMethod(method) && + !isAttributeBoolean(method)) + { + operationsList.add(getOperationInfo(method)); + } + } + + return operationsList.toArray(new MBeanOperationInfo[0]); + } + + /** + * Checks if the method is an attribute getter method. + * @param method + * @return true if the method is an attribute getter method. + */ + private static boolean isAttributeGetterMethod(Method method) + { + if (!(method.getName().equals("get")) && + method.getName().startsWith("get") && + method.getParameterTypes().length == 0 && + !method.getReturnType().equals(void.class)) + { + return true; + } + + return false; + } + + /** + * Checks if the method is an attribute setter method. + * @param method + * @return true if the method is an attribute setter method. + */ + private static boolean isAttributeSetterMethod(Method method) + { + if (!(method.getName().equals("set")) && + method.getName().startsWith("set") && + method.getParameterTypes().length == 1 && + method.getReturnType().equals(void.class)) + { + return true; + } + + return false; + } + + /** + * Checks if the attribute is a boolean and the method is a isX kind og method. + * @param method + * @return true if the method is an attribute isX type of method + */ + private static boolean isAttributeBoolean(Method method) + { + if (!(method.getName().equals("is")) && + method.getName().startsWith("is") && + method.getParameterTypes().length == 0 && + method.getReturnType().equals(boolean.class)) + { + return true; + } + + return false; + } + + /** + * Helper method to retrieve the attribute index from the list of attributes. + * @param attribute + * @param list + * @return attribute index no. -1 if attribtue doesn't exist + * @throws NotCompliantMBeanException + */ + private static int getIndexIfAlreadyExists(MBeanAttributeInfo attribute, + List<MBeanAttributeInfo> list) + throws NotCompliantMBeanException + { + String exceptionMsg = "Conflicting attribute methods for attribute " + attribute.getName(); + + for (MBeanAttributeInfo memberAttribute : list) + { + if (attribute.getName().equals(memberAttribute.getName())) + { + if (!attribute.getType().equals(memberAttribute.getType())) + { + throw new NotCompliantMBeanException(exceptionMsg); + } + if (attribute.isReadable() && memberAttribute.isReadable()) + { + if (attribute.isIs() != memberAttribute.isIs()) + { + throw new NotCompliantMBeanException(exceptionMsg); + } + } + + return list.indexOf(memberAttribute); + } + } + + return -1; + } + + /** + * Retrieves the attribute description from annotation + * @param attributeMethod + * @return attribute description + */ + private static String getAttributeDescription(Method attributeMethod) + { + MBeanAttribute anno = attributeMethod.getAnnotation(MBeanAttribute.class); + if (anno != null) + { + return anno.description(); + } + return _defaultAttributeDescription; + } + + /** + * Introspects the method to retrieve the operation information. + * @param operation + * @return MBeanOperationInfo + */ + private static MBeanOperationInfo getOperationInfo(Method operation) + { + MBeanOperationInfo operationInfo = null; + Class<?> returnType = operation.getReturnType(); + + MBeanParameterInfo[] paramsInfo = getParametersInfo(operation.getParameterAnnotations(), + operation.getParameterTypes()); + + String operationDesc = _defaultOerationDescription; + int impact = MBeanOperationInfo.UNKNOWN; + + if (operation.getAnnotation(MBeanOperation.class) != null) + { + operationDesc = operation.getAnnotation(MBeanOperation.class).description(); + impact = operation.getAnnotation(MBeanOperation.class).impact(); + } + operationInfo = new MBeanOperationInfo(operation.getName(), + operationDesc, + paramsInfo, + returnType.getName(), + impact); + + return operationInfo; + } + + /** + * Constructs the parameter info. + * @param paramsAnno + * @param paramTypes + * @return MBeanParameterInfo[] + */ + private static MBeanParameterInfo[] getParametersInfo(Annotation[][] paramsAnno, + Class<?>[] paramTypes) + { + int noOfParams = paramsAnno.length; + + MBeanParameterInfo[] paramsInfo = new MBeanParameterInfo[noOfParams]; + + for (int i = 0; i < noOfParams; i++) + { + MBeanParameterInfo paramInfo = null; + String type = paramTypes[i].getName(); + for (Annotation anno : paramsAnno[i]) + { + String name,desc; + if (MBeanOperationParameter.class.isInstance(anno)) + { + name = MBeanOperationParameter.class.cast(anno).name(); + desc = MBeanOperationParameter.class.cast(anno).description(); + paramInfo = new MBeanParameterInfo(name, type, desc); + } + } + + + if (paramInfo == null) + { + paramInfo = new MBeanParameterInfo("p " + (i + 1), type, "parameter " + (i + 1)); + } + if (paramInfo != null) + paramsInfo[i] = paramInfo; + } + + return paramsInfo; + } + + /** + * Introspects the MBean class for constructors + * @param implClass + * @return MBeanConstructorInfo[] + */ + static MBeanConstructorInfo[] getMBeanConstructorsInfo(Class implClass) + { + List<MBeanConstructorInfo> constructors = new ArrayList<MBeanConstructorInfo>(); + + for (Constructor cons : implClass.getConstructors()) + { + MBeanConstructorInfo constructorInfo = getMBeanConstructorInfo(cons); + //MBeanConstructorInfo constructorInfo = new MBeanConstructorInfo("desc", cons); + if (constructorInfo != null) + constructors.add(constructorInfo); + } + + return constructors.toArray(new MBeanConstructorInfo[0]); + } + + /** + * Retrieves the constructor info from given constructor. + * @param cons + * @return MBeanConstructorInfo + */ + private static MBeanConstructorInfo getMBeanConstructorInfo(Constructor cons) + { + String desc = null; + Annotation anno = cons.getAnnotation(MBeanConstructor.class); + if (anno != null && MBeanConstructor.class.isInstance(anno)) + { + desc = MBeanConstructor.class.cast(anno).value(); + } + + //MBeanParameterInfo[] paramsInfo = getParametersInfo(cons.getParameterAnnotations(), + // cons.getParameterTypes()); + + return new MBeanConstructorInfo(cons.getName(), + desc != null ? _defaultConstructorDescription : desc , + null); + } + + /** + * Retrieves the description from the annotations of given class + * @param annotatedClass + * @return class description + */ + static String getMBeanDescription(Class annotatedClass) + { + Annotation anno = annotatedClass.getAnnotation(MBeanDescription.class); + if (anno != null && MBeanDescription.class.isInstance(anno)) + { + return MBeanDescription.class.cast(anno).value(); + } + return _defaultMbeanDescription; + } + +}
\ No newline at end of file diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanOperation.java b/java/broker/src/org/apache/qpid/server/management/MBeanOperation.java new file mode 100644 index 0000000000..30fdf81eee --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanOperation.java @@ -0,0 +1,40 @@ +package org.apache.qpid.server.management; + +import javax.management.MBeanOperationInfo; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Annotation for MBean operations. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Inherited +public @interface MBeanOperation +{ + String name(); + String description(); + int impact() default MBeanOperationInfo.INFO; +} diff --git a/java/broker/src/org/apache/qpid/server/management/MBeanOperationParameter.java b/java/broker/src/org/apache/qpid/server/management/MBeanOperationParameter.java new file mode 100644 index 0000000000..919ac767c7 --- /dev/null +++ b/java/broker/src/org/apache/qpid/server/management/MBeanOperationParameter.java @@ -0,0 +1,35 @@ +package org.apache.qpid.server.management; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Annotation for MBean operation parameters. + * @author Bhupendra Bhardwaj + * @version 0.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface MBeanOperationParameter { + String name(); + String description(); +} diff --git a/java/broker/src/org/apache/qpid/server/management/ManagedBroker.java b/java/broker/src/org/apache/qpid/server/management/ManagedBroker.java index ecf6123c7d..a38931a0d8 100644 --- a/java/broker/src/org/apache/qpid/server/management/ManagedBroker.java +++ b/java/broker/src/org/apache/qpid/server/management/ManagedBroker.java @@ -19,6 +19,7 @@ package org.apache.qpid.server.management; import javax.management.JMException; +import javax.management.MBeanOperationInfo; import java.io.IOException; /** @@ -41,7 +42,12 @@ public interface ManagedBroker * @throws IOException * @throws JMException */ - void createNewExchange(String name, String type, boolean durable, boolean passive) + @MBeanOperation(name="createNewExchange", description="Creates a new Exchange", + impact= MBeanOperationInfo.ACTION) + void createNewExchange(@MBeanOperationParameter(name="name", description="Name of the new exchange")String name, + @MBeanOperationParameter(name="excahnge type", description="Type of the exchange")String type, + @MBeanOperationParameter(name="durable", description="true if the Exchang should be durable")boolean durable, + @MBeanOperationParameter(name="passive", description="true of the Exchange should be passive")boolean passive) throws IOException, JMException; /** @@ -51,7 +57,10 @@ public interface ManagedBroker * @throws IOException * @throws JMException */ - void unregisterExchange(String exchange) + @MBeanOperation(name="unregisterExchange", + description="Unregisters all the related channels and queuebindings of this exchange", + impact= MBeanOperationInfo.ACTION) + void unregisterExchange(@MBeanOperationParameter(name="exchange name", description="Name of the exchange")String exchange) throws IOException, JMException; /** @@ -63,7 +72,12 @@ public interface ManagedBroker * @throws IOException * @throws JMException */ - void createQueue(String queueName, boolean durable, String owner, boolean autoDelete) + @MBeanOperation(name="createQueue", description="Create a new Queue on the Broker server", + impact= MBeanOperationInfo.ACTION) + void createQueue(@MBeanOperationParameter(name="queue name", description="Name of the new queue")String queueName, + @MBeanOperationParameter(name="durable", description="true if the queue should be durable")boolean durable, + @MBeanOperationParameter(name="owner", description="Owner name")String owner, + @MBeanOperationParameter(name="autoDelete", description="true if the queue should be auto delete") boolean autoDelete) throws IOException, JMException; /** @@ -73,6 +87,9 @@ public interface ManagedBroker * @throws IOException * @throws JMException */ - void deleteQueue(String queueName) + @MBeanOperation(name="deleteQueue", + description="Unregisters the Queue bindings, removes the subscriptions and deletes the queue", + impact= MBeanOperationInfo.ACTION) + void deleteQueue(@MBeanOperationParameter(name="queue name", description="Name of the queue")String queueName) throws IOException, JMException; } diff --git a/java/broker/src/org/apache/qpid/server/management/ManagedObject.java b/java/broker/src/org/apache/qpid/server/management/ManagedObject.java index 0643f84744..4007337173 100644 --- a/java/broker/src/org/apache/qpid/server/management/ManagedObject.java +++ b/java/broker/src/org/apache/qpid/server/management/ManagedObject.java @@ -40,6 +40,8 @@ public interface ManagedObject Class<?> getManagementInterface(); + ManagedObject getParentObject(); + void register() throws AMQException; void unregister() throws AMQException; diff --git a/java/broker/src/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index 80aa4756d2..35bc7fb4c7 100644 --- a/java/broker/src/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -18,34 +18,62 @@ package org.apache.qpid.server.protocol; import org.apache.log4j.Logger; -import org.apache.mina.common.IoSession; import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; import org.apache.mina.transport.vmpipe.VmPipeAddress; import org.apache.qpid.AMQChannelException; import org.apache.qpid.AMQException; import org.apache.qpid.codec.AMQCodecFactory; import org.apache.qpid.codec.AMQDecoder; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.framing.AMQFrame; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.ConnectionStartBody; +import org.apache.qpid.framing.ContentBody; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.HeartbeatBody; +import org.apache.qpid.framing.ProtocolInitiation; +import org.apache.qpid.framing.ProtocolVersionList; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.RequiredDeliveryException; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.management.DefaultManagedObject; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.management.MBeanConstructor; +import org.apache.qpid.server.management.MBeanDescription; +import org.apache.qpid.server.management.Managable; +import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.queue.QueueRegistry; +import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.state.AMQStateManager; -import javax.security.sasl.SaslServer; -import javax.management.ObjectName; +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.MBeanNotificationInfo; import javax.management.MalformedObjectNameException; -import javax.management.openmbean.*; +import javax.management.NotCompliantMBeanException; +import javax.management.Notification; +import javax.management.ObjectName; +import javax.management.monitor.MonitorNotification; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; +import javax.security.sasl.SaslServer; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersionList +public class AMQMinaProtocolSession implements AMQProtocolSession, + ProtocolVersionList, + Managable { private static final Logger _logger = Logger.getLogger(AMQProtocolSession.class); @@ -65,7 +93,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi private AMQCodecFactory _codecFactory; - private AMQProtocolSessionMBean _managedObject; + private ManagedAMQProtocolSession _managedObject; private SaslServer _saslServer; @@ -82,28 +110,39 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi private byte _major; private byte _minor; + public ManagedObject getManagedObject() + { + return _managedObject; + } + /** - * This class implements the management interface (is an MBean). In order to make more attributes, operations - * and notifications available over JMX simply augment the ManagedConnection interface and add the appropriate - * implementation here. + * This class implements the management interface (is an MBean). In order to + * make more attributes, operations and notifications available over JMX simply + * augment the ManagedConnection interface and add the appropriate implementation here. */ - private final class AMQProtocolSessionMBean extends DefaultManagedObject implements ManagedConnection + @MBeanDescription("Management Bean for an AMQ Broker Connection") + private final class ManagedAMQProtocolSession extends AMQManagedObject + implements ManagedConnection { + private String _name = null; /** * Represents the channel attributes sent with channel data. */ private String[] _channelAtttibuteNames = { "ChannelId", "ChannelName", "Transactional", - "DefaultQueue"}; + "DefaultQueue", + "UnacknowledgedMessageCount"}; private String[] _channelAttributeDescriptions = { "Channel Identifier", "Channel Name", "is Channel Transactional?", - "Default Queue Name" }; + "Default Queue Name", + "Unacknowledged Message Count"}; private OpenType[] _channelAttributeTypes = { SimpleType.INTEGER, SimpleType.OBJECTNAME, SimpleType.BOOLEAN, - SimpleType.STRING }; + SimpleType.STRING, + SimpleType.INTEGER}; /** * Channels in the list will be indexed according to channelId. */ @@ -120,7 +159,8 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi private TabularDataSupport _channelsList = null; - public AMQProtocolSessionMBean() + @MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection") + public ManagedAMQProtocolSession() throws NotCompliantMBeanException { super(ManagedConnection.class, ManagedConnection.TYPE); init(); @@ -131,6 +171,10 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi */ private void init() { + String remote = getRemoteAddress(); + remote = "anonymous".equals(remote) ? remote + hashCode() : remote; + _name = jmxEncode(new StringBuffer(remote), 0).toString(); + try { _channelType = new CompositeType("channel", @@ -162,30 +206,69 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi return _minaProtocolSession.getRemoteAddress().toString(); } - public long getWrittenBytes() + public Long getWrittenBytes() { return _minaProtocolSession.getWrittenBytes(); } - public long getReadBytes() + public Long getReadBytes() { return _minaProtocolSession.getReadBytes(); } - public long getMaximumNumberOfAllowedChannels() + public Long getMaximumNumberOfAllowedChannels() { return _maxNoOfChannels; } - public void setMaximumNumberOfAllowedChannels(long value) + public void setMaximumNumberOfAllowedChannels(Long value) { _maxNoOfChannels = value; } public String getObjectInstanceName() { - String remote = getRemoteAddress(); - return "anonymous".equals(remote) ? remote + hashCode() : remote; + return _name; + } + + public void commitTransactions(int channelId) throws JMException + { + try + { + AMQChannel channel = _channelMap.get(channelId); + if (channel == null) + { + throw new JMException("The channel (channel Id = " + channelId + ") does not exist"); + } + if (channel.isTransactional()) + { + channel.commit(); + } + } + catch(AMQException ex) + { + throw new MBeanException(ex, ex.toString()); + } + } + + public void rollbackTransactions(int channelId) throws JMException + { + try + { + AMQChannel channel = _channelMap.get(channelId); + if (channel == null) + { + throw new JMException("The channel (channel Id = " + channelId + ") does not exist"); + } + if (channel.isTransactional()) + { + channel.rollback(); + } + } + catch(AMQException ex) + { + throw new MBeanException(ex, ex.toString()); + } } /** @@ -193,14 +276,14 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi * @return list of channels in tabular form. * @throws OpenDataException */ - private TabularData getChannels() - throws OpenDataException + public TabularData getChannels() throws OpenDataException { _channelsList = new TabularDataSupport(_channelsType); for (Map.Entry<Integer, AMQChannel> entry : _channelMap.entrySet()) { AMQChannel channel = entry.getValue(); + //ManagedChannel channel = (AMQChannelMBean)amqChannel.getManagedObject(); ObjectName channelObjectName = null; try @@ -215,7 +298,8 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi Object[] itemValues = {channel.getChannelId(), channelObjectName, channel.isTransactional(), - (channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getName() : null}; + (channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getName() : null, + channel.getUnacknowledgedMessageMap().size()}; CompositeData channelData = new CompositeDataSupport(_channelType, _channelAtttibuteNames, @@ -227,12 +311,6 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi return _channelsList; } - public TabularData viewChannels() - throws OpenDataException - { - return getChannels(); - } - public void closeChannel(int id) throws Exception { @@ -259,7 +337,37 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi } } - } + @Override + public MBeanNotificationInfo[] getNotificationInfo() + { + String[] notificationTypes = new String[] + {MonitorNotification.THRESHOLD_VALUE_EXCEEDED}; + String name = MonitorNotification.class.getName(); + String description = "An attribute of this MBean has reached threshold value"; + MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, + name, + description); + + return new MBeanNotificationInfo[] {info1}; + } + + private void checkForNotification() + { + int channelsCount = _channelMap.size(); + if (channelsCount >= getMaximumNumberOfAllowedChannels()) + { + Notification n = new Notification( + MonitorNotification.THRESHOLD_VALUE_EXCEEDED, + this, + ++_notificationSequenceNumber, + System.currentTimeMillis(), + "ChannelsCount = " + channelsCount + ", ChannelsCount has reached the threshold value"); + + _broadcaster.sendNotification(n); + } + } + + } // End of MBean class public AMQMinaProtocolSession(IoSession session, QueueRegistry queueRegistry, ExchangeRegistry exchangeRegistry, AMQCodecFactory codecFactory) @@ -279,10 +387,23 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi _queueRegistry = queueRegistry; _exchangeRegistry = exchangeRegistry; _codecFactory = codecFactory; - _managedObject = new AMQProtocolSessionMBean(); + _managedObject = createMBean(); _managedObject.register(); } + private ManagedAMQProtocolSession createMBean() throws AMQException + { + try + { + return new ManagedAMQProtocolSession(); + } + catch(NotCompliantMBeanException ex) + { + _logger.error("AMQProtocolSession MBean creation has failed.", ex); + throw new AMQException("AMQProtocolSession MBean creation has failed.", ex); + } + } + public static AMQProtocolSession getAMQProtocolSession(IoSession minaProtocolSession) { return (AMQProtocolSession) minaProtocolSession.getAttachment(); @@ -446,6 +567,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, ProtocolVersi public void addChannel(AMQChannel channel) { _channelMap.put(channel.getChannelId(), channel); + _managedObject.checkForNotification(); } /** diff --git a/java/broker/src/org/apache/qpid/server/protocol/ManagedConnection.java b/java/broker/src/org/apache/qpid/server/protocol/ManagedConnection.java index f3fd8bc7e2..2a800f327d 100644 --- a/java/broker/src/org/apache/qpid/server/protocol/ManagedConnection.java +++ b/java/broker/src/org/apache/qpid/server/protocol/ManagedConnection.java @@ -18,11 +18,15 @@ package org.apache.qpid.server.protocol; -import org.apache.qpid.AMQException; +import org.apache.qpid.server.management.MBeanOperationParameter; +import org.apache.qpid.server.management.MBeanAttribute; +import org.apache.qpid.server.management.MBeanOperation; import javax.management.openmbean.TabularData; -import javax.management.openmbean.OpenDataException; +import javax.management.JMException; +import javax.management.MBeanOperationInfo; import java.util.Date; +import java.io.IOException; /** * The management interface exposed to allow management of Connections. @@ -34,28 +38,46 @@ public interface ManagedConnection static final String TYPE = "Connection"; /** + * channel details of all the channels opened for this connection. + * @return general channel details + * @throws IOException + * @throws JMException + */ + @MBeanAttribute(name="Channels", + description="channel details of all the channels opened for this connection") + TabularData getChannels() throws IOException, JMException; + + /** * Tells the last time, the IO operation was done. * @return last IO time. */ + @MBeanAttribute(name="LastIOTime", + description="The last time, the IO operation was done") Date getLastIoTime(); /** * Tells the remote address of this connection. * @return remote address */ + @MBeanAttribute(name="RemoteAddress", + description="The remote address of this connection") String getRemoteAddress(); /** * Tells the total number of bytes written till now. * @return number of bytes written. */ - long getWrittenBytes(); + @MBeanAttribute(name="WrittenBytes", + description="The total number of bytes written till now") + Long getWrittenBytes(); /** * Tells the total number of bytes read till now. * @return number of bytes read. */ - long getReadBytes(); + @MBeanAttribute(name="ReadBytes", + description="The total number of bytes read till now") + Long getReadBytes(); /** * Tells the maximum number of channels that can be opened using @@ -63,30 +85,54 @@ public interface ManagedConnection * taking required action is there are more channels being created. * @return maximum number of channels allowed to be created. */ - long getMaximumNumberOfAllowedChannels(); + @MBeanAttribute(name="MaximumNumberOfAllowedChannels", + description="The maximum number of channels that can be opened using this connection") + Long getMaximumNumberOfAllowedChannels(); /** * Sets the maximum number of channels allowed to be created using * this connection. * @param value */ - void setMaximumNumberOfAllowedChannels(long value); + void setMaximumNumberOfAllowedChannels(Long value); //********** Operations *****************// /** - * Returns channel details of all the channels opened for this connection. - * @return channel details. + * Closes all the related channels and unregisters this connection from managed objects. + */ + @MBeanOperation(name="closeConnection", + description="Closes this connection and all related channels", + impact= MBeanOperationInfo.ACTION) + void closeConnection() throws Exception; + + /** + * Unsubscribes the consumers and unregisters the channel from managed objects. */ - TabularData viewChannels() throws OpenDataException; + @MBeanOperation(name="closeChannel", + description="Closes the channel with given channeld and" + + "connected consumers will be unsubscribed", + impact= MBeanOperationInfo.ACTION) + void closeChannel(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) + throws Exception; /** - * Closes all the channels and unregisters this connection from managed objects. + * Commits the transactions if the channel is transactional. + * @param channelId + * @throws JMException */ - void closeConnection() throws Exception; + @MBeanOperation(name="commitTransaction", + description="Commits the transactions for given channelID, if the channel is transactional", + impact= MBeanOperationInfo.ACTION) + void commitTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException; /** - * Unsubscribes the consumers and unregisters the channel from managed objects. + * Rollsback the transactions if the channel is transactional. + * @param channelId + * @throws JMException */ - void closeChannel(int channelId) throws Exception; + @MBeanOperation(name="rollbackTransactions", + description="Rollsback the transactions for given channelId, if the channel is transactional", + impact= MBeanOperationInfo.ACTION) + void rollbackTransactions(@MBeanOperationParameter(name="channel Id", description="channel Id")int channelId) throws JMException; } diff --git a/java/broker/src/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/org/apache/qpid/server/queue/AMQQueue.java index 8e744d5960..bf510d379e 100644 --- a/java/broker/src/org/apache/qpid/server/queue/AMQQueue.java +++ b/java/broker/src/org/apache/qpid/server/queue/AMQQueue.java @@ -21,17 +21,20 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.ContentBody; import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.management.MBeanConstructor; +import org.apache.qpid.server.management.MBeanDescription; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.protocol.AMQProtocolSession; -import javax.management.openmbean.*; -import javax.management.MBeanNotificationInfo; -import javax.management.AttributeChangeNotification; -import javax.management.Notification; import javax.management.JMException; import javax.management.MBeanException; +import javax.management.MBeanNotificationInfo; +import javax.management.NotCompliantMBeanException; +import javax.management.Notification; +import javax.management.monitor.MonitorNotification; +import javax.management.openmbean.*; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; @@ -97,7 +100,7 @@ public class AMQQueue implements Managable /** * max allowed number of messages on a queue. */ - private long _maxAllowedMessageCount = 0; + private Integer _maxAllowedMessageCount = 0; /** * max allowed size in bytes for all the messages combined together in a queue. @@ -110,19 +113,15 @@ public class AMQQueue implements Managable private long _totalMessagesReceived = 0; /** - * MBean interface for the implementation AMQQueueMBean. - * This is required for making the implementation a compliant MBean. - */ - public interface AMQQueueMBeanMBean extends ManagedQueue - { - - } - /** * MBean class for AMQQueue. It implements all the management features exposed * for an AMQQueue. */ - private final class AMQQueueMBean extends AMQManagedObject implements AMQQueueMBeanMBean + @MBeanDescription("Management Interface for AMQQueue") + private final class AMQQueueMBean extends AMQManagedObject implements ManagedQueue { + private String _queueName = null; + //private MBeanInfo _mbeanInfo; + // AMQ message attribute names exposed. private String[] _msgAttributeNames = { "MessageId", "Redelivered", @@ -149,7 +148,8 @@ public class AMQQueue implements Managable private CompositeType _contentBodyType = null; private TabularType _contentBodyListType = null; - public AMQQueueMBean() + @MBeanConstructor("Creates an MBean exposing an AMQQueue.") + public AMQQueueMBean() throws NotCompliantMBeanException { super(ManagedQueue.class, ManagedQueue.TYPE); init(); @@ -157,6 +157,7 @@ public class AMQQueue implements Managable private void init() { + _queueName = jmxEncode(new StringBuffer(_name), 0).toString(); try { _contentType[0] = SimpleType.INTEGER; @@ -195,7 +196,7 @@ public class AMQQueue implements Managable public String getObjectInstanceName() { - return _name; + return _queueName; } public String getName() @@ -218,52 +219,52 @@ public class AMQQueue implements Managable return _autoDelete; } - public int getMessageCount() + public Integer getMessageCount() { return _deliveryMgr.getQueueMessageCount(); } - public long getMaximumMessageSize() + public Long getMaximumMessageSize() { return _maxAllowedMessageSize; } - public void setMaximumMessageSize(long value) + public void setMaximumMessageSize(Long value) { _maxAllowedMessageSize = value; } - public int getConsumerCount() + public Integer getConsumerCount() { return _subscribers.size(); } - public int getActiveConsumerCount() + public Integer getActiveConsumerCount() { - return _subscribers.getWeight(); + return _subscribers.getWeight(); } - public long getReceivedMessageCount() + public Long getReceivedMessageCount() { return _totalMessagesReceived; } - public long getMaximumMessageCount() + public Integer getMaximumMessageCount() { return _maxAllowedMessageCount; } - public void setMaximumMessageCount( long value) + public void setMaximumMessageCount(Integer value) { _maxAllowedMessageCount = value; } - public long getQueueDepth() + public Long getQueueDepth() { return _queueDepth; } - public void setQueueDepth(long value) + public void setQueueDepth(Long value) { _queueDepth = value; } @@ -275,11 +276,11 @@ public class AMQQueue implements Managable if (getMessageCount() >= getMaximumMessageCount()) { Notification n = new Notification( - "Warning", + MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, ++_notificationSequenceNumber, System.currentTimeMillis(), - "Queue has reached its size limit and is now full."); + "MessageCount = " + getMessageCount() + ", Queue has reached its size limit and is now full."); _broadcaster.sendNotification(n); } @@ -394,12 +395,13 @@ public class AMQQueue implements Managable * Creates all the notifications this MBean can send. * @return Notifications broadcasted by this MBean. */ + @Override public MBeanNotificationInfo[] getNotificationInfo() { String[] notificationTypes = new String[] - {AttributeChangeNotification.ATTRIBUTE_CHANGE}; - String name = AttributeChangeNotification.class.getName(); - String description = "An attribute of this MBean has changed"; + {MonitorNotification.THRESHOLD_VALUE_EXCEEDED}; + String name = MonitorNotification.class.getName(); + String description = "An attribute of this MBean has reached threshold value"; MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description); @@ -480,14 +482,25 @@ public class AMQQueue implements Managable _autoDelete = autoDelete; _queueRegistry = queueRegistry; _asyncDelivery = asyncDelivery; - _managedObject = new AMQQueueMBean(); + _managedObject = createMBean(); _managedObject.register(); - _subscribers = subscribers; _subscriptionFactory = subscriptionFactory; _deliveryMgr = new DeliveryManager(_subscribers, this); } + private AMQQueueMBean createMBean() throws AMQException + { + try + { + return new AMQQueueMBean(); + } + catch(NotCompliantMBeanException ex) + { + throw new AMQException("AMQQueue MBean creation has failed.", ex); + } + } + public String getName() { return _name; diff --git a/java/broker/src/org/apache/qpid/server/queue/ManagedQueue.java b/java/broker/src/org/apache/qpid/server/queue/ManagedQueue.java index 03a0a10337..9732fc4c17 100644 --- a/java/broker/src/org/apache/qpid/server/queue/ManagedQueue.java +++ b/java/broker/src/org/apache/qpid/server/queue/ManagedQueue.java @@ -17,8 +17,13 @@ */ package org.apache.qpid.server.queue; -import javax.management.openmbean.TabularData; +import org.apache.qpid.server.management.MBeanAttribute; +import org.apache.qpid.server.management.MBeanOperation; +import org.apache.qpid.server.management.MBeanOperationParameter; + import javax.management.JMException; +import javax.management.MBeanOperationInfo; +import javax.management.openmbean.TabularData; import java.io.IOException; /** @@ -36,6 +41,7 @@ public interface ManagedQueue * @return the name of the managedQueue. * @throws IOException */ + @MBeanAttribute(name="Name", description = "Name of the " + TYPE) String getName() throws IOException; /** @@ -43,6 +49,7 @@ public interface ManagedQueue * @return true if this ManagedQueue is a durable queue. * @throws IOException */ + @MBeanAttribute(name="Durable", description = "true if the AMQQueue is durable") boolean isDurable() throws IOException; /** @@ -50,6 +57,7 @@ public interface ManagedQueue * @return the owner's name. * @throws IOException */ + @MBeanAttribute(name="Owner", description = "Owner") String getOwner() throws IOException; /** @@ -57,15 +65,17 @@ public interface ManagedQueue * @return true if the ManagedQueue is set to AutoDelete. * @throws IOException */ + @MBeanAttribute(name="AutoDelete", description = "true if the AMQQueue is AutoDelete") boolean isAutoDelete() throws IOException; /** - * Gets the total number of messages on the queue, which are yet to be - * delivered to the consumer(s). + * Total number of messages on the queue, which are yet to be delivered to the consumer(s). * @return number of undelivered message in the Queue. * @throws IOException */ - int getMessageCount() throws IOException; + @MBeanAttribute(name="MessageCount", + description = "Total number of undelivered messages on the queue") + Integer getMessageCount() throws IOException; /** * Returns the maximum size of a message (in bytes) allowed to be accepted by the @@ -76,7 +86,7 @@ public interface ManagedQueue * ManagedQueue. * @throws IOException */ - long getMaximumMessageSize() throws IOException; + Long getMaximumMessageSize() throws IOException; /** * Sets the maximum size of the message (in bytes) that is allowed to be @@ -84,28 +94,34 @@ public interface ManagedQueue * @param bytes maximum size of message. * @throws IOException */ - void setMaximumMessageSize(long bytes) throws IOException; + @MBeanAttribute(name="MaximumMessageSize", + description="Maximum size of a message in bytes allowed for this Queue") + void setMaximumMessageSize(Long bytes) throws IOException; /** * Returns the total number of subscribers to the queue. * @return the number of subscribers. * @throws IOException */ - int getConsumerCount() throws IOException; + @MBeanAttribute(name="ConsumerCount", description="The total number of subscribers to the queue") + Integer getConsumerCount() throws IOException; /** * Returns the total number of active subscribers to the queue. * @return the number of active subscribers * @throws IOException */ - int getActiveConsumerCount() throws IOException; + @MBeanAttribute(name="ActiveConsumerCount", description="The total number of active subscribers to the queue") + Integer getActiveConsumerCount() throws IOException; /** * Tells the total number of messages receieved by the queue since startup. * @return total number of messages received. * @throws IOException */ - long getReceivedMessageCount() throws IOException; + @MBeanAttribute(name="ReceivedMessageCount", + description="The total number of messages receieved by the queue since startup") + Long getReceivedMessageCount() throws IOException; /** * Tells the maximum number of messages that can be stored in the queue. @@ -114,14 +130,16 @@ public interface ManagedQueue * @return maximum muber of message allowed to be stored in the queue. * @throws IOException */ - long getMaximumMessageCount() throws IOException; + Integer getMaximumMessageCount() throws IOException; /** * Sets the maximum number of messages allowed to be stored in the queue. * @param value the maximum number of messages allowed to be stored in the queue. * @throws IOException */ - void setMaximumMessageCount(long value) throws IOException; + @MBeanAttribute(name="MaximumMessageCount", + description="The maximum number of messages allowed to be stored in the queue") + void setMaximumMessageCount(Integer value) throws IOException; /** * Tells the maximum size of all the messages combined together, @@ -131,7 +149,7 @@ public interface ManagedQueue * @return maximum size of the all the messages allowed for the queue. * @throws IOException */ - long getQueueDepth() throws IOException; + Long getQueueDepth() throws IOException; /** * Sets the maximum size of all the messages together, that can be stored @@ -139,7 +157,9 @@ public interface ManagedQueue * @param value * @throws IOException */ - void setQueueDepth(long value) throws IOException; + @MBeanAttribute(name="QueueDepth", + description="The size of all the messages together, that can be stored in the queue") + void setQueueDepth(Long value) throws IOException; @@ -155,7 +175,10 @@ public interface ManagedQueue * @throws IOException * @throws JMException */ - TabularData viewMessages(int fromIndex, int toIndex) + @MBeanOperation(name="viewMessages", + description="shows messages in this queue with given indexes. 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; /** @@ -163,15 +186,19 @@ public interface ManagedQueue * @throws IOException * @throws JMException */ - void deleteMessageFromTop() - throws IOException, JMException; + @MBeanOperation(name="deleteMessageFromTop", + description="Deletes the first message from top", + impact= MBeanOperationInfo.ACTION) + void deleteMessageFromTop() throws IOException, JMException; /** - * Clears the queue by deleting all the messages from the queue. + * Clears the queue by deleting all the undelivered messages from the queue. * @throws IOException * @throws JMException */ - void clearQueue() - throws IOException, JMException; + @MBeanOperation(name="clearQueue", + description="Clears the queue by deleting all the undelivered messages from the queue", + impact= MBeanOperationInfo.ACTION) + void clearQueue() throws IOException, JMException; } |
