summaryrefslogtreecommitdiff
path: root/qpid/java/broker/src
diff options
context:
space:
mode:
authorRobert Gemmell <robbie@apache.org>2012-06-28 16:46:12 +0000
committerRobert Gemmell <robbie@apache.org>2012-06-28 16:46:12 +0000
commit07c285f662e8f60d4e8aca247b65b77ca5df4587 (patch)
tree7fe15262589c0fe5206e02a5e9336c6288f004e0 /qpid/java/broker/src
parentbb45ec03f95ffdfa6c0163067dcb75af8b64ceb5 (diff)
downloadqpid-python-07c285f662e8f60d4e8aca247b65b77ca5df4587.tar.gz
QPID-3998, QPID-3999, QPID-4093: add new management plugins for jmx/rest/webui functionality, partial merge from the java-config-and-management branch at r1355039
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1355072 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src')
-rw-r--r--qpid/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java74
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java18
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java410
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java20
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java52
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java47
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java57
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java215
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java45
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java85
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java14
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java74
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java158
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java81
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java145
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java210
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java822
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java105
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java90
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java192
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java490
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java399
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java367
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java59
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java18
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java17
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java28
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java29
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java199
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java)25
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java55
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java82
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java25
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java)48
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java107
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Event.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java60
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java97
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java46
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java91
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/QueueNotificationListener.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java)5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Session.java82
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java59
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java154
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java37
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java293
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java487
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java222
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java484
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java315
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java225
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java409
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java262
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java46
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java318
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java702
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java239
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java67
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java844
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java142
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java97
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java344
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java43
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java68
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java69
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java664
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java50
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java39
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java456
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java227
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java34
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java186
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java24
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java12
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java38
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java4
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java2
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java72
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java53
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java93
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java263
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java6
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java3
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java128
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java31
-rw-r--r--qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java395
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java194
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java20
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java235
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java27
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java428
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java153
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java146
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java348
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java546
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java113
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java106
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java156
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java3
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java76
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java10
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java323
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java231
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java13
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java16
151 files changed, 8444 insertions, 9268 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java b/qpid/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java
index dca62f34b4..79bedb2a7e 100644
--- a/qpid/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java
+++ b/qpid/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java
@@ -26,8 +26,6 @@ import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
-import org.apache.qpid.server.logging.management.LoggingManagementMBean;
-
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -65,7 +63,6 @@ public class QpidLog4JConfigurator
LOCK.lock();
parseXMLConfigFile(filename);
- checkLoggerLevels(filename);
DOMConfigurator.configure(filename);
@@ -84,7 +81,6 @@ public class QpidLog4JConfigurator
SAXException, IllegalLoggerLevelException
{
parseXMLConfigFile(filename);
- checkLoggerLevels(filename);
QpidLog4JXMLWatchdog watchdog = new QpidLog4JXMLWatchdog(filename);
watchdog.setDelay(delay);
@@ -200,23 +196,6 @@ public class QpidLog4JConfigurator
return;
}
- try
- {
- checkLoggerLevels(filename);
- }
- catch (Exception e)
- {
- //logger will be instantiated following first configuration success, which has been pre-validated
- //and so the null check should never actually be required.
- if(_logger != null)
- {
- _logger.warn("Errors were found when validating the logger level values in the " +
- "log4j XML configuration file. The new configuration was not applied. " +
- "Correct the issues to prompt another update attempt: " + e.getMessage());
- }
- return;
- }
-
//everything checked was ok, let the normal update process proceed
super.doOnChange();
@@ -235,60 +214,7 @@ public class QpidLog4JConfigurator
}
}
-
- protected static void checkLoggerLevels(String filename) throws IllegalLoggerLevelException, IOException
- {
- //check that the logger levels specified in the XML are actually valid
- try
- {
- LOCK.lock();
-
- //get the Logger levels to check
- Map<String, String> loggersLevels;
- loggersLevels = LoggingManagementMBean.retrieveConfigFileLoggersLevels(filename);
- //add the RootLogger to the list too
- String rootLoggerlevelString = LoggingManagementMBean.retrieveConfigFileRootLoggerLevel(filename);
- loggersLevels.put("Root", rootLoggerlevelString);
-
-
- for (Map.Entry<String, String> entry : loggersLevels.entrySet())
- {
- String loggerName = entry.getKey();
- String levelString = entry.getValue();
-
- //let log4j replace any properties in the string
- String log4jConfiguredString = domConfig.subst(levelString);
-
- if(log4jConfiguredString.equals("") && ! log4jConfiguredString.equals(levelString))
- {
- //log4j has returned an empty string but this isnt what we gave it.
- //There may have been an undefined property. Unlike an incorrect
- //literal value, we will allow this case to proceed, but warn users.
-
- if(_logger != null)
- {
- _logger.warn("Unable to detect Level value from '" + levelString
- +"' for logger '" + loggerName + "', Log4J will default this to DEBUG");
- }
- else
- {
- System.err.println("Unable to detect Level value from '" + levelString
- +"' for logger " + loggerName + ", Log4J will default this to DEBUG");
- }
-
- continue;
- }
-
- checkLevel(loggerName,log4jConfiguredString);
- }
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
private static void checkLevel(String loggerName, String levelString) throws IllegalLoggerLevelException
{
if("null".equalsIgnoreCase(levelString) || "inherited".equalsIgnoreCase(levelString))
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
index 034a4ae53c..0d48aec562 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
@@ -540,6 +540,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener
return getMsgReceives();
}
+ public long getMsgDrops()
+ {
+ return 0l;
+ }
+
public long getByteReceives()
{
return _bytesReceived.get();
@@ -550,6 +555,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener
return getByteReceives();
}
+ public long getByteDrops()
+ {
+ return 0l;
+ }
+
public long getCreateTime()
{
return _createTime;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
index 787cede2b7..1b173c7e11 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
@@ -21,6 +21,8 @@
package org.apache.qpid.qmf;
+import java.util.Collection;
+import java.util.Collections;
import org.apache.commons.lang.NotImplementedException;
import org.apache.qpid.framing.AMQShortString;
@@ -111,6 +113,16 @@ public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHead
return 0;
}
+ public String getUserId()
+ {
+ return null;
+ }
+
+ public String getAppId()
+ {
+ return null;
+ }
+
public String getMessageId()
{
return null;
@@ -166,6 +178,12 @@ public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHead
return false;
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ return Collections.EMPTY_SET;
+ }
+
public boolean containsHeader(String name)
{
return false;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
deleted file mode 100644
index 0f32b98aa8..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.ExchangeFactory;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeType;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.model.UUIDGenerator;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.queue.AMQQueueMBean;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * This MBean implements the broker management interface and exposes the
- * Broker level management features like creating and deleting exchanges and queue.
- */
-@MBeanDescription("This MBean exposes the broker level management features")
-public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBroker
-{
- private final QueueRegistry _queueRegistry;
- private final ExchangeRegistry _exchangeRegistry;
- private final ExchangeFactory _exchangeFactory;
-
- private final VirtualHostImpl.VirtualHostMBean _virtualHostMBean;
-
- @MBeanConstructor("Creates the Broker Manager MBean")
- public AMQBrokerManagerMBean(VirtualHostImpl.VirtualHostMBean virtualHostMBean) throws JMException
- {
- super(ManagedBroker.class, ManagedBroker.TYPE);
-
- _virtualHostMBean = virtualHostMBean;
- VirtualHost virtualHost = virtualHostMBean.getVirtualHost();
-
- _queueRegistry = virtualHost.getQueueRegistry();
- _exchangeRegistry = virtualHost.getExchangeRegistry();
- _exchangeFactory = virtualHost.getExchangeFactory();
- }
-
- public String getObjectInstanceName()
- {
- return _virtualHostMBean.getVirtualHost().getName();
- }
-
- /**
- * Returns an array of the exchange types available for creation.
- * @since Qpid JMX API 1.3
- * @throws IOException
- */
- public String[] getExchangeTypes() throws IOException
- {
- ArrayList<String> exchangeTypes = new ArrayList<String>();
- for(ExchangeType<? extends Exchange> ex : _exchangeFactory.getPublicCreatableTypes())
- {
- exchangeTypes.add(ex.getName().toString());
- }
-
- return exchangeTypes.toArray(new String[0]);
- }
-
- /**
- * Returns a list containing the names of the attributes available for the Queue mbeans.
- * @since Qpid JMX API 1.3
- * @throws IOException
- */
- public List<String> retrieveQueueAttributeNames() throws IOException
- {
- return ManagedQueue.QUEUE_ATTRIBUTES;
- }
-
- /**
- * Returns a List of Object Lists containing the requested attribute values (in the same sequence requested) for each queue in the virtualhost.
- * If a particular attribute cant be found or raises an mbean/reflection exception whilst being gathered its value is substituted with the String "-".
- * @since Qpid JMX API 1.3
- * @throws IOException
- */
- public List<List<Object>> retrieveQueueAttributeValues(String[] attributes) throws IOException
- {
- if(_queueRegistry.getQueues().size() == 0)
- {
- return new ArrayList<List<Object>>();
- }
-
- List<List<Object>> queueAttributesList = new ArrayList<List<Object>>(_queueRegistry.getQueues().size());
-
- int attributesLength = attributes.length;
-
- for(AMQQueue queue : _queueRegistry.getQueues())
- {
- AMQQueueMBean mbean = (AMQQueueMBean) queue.getManagedObject();
-
- if(mbean == null)
- {
- continue;
- }
-
- List<Object> attributeValues = new ArrayList<Object>(attributesLength);
-
- for(int i=0; i < attributesLength; i++)
- {
- try
- {
- attributeValues.add(mbean.getAttribute(attributes[i]));
- }
- catch (Exception e)
- {
- attributeValues.add("-");
- }
- }
-
- queueAttributesList.add(attributeValues);
- }
-
- return queueAttributesList;
- }
-
- /**
- * Creates new exchange and registers it with the registry.
- *
- * @param exchangeName
- * @param type
- * @param durable
- * @throws JMException
- * @throws MBeanException
- */
- public void createNewExchange(String exchangeName, String type, boolean durable) throws JMException, MBeanException
- {
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- synchronized (_exchangeRegistry)
- {
- Exchange exchange = _exchangeRegistry.getExchange(new AMQShortString(exchangeName));
- if (exchange == null)
- {
- exchange = _exchangeFactory.createExchange(new AMQShortString(exchangeName),
- new AMQShortString(type), durable, false, 0);
- _exchangeRegistry.registerExchange(exchange);
- if (durable)
- {
- getVirtualHost().getMessageStore().createExchange(exchange);
- }
- }
- else
- {
- throw new JMException("The exchange \"" + exchangeName + "\" already exists.");
- }
- }
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error in creating exchange " + exchangeName);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- /**
- * Unregisters the exchange from registry.
- *
- * @param exchangeName
- * @throws JMException
- * @throws MBeanException
- */
- public void unregisterExchange(String exchangeName) throws JMException, MBeanException
- {
- // TODO
- // Check if the exchange is in use.
-
- // Check if there are queue-bindings with the exchange and unregister
- // when there are no bindings.
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- _exchangeRegistry.unregisterExchange(new AMQShortString(exchangeName), false);
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error in unregistering exchange " + exchangeName);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- /**
- * Creates a new queue and registers it with the registry and puts it
- * in persistance storage if durable queue.
- *
- * @param queueName
- * @param durable
- * @param owner
- * @throws JMException
- * @throws MBeanException
- */
- public void createNewQueue(String queueName, String owner, boolean durable) throws JMException, MBeanException
- {
- createNewQueue(queueName, owner, durable, null);
- }
-
- public void createNewQueue(String queueName, String owner, boolean durable, Map<String,Object> arguments) throws JMException
- {
- final AMQShortString queueNameAsAMQShortString = new AMQShortString(queueName);
- synchronized (_queueRegistry)
- {
- AMQQueue queue = _queueRegistry.getQueue(queueNameAsAMQShortString);
- if (queue != null)
- {
- throw new JMException("The queue \"" + queueName + "\" already exists.");
- }
-
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- FieldTable args = null;
- if(arguments != null)
- {
- args = FieldTable.convertToFieldTable(arguments);
- }
- final VirtualHost virtualHost = getVirtualHost();
-
- queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateUUID(), queueName, durable, owner,
- false, false, getVirtualHost(), arguments);
- if (queue.isDurable() && !queue.isAutoDelete())
- {
- getVirtualHost().getMessageStore().createQueue(queue, args);
- }
-
- virtualHost.getBindingFactory().addBinding(queueName, queue, _exchangeRegistry.getDefaultExchange(), null);
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error in creating queue " + queueName);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
- }
-
- private VirtualHost getVirtualHost()
- {
- return _virtualHostMBean.getVirtualHost();
- }
-
- /**
- * Deletes the queue from queue registry and persistant storage.
- *
- * @param queueName
- * @throws JMException
- * @throws MBeanException
- */
- public void deleteQueue(String queueName) throws JMException, MBeanException
- {
- AMQQueue queue = _queueRegistry.getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("The Queue " + queueName + " is not a registered queue.");
- }
-
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- queue.delete();
- if (queue.isDurable())
- {
- getVirtualHost().getMessageStore().removeQueue(queue);
- }
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error in deleting queue " + queueName);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return _virtualHostMBean;
- }
-
- // This will have a single instance for a virtual host, so not having the name property in the ObjectName
- @Override
- public ObjectName getObjectName() throws MalformedObjectNameException
- {
- return getObjectNameForSingleInstanceMBean();
- }
-
- public void resetStatistics() throws Exception
- {
- getVirtualHost().resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return getVirtualHost().getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return getVirtualHost().getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return getVirtualHost().getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return getVirtualHost().isStatisticsEnabled();
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 4fd4e02220..030fd3f499 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -140,7 +140,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
private UnacknowledgedMessageMap _unacknowledgedMessageMap = new UnacknowledgedMessageMapImpl(DEFAULT_PREFETCH);
- // Set of messages being acknoweledged in the current transaction
+ // Set of messages being acknowledged in the current transaction
private SortedSet<QueueEntry> _acknowledgedMessages = new TreeSet<QueueEntry>();
private final AtomicBoolean _suspended = new AtomicBoolean(false);
@@ -263,6 +263,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return _txnCount.get();
}
+ public Long getTxnStart()
+ {
+ return _txnStarts.get();
+ }
+
public int getChannelId()
{
return _channelId;
@@ -440,7 +445,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
* @param acks Are acks enabled for this subscriber
* @param filters Filters to apply to this subscriber
*
- * @param noLocal Flag stopping own messages being receivied.
+ * @param noLocal Flag stopping own messages being received.
* @param exclusive Flag requesting exclusive access to the queue
* @return the consumer tag. This is returned to the subscriber and used in subsequent unsubscribe requests
*
@@ -1417,6 +1422,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return false;
}
+ public int getUnacknowledgedMessageCount()
+ {
+ return getUnacknowledgedMessageMap().size();
+ }
+
private void flow(boolean flow)
{
MethodRegistry methodRegistry = _session.getMethodRegistry();
@@ -1424,6 +1434,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_session.writeFrame(responseBody.generateFrame(_channelId));
}
+ @Override
public boolean getBlocking()
{
return _blocking.get();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
index 90603777d1..c843ce6a23 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
@@ -25,24 +25,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
import javax.net.ssl.SSLContext;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.QpidLog4JConfigurator;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration;
-import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
-import org.apache.qpid.server.information.management.ServerInformationMBean;
import org.apache.qpid.server.logging.SystemOutMessageLogger;
import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
-import org.apache.qpid.server.logging.management.LoggingManagementMBean;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
@@ -118,6 +111,14 @@ public class Broker
ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile, options.getBundleContext());
ServerConfiguration serverConfig = config.getConfiguration();
+ if (options.getQpidWork() != null)
+ {
+ serverConfig.setQpidWork(options.getQpidWork());
+ }
+ if (options.getQpidHome() != null)
+ {
+ serverConfig.setQpidHome(options.getQpidHome());
+ }
updateManagementPorts(serverConfig, options.getJmxPortRegistryServer(), options.getJmxPortConnectorServer());
ApplicationRegistry.initialise(config);
@@ -135,14 +136,6 @@ public class Broker
try
{
- configureLoggingManagementMBean(logConfigFile, options.getLogWatchFrequency());
-
- ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
- configMBean.register();
-
- ServerInformationMBean sysInfoMBean = new ServerInformationMBean(config);
- sysInfoMBean.register();
-
Set<Integer> ports = new HashSet<Integer>(options.getPorts());
if(ports.isEmpty())
{
@@ -258,7 +251,7 @@ public class Broker
transport.accept(settings, protocolEngineFactory, null);
ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress,
- new QpidAcceptor(transport,"TCP"));
+ new QpidAcceptor(transport,QpidAcceptor.Transport.TCP, supported));
CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
}
}
@@ -302,7 +295,7 @@ public class Broker
transport.accept(settings, protocolEngineFactory, sslContext);
ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress,
- new QpidAcceptor(transport,"TCP"));
+ new QpidAcceptor(transport,QpidAcceptor.Transport.SSL, supported));
CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort));
}
}
@@ -495,12 +488,6 @@ public class Broker
}
}
- private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
- {
- LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
-
- blm.register();
- }
private void addShutdownHook()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
index cec614881d..434d40d557 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
@@ -33,6 +33,7 @@ public class BrokerOptions
public static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml";
public static final String QPID_HOME = "QPID_HOME";
+ public static final String QPID_WORK = "QPID_WORK";
private final Set<Integer> _ports = new HashSet<Integer>();
private final Set<Integer> _sslPorts = new HashSet<Integer>();
@@ -47,6 +48,8 @@ public class BrokerOptions
private BundleContext _bundleContext;
private Integer _logWatchFrequency = 0;
+ private String _qpidWorkFolder;
+ private String _qpidHomeFolder;
public void addPort(final int port)
{
@@ -109,7 +112,7 @@ public class BrokerOptions
}
public String getQpidHome()
{
- return System.getProperty(QPID_HOME);
+ return _qpidHomeFolder == null? System.getProperty(QPID_HOME): _qpidHomeFolder;
}
public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol)
@@ -179,4 +182,19 @@ public class BrokerOptions
Set<Integer> ports = _inclusionMap.get(includeProtocol);
ports.add(port);
}
+
+ public String getQpidWork()
+ {
+ return _qpidWorkFolder;
+ }
+
+ public void setQpidWork(String qpidWorkFolder)
+ {
+ _qpidWorkFolder = qpidWorkFolder;
+ }
+
+ public void setQpidHome(String qpidHomeFolder)
+ {
+ _qpidHomeFolder = qpidHomeFolder;
+ }
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
index 41c51d9684..6633d93adf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
@@ -49,7 +49,12 @@ public interface ExchangeConfig extends ConfiguredObject<ExchangeConfigType, Exc
long getMsgRoutes();
+ long getMsgDrops();
+
long getByteReceives();
long getByteRoutes();
+
+ long getByteDrops();
+
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
index 40bafb4275..8f03383777 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
@@ -126,6 +126,11 @@ public class QueueConfiguration extends ConfigurationPlugin
return _name;
}
+ public String getDescription()
+ {
+ return getStringValue("description");
+ }
+
public int getMaximumMessageAge()
{
return getIntValue("maximumMessageAge", _vHostConfig.getMaximumMessageAge());
@@ -226,4 +231,5 @@ public class QueueConfiguration extends ConfigurationPlugin
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index b48d8c5fdb..c23e58fdab 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -64,6 +64,7 @@ public class ServerConfiguration extends ConfigurationPlugin
public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
public static final int DEFAULT_JMXPORT_REGISTRYSERVER = 8999;
public static final int JMXPORT_CONNECTORSERVER_OFFSET = 100;
+ public static final int DEFAULT_HTTP_MANAGEMENT_PORT = 8080;
public static final String QPID_HOME = "QPID_HOME";
public static final String QPID_WORK = "QPID_WORK";
@@ -75,6 +76,8 @@ public class ServerConfiguration extends ConfigurationPlugin
private File _configFile;
private File _vhostsFile;
+ private String _qpidWork;
+ private String _qpidHome;
// Map of environment variables to config items
private static final Map<String, String> envVarMap = new HashMap<String, String>();
@@ -110,6 +113,8 @@ public class ServerConfiguration extends ConfigurationPlugin
envVarMap.put("QPID_MSGAUTH", "security.msg-auth");
envVarMap.put("QPID_AUTOREGISTER", "auto_register");
envVarMap.put("QPID_MANAGEMENTENABLED", "management.enabled");
+ envVarMap.put("QPID_HTTPMANAGEMENTENABLED", "management.http.enabled");
+ envVarMap.put("QPID_HTTPMANAGEMENTPORT", "management.http.port");
envVarMap.put("QPID_HEARTBEATDELAY", "heartbeat.delay");
envVarMap.put("QPID_HEARTBEATTIMEOUTFACTOR", "heartbeat.timeoutFactor");
envVarMap.put("QPID_MAXIMUMMESSAGEAGE", "maximumMessageAge");
@@ -511,12 +516,26 @@ public class ServerConfiguration extends ConfigurationPlugin
public String getQpidWork()
{
- return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir"));
+ if ( _qpidWork == null )
+ {
+ return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir"));
+ }
+ else
+ {
+ return _qpidWork;
+ }
}
public String getQpidHome()
{
- return System.getProperty(QPID_HOME);
+ if ( _qpidHome == null )
+ {
+ return System.getProperty(QPID_HOME);
+ }
+ else
+ {
+ return _qpidHome;
+ }
}
public void setJMXPortRegistryServer(int registryServerPort)
@@ -554,6 +573,16 @@ public class ServerConfiguration extends ConfigurationPlugin
return getBooleanValue("management.platform-mbeanserver", true);
}
+ public boolean getHTTPManagementEnabled()
+ {
+ return getBooleanValue("management.http.enabled", true);
+ }
+
+ public int getHTTPManagementPort()
+ {
+ return getIntValue("management.http.port", 8080);
+ }
+
public String[] getVirtualHosts()
{
return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]);
@@ -622,7 +651,7 @@ public class ServerConfiguration extends ConfigurationPlugin
public boolean getManagementSSLEnabled()
{
- return getBooleanValue("management.ssl.enabled", true);
+ return getBooleanValue("management.ssl.enabled", false);
}
public String getManagementKeyStorePassword()
@@ -636,16 +665,11 @@ public class ServerConfiguration extends ConfigurationPlugin
return getBooleanValue("queue.auto_register", true);
}
- public boolean getManagementEnabled()
+ public boolean getJMXManagementEnabled()
{
return getBooleanValue("management.enabled", true);
}
- public void setManagementEnabled(boolean enabled)
- {
- getConfig().setProperty("management.enabled", enabled);
- }
-
public int getHeartBeatDelay()
{
return getIntValue("heartbeat.delay", 5);
@@ -981,4 +1005,14 @@ public class ServerConfiguration extends ConfigurationPlugin
return reply == null ? null : AmqpProtocolVersion.valueOf(reply);
}
+
+ public void setQpidWork(String path)
+ {
+ _qpidWork = path;
+ }
+
+ public void setQpidHome(String path)
+ {
+ _qpidHome = path;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java
deleted file mode 100644
index f0ca5dc139..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.configuration.management;
-
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.management.NotCompliantMBeanException;
-
-public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement
-{
-
- public ConfigurationManagementMBean() throws NotCompliantMBeanException
- {
- super(ConfigurationManagement.class, ConfigurationManagement.TYPE);
- }
-
- public String getObjectInstanceName()
- {
- return ConfigurationManagement.TYPE;
- }
-
- public void reloadSecurityConfiguration() throws Exception
- {
- ApplicationRegistry.getInstance().getConfiguration().reparseConfigFileSecuritySections();
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
index a539743081..451754e6d8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
@@ -88,6 +88,13 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
}
}
}
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionRegistered(connnection);
+ }
+ }
}
public void deregisterConnection(AMQConnectionModel connnection)
@@ -104,6 +111,14 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
}
}
}
+
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionUnregistered(connnection);
+ }
+ }
}
public void addRegistryChangeListener(RegistryChangeListener listener)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 9493f400f2..e633ddd341 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -30,15 +30,12 @@ import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ExchangeMessages;
import org.apache.qpid.server.logging.subjects.ExchangeLogSubject;
-import org.apache.qpid.server.management.Managable;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import javax.management.JMException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -50,10 +47,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-public abstract class AbstractExchange implements Exchange, Managable
+public abstract class AbstractExchange implements Exchange
{
-
-
private AMQShortString _name;
private final AtomicBoolean _closed = new AtomicBoolean();
@@ -66,9 +61,6 @@ public abstract class AbstractExchange implements Exchange, Managable
private final List<Exchange.Task> _closeTaskList = new CopyOnWriteArrayList<Exchange.Task>();
-
- private AbstractExchangeMBean _exchangeMbean;
-
/**
* Whether the exchange is automatically deleted once all queues have detached from it
*/
@@ -86,6 +78,8 @@ public abstract class AbstractExchange implements Exchange, Managable
private final AtomicLong _receivedMessageSize = new AtomicLong();
private final AtomicLong _routedMessageCount = new AtomicLong();
private final AtomicLong _routedMessageSize = new AtomicLong();
+ private final AtomicLong _droppedMessageCount = new AtomicLong();
+ private final AtomicLong _droppedMessageSize = new AtomicLong();
private final CopyOnWriteArrayList<Exchange.BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>();
@@ -107,13 +101,6 @@ public abstract class AbstractExchange implements Exchange, Managable
return _type.getName();
}
- /**
- * Concrete exchanges must implement this method in order to create the managed representation. This is
- * called during initialisation (template method pattern).
- * @return the MBean
- */
- protected abstract AbstractExchangeMBean createMBean() throws JMException;
-
public void initialise(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete)
throws AMQException
{
@@ -126,26 +113,12 @@ public abstract class AbstractExchange implements Exchange, Managable
_id = id;
getConfigStore().addConfiguredObject(this);
- createAndRegisterMBean();
_logSubject = new ExchangeLogSubject(this, this.getVirtualHost());
// Log Exchange creation
CurrentActor.get().message(ExchangeMessages.CREATED(String.valueOf(getTypeShortString()), String.valueOf(name), durable));
}
- private void createAndRegisterMBean()
- {
- try
- {
- _exchangeMbean = createMBean();
- _exchangeMbean.register();
- }
- catch (JMException e)
- {
- throw new RuntimeException("Failed to register mbean",e);
- }
- }
-
public ConfigStore getConfigStore()
{
return getVirtualHost().getConfigStore();
@@ -171,10 +144,6 @@ public abstract class AbstractExchange implements Exchange, Managable
if(_closed.compareAndSet(false,true))
{
- if (_exchangeMbean != null)
- {
- _exchangeMbean.unregister();
- }
getConfigStore().removeConfiguredObject(this);
if(_alternateExchange != null)
{
@@ -196,11 +165,6 @@ public abstract class AbstractExchange implements Exchange, Managable
return getClass().getSimpleName() + "[" + getNameShortString() +"]";
}
- public ManagedObject getManagedObject()
- {
- return _exchangeMbean;
- }
-
public VirtualHost getVirtualHost()
{
return _virtualHost;
@@ -359,6 +323,11 @@ public abstract class AbstractExchange implements Exchange, Managable
_routedMessageCount.incrementAndGet();
_routedMessageSize.addAndGet(message.getSize());
}
+ else
+ {
+ _droppedMessageCount.incrementAndGet();
+ _droppedMessageSize.addAndGet(message.getSize());
+ }
return queues;
}
@@ -374,6 +343,11 @@ public abstract class AbstractExchange implements Exchange, Managable
return _routedMessageCount.get();
}
+ public long getMsgDrops()
+ {
+ return _droppedMessageCount.get();
+ }
+
public long getByteReceives()
{
return _receivedMessageSize.get();
@@ -384,6 +358,11 @@ public abstract class AbstractExchange implements Exchange, Managable
return _routedMessageSize.get();
}
+ public long getByteDrops()
+ {
+ return _droppedMessageSize.get();
+ }
+
public long getCreateTime()
{
return _createTime;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
deleted file mode 100644
index 034331abd9..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedExchange;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-import javax.management.openmbean.ArrayType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularType;
-import java.util.Collections;
-
-
-/**
- * Abstract MBean class. This has some of the methods implemented from
- * management intrerface for exchanges. Any implementaion of an
- * Exchange MBean should extend this class.
- */
-public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends AMQManagedObject implements ManagedExchange
-{
- // open mbean data types for representing exchange bindings
- private OpenType[] _bindingItemTypes;
- private CompositeType _bindingDataType;
- private TabularType _bindinglistDataType;
-
-
- private T _exchange;
-
- public AbstractExchangeMBean(final T abstractExchange) throws NotCompliantMBeanException
- {
- super(ManagedExchange.class, ManagedExchange.TYPE);
- _exchange = abstractExchange;
- }
-
- protected void init() throws OpenDataException
- {
- _bindingItemTypes = new OpenType[2];
- _bindingItemTypes[0] = SimpleType.STRING;
- _bindingItemTypes[1] = new ArrayType(1, SimpleType.STRING);
- _bindingDataType = new CompositeType("Exchange Binding", "Binding key and Queue names",
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- COMPOSITE_ITEM_DESCRIPTIONS.toArray(new String[COMPOSITE_ITEM_DESCRIPTIONS.size()]), _bindingItemTypes);
- _bindinglistDataType = new TabularType("Exchange Bindings", "Exchange Bindings for " + getName(),
- _bindingDataType, TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()]));
- }
-
- public ManagedObject getParentObject()
- {
- return _exchange.getVirtualHost().getManagedObject();
- }
-
- public T getExchange()
- {
- return _exchange;
- }
-
-
- public String getObjectInstanceName()
- {
- return ObjectName.quote(_exchange.getName());
- }
-
- public String getName()
- {
- return _exchange.getName();
- }
-
- public String getExchangeType()
- {
- return _exchange.getTypeShortString().toString();
- }
-
- public Integer getTicketNo()
- {
- return _exchange.getTicket();
- }
-
- public boolean isDurable()
- {
- return _exchange.isDurable();
- }
-
- public boolean isAutoDelete()
- {
- return _exchange.isAutoDelete();
- }
-
- // Added exchangetype in the object name lets maangement apps to do any customization required
- public ObjectName getObjectName() throws MalformedObjectNameException
- {
- String objNameString = super.getObjectName().toString();
- objNameString = objNameString + ",ExchangeType=" + getExchangeType();
- return new ObjectName(objNameString);
- }
-
- protected ManagedObjectRegistry getManagedObjectRegistry()
- {
- return ApplicationRegistry.getInstance().getManagedObjectRegistry();
- }
-
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- VirtualHost vhost = getExchange().getVirtualHost();
- AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost.");
- }
-
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- vhost.getBindingFactory().addBinding(binding,queue,getExchange(),null);
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error creating new binding " + binding);
- }
- CurrentActor.remove();
- }
-
- /**
- * Removes a queue binding from the exchange.
- *
- * @see org.apache.qpid.server.binding.BindingFactory#removeBinding(String, AMQQueue, Exchange, java.util.Map)
- */
- public void removeBinding(String queueName, String binding) throws JMException
- {
- VirtualHost vhost = getExchange().getVirtualHost();
- AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost.");
- }
-
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- vhost.getBindingFactory().removeBinding(binding, queue, _exchange, Collections.<String, Object>emptyMap());
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error removing binding " + binding);
- }
- CurrentActor.remove();
- }
-
-
- protected OpenType[] getBindingItemTypes()
- {
- return _bindingItemTypes;
- }
-
- protected void setBindingItemTypes(OpenType[] bindingItemTypes)
- {
- _bindingItemTypes = bindingItemTypes;
- }
-
- protected CompositeType getBindingDataType()
- {
- return _bindingDataType;
- }
-
- protected void setBindingDataType(CompositeType bindingDataType)
- {
- _bindingDataType = bindingDataType;
- }
-
- protected TabularType getBindinglistDataType()
- {
- return _bindinglistDataType;
- }
-
- protected void setBindinglistDataType(TabularType bindinglistDataType)
- {
- _bindinglistDataType = bindinglistDataType;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index bf4184bf0b..baf9cc3d09 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
@@ -29,7 +29,9 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -46,6 +48,8 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
private Exchange _defaultExchange;
private VirtualHost _host;
+ private final Collection<RegistryChangeListener> _listeners =
+ Collections.synchronizedCollection(new ArrayList<RegistryChangeListener>());
public DefaultExchangeRegistry(VirtualHost host)
{
@@ -68,6 +72,14 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
{
_exchangeMap.put(exchange.getNameShortString(), exchange);
_exchangeMapStr.put(exchange.getNameShortString().toString(), exchange);
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.exchangeRegistered(exchange);
+ }
+
+ }
}
public void setDefaultExchange(Exchange exchange)
@@ -114,6 +126,15 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
getDurableConfigurationStore().removeExchange(e);
}
e.close();
+
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.exchangeUnregistered(exchange);
+ }
+ }
+
}
else
{
@@ -126,6 +147,16 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
unregisterExchange(new AMQShortString(name), inUse);
}
+ public Collection<Exchange> getExchanges()
+ {
+ return new ArrayList<Exchange>(_exchangeMap.values());
+ }
+
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ _listeners.add(listener);
+ }
+
public Exchange getExchange(AMQShortString name)
{
if ((name == null) || name.length() == 0)
@@ -158,16 +189,14 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
{
final Exchange exchange = getExchange(exchangeName);
- if (exchange instanceof AbstractExchange)
+ //TODO: this is a bit of a hack, what if the listeners aren't aware
+ //that we are just unregistering the MBean because of HA, and aren't
+ //actually removing the exchange as such.
+ synchronized (_listeners)
{
- AbstractExchange abstractExchange = (AbstractExchange) exchange;
- try
- {
- abstractExchange.getManagedObject().unregister();
- }
- catch (AMQException e)
+ for(RegistryChangeListener listener : _listeners)
{
- LOGGER.warn("Failed to unregister mbean", e);
+ listener.exchangeUnregistered(exchange);
}
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index af9322764a..92326412c1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
@@ -127,11 +127,6 @@ public class DirectExchange extends AbstractExchange
super(TYPE);
}
- protected AbstractExchangeMBean createMBean() throws JMException
- {
- return new DirectExchangeMBean(this);
- }
-
public List<? extends BaseQueue> doRoute(InboundMessage payload)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java
deleted file mode 100644
index 0bfaf7035d..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.binding.Binding;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * MBean class implementing the management interfaces.
- */
-@MBeanDescription("Management Bean for Direct Exchange")
-final class DirectExchangeMBean extends AbstractExchangeMBean<DirectExchange>
-{
- @MBeanConstructor("Creates an MBean for AMQ direct exchange")
- public DirectExchangeMBean(final DirectExchange exchange) throws JMException
- {
- super(exchange);
-
- init();
- }
-
- public TabularData bindings() throws OpenDataException
- {
- TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType());
-
- Map<String, List<String>> bindingMap = new HashMap<String, List<String>>();
-
- for (Binding binding : getExchange().getBindings())
- {
- String key = binding.getBindingKey();
- List<String> queueList = bindingMap.get(key);
- if(queueList == null)
- {
- queueList = new ArrayList<String>();
- bindingMap.put(key, queueList);
- }
- queueList.add(binding.getQueue().getNameShortString().toString());
-
- }
-
- for(Map.Entry<String, List<String>> entry : bindingMap.entrySet())
- {
- Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(getBindingDataType(),
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- bindingItemValues);
- bindingList.put(bindingData);
- }
-
- return bindingList;
- }
-
-
-
-}// End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
index 795ae2e140..692a2b2b0d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
@@ -7,9 +7,9 @@
* to you 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
@@ -57,4 +57,14 @@ public interface ExchangeRegistry
void clearAndUnregisterMbeans();
Exchange getExchange(UUID exchangeId);
+
+ Collection<Exchange> getExchanges();
+
+ void addRegistryChangeListener(RegistryChangeListener listener);
+
+ interface RegistryChangeListener
+ {
+ void exchangeRegistered(Exchange exchange);
+ void exchangeUnregistered(Exchange exchange);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
index 5ebcfd095f..5f4998f77f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
@@ -48,11 +48,6 @@ public class FanoutExchange extends AbstractExchange
*/
private final ConcurrentHashMap<AMQQueue,Integer> _queues = new ConcurrentHashMap<AMQQueue,Integer>();
- protected AbstractExchangeMBean createMBean() throws JMException
- {
- return new FanoutExchangeMBean(this);
- }
-
public static final ExchangeType<FanoutExchange> TYPE = new ExchangeType<FanoutExchange>()
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java
deleted file mode 100644
index 61e23c896c..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.binding.Binding;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.util.ArrayList;
-
-/**
- * MBean class implementing the management interfaces.
- */
-@MBeanDescription("Management Bean for Fanout Exchange")
-final class FanoutExchangeMBean extends AbstractExchangeMBean<FanoutExchange>
-{
- private static final String BINDING_KEY_SUBSTITUTE = "*";
-
- @MBeanConstructor("Creates an MBean for AMQ fanout exchange")
- public FanoutExchangeMBean(final FanoutExchange exchange) throws JMException
- {
- super(exchange);
- init();
- }
-
- public TabularData bindings() throws OpenDataException
- {
-
- TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType());
-
-
- ArrayList<String> queueNames = new ArrayList<String>();
-
- for (Binding binding : getExchange().getBindings())
- {
- String queueName = binding.getQueue().getNameShortString().toString();
- queueNames.add(queueName);
- }
-
- Object[] bindingItemValues = {BINDING_KEY_SUBSTITUTE, queueNames.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(getBindingDataType(),
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- bindingItemValues);
- bindingList.put(bindingData);
-
- return bindingList;
- }
-
-
-} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 16ba3c0431..6bad59c2ae 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -227,11 +227,6 @@ public class HeadersExchange extends AbstractExchange
return !getBindings().isEmpty();
}
- protected AbstractExchangeMBean createMBean() throws JMException
- {
- return new HeadersExchangeMBean(this);
- }
-
protected void onBind(final Binding binding)
{
String bindingKey = binding.getBindingKey();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java
deleted file mode 100644
index 395c6c8a91..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.openmbean.ArrayType;
-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 java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * HeadersExchangeMBean class implements the management interface for the
- * Header Exchanges.
- */
-@MBeanDescription("Management Bean for Headers Exchange")
-final class HeadersExchangeMBean extends AbstractExchangeMBean<HeadersExchange>
-{
-
- @MBeanConstructor("Creates an MBean for AMQ Headers exchange")
- public HeadersExchangeMBean(final HeadersExchange headersExchange) throws JMException
- {
- super(headersExchange);
- init();
- }
-
- /**
- * initialises the OpenType objects.
- */
- protected void init() throws OpenDataException
- {
-
- setBindingItemTypes(new OpenType[3]);
- getBindingItemTypes()[0] = SimpleType.INTEGER;
- getBindingItemTypes()[1] = SimpleType.STRING;
- getBindingItemTypes()[2] = new ArrayType(1, SimpleType.STRING);
- setBindingDataType(new CompositeType("Exchange Binding", "Queue name and header bindings",
- HEADERS_COMPOSITE_ITEM_NAMES.toArray(new String[HEADERS_COMPOSITE_ITEM_NAMES.size()]),
- HEADERS_COMPOSITE_ITEM_DESC.toArray(new String[HEADERS_COMPOSITE_ITEM_DESC.size()]), getBindingItemTypes()));
- setBindinglistDataType(new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(),
- getBindingDataType(), HEADERS_TABULAR_UNIQUE_INDEX.toArray(new String[HEADERS_TABULAR_UNIQUE_INDEX.size()])));
- }
-
- public TabularData bindings() throws OpenDataException
- {
- TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType());
- int count = 1;
- for (Binding binding : getExchange().getBindings())
- {
-
- String queueName = binding.getQueue().getNameShortString().toString();
-
-
- Map<String,Object> headerMappings = binding.getArguments();
- final List<String> mappingList = new ArrayList<String>();
-
- if(headerMappings != null)
- {
- for(Map.Entry<String,Object> entry : headerMappings.entrySet())
- {
-
- mappingList.add(entry.getKey() + "=" + entry.getValue());
- }
- }
-
-
- Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])};
- CompositeData bindingData = new CompositeDataSupport(getBindingDataType(),
- HEADERS_COMPOSITE_ITEM_NAMES.toArray(new String[HEADERS_COMPOSITE_ITEM_NAMES.size()]), bindingItemValues);
- bindingList.put(bindingData);
- }
-
- return bindingList;
- }
-
- @Override
- public void createNewBinding(String queueName, String binding) throws JMException
- {
- VirtualHost vhost = getExchange().getVirtualHost();
- AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (queue == null)
- {
- throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost.");
- }
-
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
-
- final Map<String,Object> arguments = new HashMap<String, Object>();
- final String[] bindings = binding.split(",");
- for (int i = 0; i < bindings.length; i++)
- {
- final String[] keyAndValue = bindings[i].split("=");
- if (keyAndValue == null || keyAndValue.length == 0 || keyAndValue.length > 2 || keyAndValue[0].length() == 0)
- {
- throw new JMException("Format for headers binding should be \"<attribute1>=<value1>,<attribute2>=<value2>\" ");
- }
-
- if(keyAndValue.length == 1)
- {
- //no value was given, only a key. Use an empty value to signal match on key presence alone
- arguments.put(keyAndValue[0], "");
- }
- else
- {
- arguments.put(keyAndValue[0], keyAndValue[1]);
- }
- }
- try
- {
- vhost.getBindingFactory().addBinding(binding,queue,getExchange(),arguments);
- }
- catch (AMQException ex)
- {
- JMException jme = new JMException(ex.toString());
- throw new MBeanException(jme, "Error creating new binding " + binding);
- }
- CurrentActor.remove();
- }
-
-} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
index 7ea7a41826..480d4e4215 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
@@ -403,11 +403,6 @@ public class TopicExchange extends AbstractExchange
}
}
- protected AbstractExchangeMBean createMBean() throws JMException
- {
- return new TopicExchangeMBean(this);
- }
-
private Collection<AMQQueue> getMatchedQueues(InboundMessage message, AMQShortString routingKey)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java
deleted file mode 100644
index 481a377fc4..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.binding.Binding;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/** TopicExchangeMBean class implements the management interface for the Topic exchanges. */
-@MBeanDescription("Management Bean for Topic Exchange")
-final class TopicExchangeMBean extends AbstractExchangeMBean<TopicExchange>
-{
- private TopicExchange _topicExchange;
-
- @MBeanConstructor("Creates an MBean for AMQ topic exchange")
- public TopicExchangeMBean(final TopicExchange topicExchange) throws JMException
- {
- super(topicExchange);
- init();
- }
-
- /** returns exchange bindings in tabular form */
- public TabularData bindings() throws OpenDataException
- {
- TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType());
- Map<String, List<String>> bindingData = new HashMap<String, List<String>>();
- for (Binding binding : getExchange().getBindings())
- {
- String key = binding.getBindingKey();
- List<String> queueNames = bindingData.get(key);
- if(queueNames == null)
- {
- queueNames = new ArrayList<String>();
- bindingData.put(key, queueNames);
- }
- queueNames.add(binding.getQueue().getNameShortString().toString());
-
- }
- for(Map.Entry<String, List<String>> entry : bindingData.entrySet())
- {
- Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]) };
- CompositeData bindingCompositeData =
- new CompositeDataSupport(getBindingDataType(),
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- bindingItemValues);
- bindingList.put(bindingCompositeData);
- }
-
- return bindingList;
- }
-
-} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
deleted file mode 100644
index 4d395f625a..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.information.management;
-
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.management.common.mbeans.ServerInformation;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.management.JMException;
-import java.io.IOException;
-
-/** MBean class for the ServerInformationMBean. */
-@MBeanDescription("Server Information Interface")
-public class ServerInformationMBean extends AMQManagedObject implements ServerInformation
-{
- private String buildVersion;
- private String productVersion;
- private ApplicationRegistry registry;
-
- public ServerInformationMBean(ApplicationRegistry applicationRegistry) throws JMException
- {
- super(ServerInformation.class, ServerInformation.TYPE);
-
- registry = applicationRegistry;
- buildVersion = QpidProperties.getBuildVersion();
- productVersion = QpidProperties.getReleaseVersion();
- }
-
- public String getObjectInstanceName()
- {
- return ServerInformation.TYPE;
- }
-
- public Integer getManagementApiMajorVersion() throws IOException
- {
- return QPID_JMX_API_MAJOR_VERSION;
- }
-
- public Integer getManagementApiMinorVersion() throws IOException
- {
- return QPID_JMX_API_MINOR_VERSION;
- }
-
- public String getBuildVersion() throws IOException
- {
- return buildVersion;
- }
-
- public String getProductVersion() throws IOException
- {
- return productVersion;
- }
-
-
- public void resetStatistics() throws Exception
- {
- registry.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return registry.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return registry.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return registry.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return registry.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return registry.isStatisticsEnabled();
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
new file mode 100644
index 0000000000..a1065319d3
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.logging;
+
+import java.util.Iterator;
+import org.apache.log4j.Appender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.ErrorHandler;
+import org.apache.log4j.spi.Filter;
+import org.apache.log4j.spi.LoggingEvent;
+
+public class LogRecorder implements Appender, Iterable<LogRecorder.Record>
+{
+ private ErrorHandler _errorHandler;
+ private Filter _filter;
+ private String _name;
+ private long _recordId;
+
+ private final int _bufferSize = 4096;
+ private final int _mask = _bufferSize - 1;
+ private Record[] _records = new Record[_bufferSize];
+
+
+ public static class Record
+ {
+ private final long _id;
+ private final String _logger;
+ private final long _timestamp;
+ private final String _threadName;
+ private final String _level;
+ private final String _message;
+
+
+ public Record(long id, LoggingEvent event)
+ {
+ _id = id;
+ _logger = event.getLoggerName();
+ _timestamp = event.timeStamp;
+ _threadName = event.getThreadName();
+ _level = event.getLevel().toString();
+ _message = event.getRenderedMessage();
+ }
+
+ public long getId()
+ {
+ return _id;
+ }
+
+ public long getTimestamp()
+ {
+ return _timestamp;
+ }
+
+ public String getThreadName()
+ {
+ return _threadName;
+ }
+
+ public String getLevel()
+ {
+ return _level;
+ }
+
+ public String getMessage()
+ {
+ return _message;
+ }
+
+ public String getLogger()
+ {
+ return _logger;
+ }
+ }
+
+ public LogRecorder()
+ {
+
+ Logger.getRootLogger().addAppender(this);
+ }
+
+ @Override
+ public void addFilter(Filter filter)
+ {
+ _filter = filter;
+ }
+
+ @Override
+ public void clearFilters()
+ {
+ _filter = null;
+ }
+
+ @Override
+ public void close()
+ {
+ //TODO - Implement
+ }
+
+ @Override
+ public synchronized void doAppend(LoggingEvent loggingEvent)
+ {
+ _records[((int) (_recordId & _mask))] = new Record(_recordId, loggingEvent);
+ _recordId++;
+ }
+
+ @Override
+ public ErrorHandler getErrorHandler()
+ {
+ return _errorHandler;
+ }
+
+ @Override
+ public Filter getFilter()
+ {
+ return _filter;
+ }
+
+ @Override
+ public Layout getLayout()
+ {
+ return null;
+ }
+
+ @Override
+ public String getName()
+ {
+ return _name;
+ }
+
+ @Override
+ public boolean requiresLayout()
+ {
+ return false;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler errorHandler)
+ {
+ _errorHandler = errorHandler;
+ }
+
+ @Override
+ public void setLayout(Layout layout)
+ {
+
+ }
+
+ @Override
+ public void setName(String name)
+ {
+ _name = name;
+ }
+
+ @Override
+ public Iterator<Record> iterator()
+ {
+ return new RecordIterator(Math.max(_recordId-_bufferSize, 0l));
+ }
+
+ private class RecordIterator implements Iterator<Record>
+ {
+ private long _id;
+
+ public RecordIterator(long currentRecordId)
+ {
+ _id = currentRecordId;
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return _id < _recordId;
+ }
+
+ @Override
+ public Record next()
+ {
+ Record record = _records[((int) (_id & _mask))];
+ while(_id < _recordId-_bufferSize)
+ {
+ _id = _recordId-_bufferSize;
+ record = _records[((int) (_id & _mask))];
+ }
+ _id++;
+ return record;
+ }
+
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
deleted file mode 100644
index c699dff175..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.logging.management;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.xml.Log4jEntityResolver;
-import org.apache.log4j.xml.QpidLog4JConfigurator;
-import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException;
-import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-
-import org.apache.qpid.management.common.mbeans.LoggingManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.management.AMQManagedObject;
-
-import javax.management.JMException;
-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.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK;
-
-
-/** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */
-@MBeanDescription("Logging Management Interface")
-public class LoggingManagementMBean extends AMQManagedObject implements LoggingManagement
-{
-
- private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class);
- private String _log4jConfigFileName;
- private int _log4jLogWatchInterval;
- private static final String INHERITED = "INHERITED";
- private static final String[] LEVELS = new String[]{Level.ALL.toString(), Level.TRACE.toString(),
- Level.DEBUG.toString(), Level.INFO.toString(),
- Level.WARN.toString(), Level.ERROR.toString(),
- Level.FATAL.toString(),Level.OFF.toString(),
- INHERITED};
- private static TabularType _loggerLevelTabularType;
- private static CompositeType _loggerLevelCompositeType;
-
- static
- {
- try
- {
- OpenType[] loggerLevelItemTypes = new OpenType[]{SimpleType.STRING, SimpleType.STRING};
-
- _loggerLevelCompositeType = new CompositeType("LoggerLevelList", "Logger Level Data",
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- COMPOSITE_ITEM_DESCRIPTIONS.toArray(new String[COMPOSITE_ITEM_DESCRIPTIONS.size()]),
- loggerLevelItemTypes);
-
- _loggerLevelTabularType = new TabularType("LoggerLevel", "List of loggers with levels",
- _loggerLevelCompositeType,
- TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()]));
- }
- catch (OpenDataException e)
- {
- _logger.error("Tabular data setup for viewing logger levels was incorrect.");
- _loggerLevelTabularType = null;
- }
- }
-
- public LoggingManagementMBean(String log4jConfigFileName, int log4jLogWatchInterval) throws JMException
- {
- super(LoggingManagement.class, LoggingManagement.TYPE);
- _log4jConfigFileName = log4jConfigFileName;
- _log4jLogWatchInterval = log4jLogWatchInterval;
- }
-
- public String getObjectInstanceName()
- {
- return LoggingManagement.TYPE;
- }
-
- public Integer getLog4jLogWatchInterval()
- {
- return _log4jLogWatchInterval;
- }
-
- public String[] getAvailableLoggerLevels()
- {
- return LEVELS;
- }
- @SuppressWarnings("unchecked")
- public synchronized boolean setRuntimeLoggerLevel(String logger, String level)
- {
- //check specified level is valid
- Level newLevel;
- try
- {
- newLevel = getLevel(level);
- }
- catch (Exception e)
- {
- return false;
- }
-
- //check specified logger exists
- Enumeration loggers = LogManager.getCurrentLoggers();
- Boolean loggerExists = false;
-
- while(loggers.hasMoreElements())
- {
- Logger log = (Logger) loggers.nextElement();
- if (log.getName().equals(logger))
- {
- loggerExists = true;
- break;
- }
- }
-
- if(!loggerExists)
- {
- return false;
- }
-
- //set the logger to the new level
- _logger.info("Setting level to " + level + " for logger: " + logger);
-
- Logger log = Logger.getLogger(logger);
- log.setLevel(newLevel);
-
- return true;
- }
-
- @SuppressWarnings("unchecked")
- public synchronized TabularData viewEffectiveRuntimeLoggerLevels()
- {
- if (_loggerLevelTabularType == null)
- {
- _logger.warn("TabluarData type not set up correctly");
- return null;
- }
-
- _logger.info("Getting levels for currently active log4j loggers");
-
- Enumeration loggers = LogManager.getCurrentLoggers();
-
- TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
-
- Logger logger;
- String loggerName;
- String level;
-
- try
- {
- while(loggers.hasMoreElements()){
- logger = (Logger) loggers.nextElement();
-
- loggerName = logger.getName();
- level = logger.getEffectiveLevel().toString();
-
- Object[] itemData = {loggerName, level};
- CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType,
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
- loggerLevelList.put(loggerData);
- }
- }
- catch (OpenDataException e)
- {
- _logger.warn("Unable to create logger level list due to :" + e);
- return null;
- }
-
- return loggerLevelList;
-
- }
-
- public synchronized String getRuntimeRootLoggerLevel()
- {
- Logger rootLogger = Logger.getRootLogger();
-
- return rootLogger.getLevel().toString();
- }
-
- public synchronized boolean setRuntimeRootLoggerLevel(String level)
- {
- Level newLevel;
- try
- {
- newLevel = getLevel(level);
- }
- catch (Exception e)
- {
- return false;
- }
-
- if(newLevel == null)
- {
- //A null Level reference implies inheritance. Setting the runtime RootLogger
- //to null is catastrophic (and prevented by Log4J at startup and runtime anyway).
- return false;
- }
-
- _logger.info("Setting RootLogger level to " + level);
-
- Logger log = Logger.getRootLogger();
- log.setLevel(newLevel);
-
- return true;
- }
-
- //method to convert from a string to a log4j Level, throws exception if the given value is invalid
- private Level getLevel(String level) throws Exception
- {
- if("null".equalsIgnoreCase(level) || INHERITED.equalsIgnoreCase(level))
- {
- //the string "null" or "inherited" signals to inherit from a parent logger,
- //using a null Level reference for the logger.
- return null;
- }
-
- Level newLevel = Level.toLevel(level);
-
- //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result.
- if (newLevel.equals(Level.DEBUG) && !(level.equalsIgnoreCase("debug")))
- {
- //received DEBUG but we did not ask for it, the Level request failed.
- throw new Exception("Invalid level name");
- }
-
- return newLevel;
- }
-
- //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
- private static synchronized Document parseConfigFile(String fileName) throws IOException
- {
- try
- {
- LOCK.lock();
-
- //check file was specified, exists, and is readable
- if(fileName == null)
- {
- _logger.warn("Provided log4j XML configuration filename is null");
- throw new IOException("Provided log4j XML configuration filename is null");
- }
-
- File configFile = new File(fileName);
-
- if (!configFile.exists())
- {
- _logger.warn("The log4j XML configuration file could not be found: " + fileName);
- throw new IOException("The log4j XML configuration file could not be found");
- }
- else if (!configFile.canRead())
- {
- _logger.warn("The log4j XML configuration file is not readable: " + fileName);
- throw new IOException("The log4j XML configuration file is not readable");
- }
-
- //parse it
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder;
- Document doc;
-
- ErrorHandler errHandler = new QpidLog4JSaxErrorHandler();
- try
- {
- docFactory.setValidating(true);
- docBuilder = docFactory.newDocumentBuilder();
- docBuilder.setErrorHandler(errHandler);
- docBuilder.setEntityResolver(new Log4jEntityResolver());
- doc = docBuilder.parse(fileName);
- }
- catch (ParserConfigurationException e)
- {
- _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e);
- //recommended that MBeans should use java.* and javax.* exceptions only
- throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage());
- }
- catch (SAXException e)
- {
- _logger.warn("The specified log4j XML file is invalid: " + e);
- //recommended that MBeans should use standard java.* and javax.* exceptions only
- throw new IOException("The specified log4j XML file is invalid: " + e.getMessage());
- }
- catch (IOException e)
- {
- _logger.warn("Unable to parse the specified log4j XML file" + e);
- throw new IOException("Unable to parse the specified log4j XML file: " + e.getMessage());
- }
-
- return doc;
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
-
- private static synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException
- {
- try
- {
- LOCK.lock();
-
- File log4jConfigFile = new File(log4jConfigFileName);
-
- if (!log4jConfigFile.canWrite())
- {
- _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile);
- throw new IOException("Specified log4j XML configuration file is not writable");
- }
-
- Transformer transformer = null;
- try
- {
- transformer = TransformerFactory.newInstance().newTransformer();
- }
- catch (Exception e)
- {
- _logger.warn("Could not create an XML transformer: " +e);
- return false;
- }
-
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd");
- DOMSource source = new DOMSource(doc);
-
- File tmp;
- Random r = new Random();
- do
- {
- tmp = new File(log4jConfigFile.getPath() + r.nextInt() + ".tmp");
- }
- while(tmp.exists());
-
- tmp.deleteOnExit();
-
- try
- {
- StreamResult result = new StreamResult(tmp);
- transformer.transform(source, result);
- }
- catch (TransformerException e)
- {
- _logger.warn("Could not transform the XML into new file: " +e);
- throw new IOException("Could not transform the XML into new file: " +e);
- }
-
- // Swap temp file in to replace existing configuration file.
- File old = new File(log4jConfigFile.getAbsoluteFile() + ".old");
- if (old.exists())
- {
- old.delete();
- }
-
- if(!log4jConfigFile.renameTo(old))
- {
- //unable to rename the existing file to the backup name
- _logger.error("Could not backup the existing log4j XML file");
- throw new IOException("Could not backup the existing log4j XML file");
- }
-
- if(!tmp.renameTo(log4jConfigFile))
- {
- //failed to rename the new file to the required filename
-
- if(!old.renameTo(log4jConfigFile))
- {
- //unable to return the backup to required filename
- _logger.error("Could not rename the new log4j configuration file into place, and unable to restore original file");
- throw new IOException("Could not rename the new log4j configuration file into place, and unable to restore original file");
- }
-
- _logger.error("Could not rename the new log4j configuration file into place");
- throw new IOException("Could not rename the new log4j configuration file into place");
- }
-
- return true;
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
-
- /* The log4j XML configuration file DTD defines three possible element
- * combinations for specifying optional logger+level settings.
- * Must account for the following:
- *
- * <category name="x"> <priority value="y"/> </category> OR
- * <category name="x"> <level value="y"/> </category> OR
- * <logger name="x"> <level value="y"/> </logger>
- *
- * Noting also that the level/priority child element is optional too,
- * and not the only possible child element.
- */
-
- public static synchronized Map<String,String> retrieveConfigFileLoggersLevels(String fileName) throws IOException
- {
- try
- {
- LOCK.lock();
-
- Document doc = parseConfigFile(fileName);
-
- HashMap<String,String> loggerLevelList = new HashMap<String,String>();
-
- //retrieve the 'category' element nodes
- NodeList categoryElements = doc.getElementsByTagName("category");
-
- String categoryName;
- String priority = null;
-
- for (int i = 0; i < categoryElements.getLength(); i++)
- {
- Element categoryElement = (Element) categoryElements.item(i);
- categoryName = categoryElement.getAttribute("name");
-
- //retrieve the category's mandatory 'priority' or 'level' element's value.
- //It may not be the only child node, so request by tag name.
- NodeList priorityElements = categoryElement.getElementsByTagName("priority");
- NodeList levelElements = categoryElement.getElementsByTagName("level");
-
- if (priorityElements.getLength() != 0)
- {
- Element priorityElement = (Element) priorityElements.item(0);
- priority = priorityElement.getAttribute("value");
- }
- else if (levelElements.getLength() != 0)
- {
- Element levelElement = (Element) levelElements.item(0);
- priority = levelElement.getAttribute("value");
- }
- else
- {
- //there is no exiting priority or level to view, move onto next category/logger
- continue;
- }
-
- loggerLevelList.put(categoryName, priority);
- }
-
- //retrieve the 'logger' element nodes
- NodeList loggerElements = doc.getElementsByTagName("logger");
-
- String loggerName;
- String level;
-
- for (int i = 0; i < loggerElements.getLength(); i++)
- {
- Element loggerElement = (Element) loggerElements.item(i);
- loggerName = loggerElement.getAttribute("name");
-
- //retrieve the logger's mandatory 'level' element's value
- //It may not be the only child node, so request by tag name.
- NodeList levelElements = loggerElement.getElementsByTagName("level");
-
- Element levelElement = (Element) levelElements.item(0);
- level = levelElement.getAttribute("value");
-
- loggerLevelList.put(loggerName, level);
- }
-
- return loggerLevelList;
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public synchronized TabularData viewConfigFileLoggerLevels() throws IOException
- {
- try
- {
- LOCK.lock();
-
- if (_loggerLevelTabularType == null)
- {
- _logger.warn("TabluarData type not set up correctly");
- return null;
- }
-
- _logger.info("Getting logger levels from log4j configuration file");
-
- TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
-
- Map<String,String> levels = retrieveConfigFileLoggersLevels(_log4jConfigFileName);
-
- for (Map.Entry<String,String> entry : levels.entrySet())
- {
- String loggerName = entry.getKey();
- String level = entry.getValue();
-
- try
- {
- Object[] itemData = {loggerName, level.toUpperCase()};
- CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType,
- COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
- loggerLevelList.put(loggerData);
- }
- catch (OpenDataException e)
- {
- _logger.warn("Unable to create logger level list due to :" + e);
- return null;
- }
- }
-
- return loggerLevelList;
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException
- {
- try
- {
- LOCK.lock();
-
- //check that the specified level is a valid log4j Level
- try
- {
- getLevel(level);
- }
- catch (Exception e)
- {
- //it isnt a valid level
- return false;
- }
-
- _logger.info("Setting level to " + level + " for logger '" + logger
- + "' in log4j xml configuration file: " + _log4jConfigFileName);
-
- Document doc = parseConfigFile(_log4jConfigFileName);
-
- //retrieve the 'category' and 'logger' element nodes
- NodeList categoryElements = doc.getElementsByTagName("category");
- NodeList loggerElements = doc.getElementsByTagName("logger");
-
- //collect them into a single elements list
- List<Element> logElements = new ArrayList<Element>();
-
- for (int i = 0; i < categoryElements.getLength(); i++)
- {
- logElements.add((Element) categoryElements.item(i));
- }
- for (int i = 0; i < loggerElements.getLength(); i++)
- {
- logElements.add((Element) loggerElements.item(i));
- }
-
- //try to locate the specified logger/category in the elements retrieved
- Element logElement = null;
- for (Element e : logElements)
- {
- if (e.getAttribute("name").equals(logger))
- {
- logElement = e;
- break;
- }
- }
-
- if (logElement == null)
- {
- //no loggers/categories with given name found, does not exist to update
- _logger.warn("Specified logger does not exist in the configuration file: " +logger);
- return false;
- }
-
- //retrieve the optional 'priority' or 'level' sub-element value.
- //It may not be the only child node, so request by tag name.
- NodeList priorityElements = logElement.getElementsByTagName("priority");
- NodeList levelElements = logElement.getElementsByTagName("level");
-
- Element levelElement = null;
- if (priorityElements.getLength() != 0)
- {
- levelElement = (Element) priorityElements.item(0);
- }
- else if (levelElements.getLength() != 0)
- {
- levelElement = (Element) levelElements.item(0);
- }
- else
- {
- //there is no exiting priority or level element to update
- return false;
- }
-
- //update the element with the new level/priority
- levelElement.setAttribute("value", level.toLowerCase());
-
- //output the new file
- return writeUpdatedConfigFile(_log4jConfigFileName, doc);
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
-
- /* The log4j XML configuration file DTD defines 2 possible element
- * combinations for specifying the optional root logger level settings
- * Must account for the following:
- *
- * <root> <priority value="y"/> </root> OR
- * <root> <level value="y"/> </root>
- *
- * Noting also that the level/priority child element is optional too,
- * and not the only possible child element.
- */
-
- public static synchronized String retrieveConfigFileRootLoggerLevel(String fileName) throws IOException
- {
- try
- {
- LOCK.lock();
-
- Document doc = parseConfigFile(fileName);
-
- //retrieve the optional 'root' element node
- NodeList rootElements = doc.getElementsByTagName("root");
-
- if (rootElements.getLength() == 0)
- {
- //there is no root logger definition
- return "N/A";
- }
-
- Element rootElement = (Element) rootElements.item(0);
-
- //retrieve the optional 'priority' or 'level' element value.
- //It may not be the only child node, so request by tag name.
- NodeList priorityElements = rootElement.getElementsByTagName("priority");
- NodeList levelElements = rootElement.getElementsByTagName("level");
- String priority = null;
-
- if (priorityElements.getLength() != 0)
- {
- Element priorityElement = (Element) priorityElements.item(0);
- priority = priorityElement.getAttribute("value");
- }
- else if(levelElements.getLength() != 0)
- {
- Element levelElement = (Element) levelElements.item(0);
- priority = levelElement.getAttribute("value");
- }
-
- if(priority != null)
- {
- return priority;
- }
- else
- {
- return "N/A";
- }
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public synchronized String getConfigFileRootLoggerLevel() throws IOException
- {
- return retrieveConfigFileRootLoggerLevel(_log4jConfigFileName).toUpperCase();
- }
-
- public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException
- {
- try
- {
- LOCK.lock();
-
- //check that the specified level is a valid log4j Level
- try
- {
- Level newLevel = getLevel(level);
- if(newLevel == null)
- {
- //A null Level reference implies inheritance. Setting the config file RootLogger
- //to "null" or "inherited" just ensures it defaults to DEBUG at startup as Log4J
- //prevents this catastrophic situation at startup and runtime anyway.
- return false;
- }
- }
- catch (Exception e)
- {
- //it isnt a valid level
- return false;
- }
-
- _logger.info("Setting level to " + level + " for the Root logger in " +
- "log4j xml configuration file: " + _log4jConfigFileName);
-
- Document doc = parseConfigFile(_log4jConfigFileName);
-
- //retrieve the optional 'root' element node
- NodeList rootElements = doc.getElementsByTagName("root");
-
- if (rootElements.getLength() == 0)
- {
- return false;
- }
-
- Element rootElement = (Element) rootElements.item(0);
-
- //retrieve the optional 'priority' or 'level' sub-element value.
- //It may not be the only child node, so request by tag name.
- NodeList priorityElements = rootElement.getElementsByTagName("priority");
- NodeList levelElements = rootElement.getElementsByTagName("level");
-
- Element levelElement = null;
- if (priorityElements.getLength() != 0)
- {
- levelElement = (Element) priorityElements.item(0);
- }
- else if (levelElements.getLength() != 0)
- {
- levelElement = (Element) levelElements.item(0);
- }
- else
- {
- //there is no exiting priority/level to update
- return false;
- }
-
- //update the element with the new level/priority
- levelElement.setAttribute("value", level);
-
- //output the new file
- return writeUpdatedConfigFile(_log4jConfigFileName, doc);
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public synchronized void reloadConfigFile() throws IOException
- {
- try
- {
- LOCK.lock();
-
- QpidLog4JConfigurator.configure(_log4jConfigFileName);
- _logger.info("Applied log4j configuration from: " + _log4jConfigFileName);
- }
- catch (IllegalLoggerLevelException e)
- {
- _logger.warn("The log4j configuration reload request was aborted: " + e);
- //recommended that MBeans should use standard java.* and javax.* exceptions only
- throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
- }
- catch (ParserConfigurationException e)
- {
- _logger.warn("The log4j configuration reload request was aborted: " + e);
- throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
- }
- catch (SAXException e)
- {
- _logger.warn("The log4j configuration reload request was aborted: " + e);
- //recommended that MBeans should use standard java.* and javax.* exceptions only
- throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
- }
- catch (IOException e)
- {
- _logger.warn("The log4j configuration reload request was aborted: " + e);
- throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage());
- }
- finally
- {
- LOCK.unlock();
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
deleted file mode 100644
index 5c57c01f6e..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-
-import javax.management.ListenerNotFoundException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationBroadcaster;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-
-/**
- * This class provides additinal feature of Notification Broadcaster to the
- * DefaultManagedObject.
- * @author Bhupendra Bhardwaj
- * @version 0.1
- */
-public abstract class AMQManagedObject extends DefaultManagedObject
- implements NotificationBroadcaster
-{
- private NotificationBroadcasterSupport _broadcaster = new NotificationBroadcasterSupport();
-
- private long _notificationSequenceNumber = 0;
-
- private LogActor _logActor;
-
- protected AMQManagedObject(Class<?> managementInterface, String typeName)
- throws NotCompliantMBeanException
- {
- super(managementInterface, typeName);
- // CurrentActor will be defined as these objects are created during
- // broker startup.
- _logActor = new ManagementActor(CurrentActor.get().getRootMessageLogger());
- }
-
- // notification broadcaster implementation
-
- public void addNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- {
- _broadcaster.addNotificationListener(listener, filter, handback);
- }
-
- public void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException
- {
- _broadcaster.removeNotificationListener(listener);
- }
-
-
- /**
- * broadcaster support class
- */
- protected NotificationBroadcasterSupport getBroadcaster()
- {
- return _broadcaster;
- }
-
- /**
- * sequence number for notifications
- */
- protected long getNotificationSequenceNumber()
- {
- return _notificationSequenceNumber;
- }
-
- protected void setNotificationSequenceNumber(long notificationSequenceNumber)
- {
- _notificationSequenceNumber = notificationSequenceNumber;
- }
-
- protected long incrementAndGetSequenceNumber()
- {
- return ++_notificationSequenceNumber;
- }
-
- protected LogActor getLogActor()
- {
- return _logActor;
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java
deleted file mode 100644
index 6cfc827046..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-import javax.management.JMException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.ObjectName;
-import javax.management.monitor.MonitorNotification;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularType;
-
-public abstract class AbstractAMQManagedConnectionObject extends AMQManagedObject implements ManagedConnection
-{
- private final String _name;
-
- protected static final OpenType[] _channelAttributeTypes = { SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.INTEGER, SimpleType.BOOLEAN };
- protected static final CompositeType _channelType;
- protected static final TabularType _channelsType;
-
- protected static final String BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION_STR =
- "Broker Management Console has closed the connection.";
-
- static
- {
- try
- {
- _channelType = new CompositeType("Channel", "Channel Details", COMPOSITE_ITEM_NAMES_DESC.toArray(new String[COMPOSITE_ITEM_NAMES_DESC.size()]),
- COMPOSITE_ITEM_NAMES_DESC.toArray(new String[COMPOSITE_ITEM_NAMES_DESC.size()]), _channelAttributeTypes);
- _channelsType = new TabularType("Channels", "Channels", _channelType, (String[]) TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()]));
- }
- catch (JMException ex)
- {
- // This is not expected to ever occur.
- throw new RuntimeException("Got JMException in static initializer.", ex);
- }
- }
-
- protected AbstractAMQManagedConnectionObject(final String remoteAddress) throws NotCompliantMBeanException
- {
- super(ManagedConnection.class, ManagedConnection.TYPE);
- _name = "anonymous".equals(remoteAddress) ? (remoteAddress + hashCode()) : remoteAddress;
- }
-
- public String getObjectInstanceName()
- {
- return ObjectName.quote(_name);
- }
-
- public void notifyClients(String notificationMsg)
- {
- final Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, incrementAndGetSequenceNumber(),
- System.currentTimeMillis(), notificationMsg);
- getBroadcaster().sendNotification(n);
- }
-
- @Override
- public MBeanNotificationInfo[] getNotificationInfo()
- {
- String[] notificationTypes = new String[] { MonitorNotification.THRESHOLD_VALUE_EXCEEDED };
- String name = MonitorNotification.class.getName();
- String description = "Channel count has reached threshold value";
- MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
-
- return new MBeanNotificationInfo[] { info1 };
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
deleted file mode 100644
index 10d7503800..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.log4j.Logger;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.management.JMException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanNotificationInfo;
-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 extends StandardMBean implements ManagedObject
-{
- private static final Logger LOGGER = Logger.getLogger(DefaultManagedObject.class);
-
- private final Class<?> _managementInterface;
-
- private final String _typeName;
-
- private final MBeanInfo _mbeanInfo;
-
- private ManagedObjectRegistry _registry;
-
- protected DefaultManagedObject(Class<?> managementInterface, String typeName)
- throws NotCompliantMBeanException
- {
- super(managementInterface);
- _managementInterface = managementInterface;
- _typeName = typeName;
- _mbeanInfo = buildMBeanInfo();
- }
-
- @Override
- public MBeanInfo getMBeanInfo()
- {
- return _mbeanInfo;
- }
-
- public String getType()
- {
- return _typeName;
- }
-
- public Class<?> getManagementInterface()
- {
- return _managementInterface;
- }
-
- public ManagedObject getParentObject()
- {
- return null;
- }
-
- public void register() throws JMException
- {
- _registry = ApplicationRegistry.getInstance().getManagedObjectRegistry();
- _registry.registerObject(this);
- }
-
- public void unregister()
- {
- try
- {
- if(_registry != null)
- {
- _registry.unregisterObject(this);
- }
- }
- catch (JMException e)
- {
- LOGGER.error("Error unregistering managed object: " + this + ": " + e, e);
- }
- finally
- {
- _registry = null;
- }
- }
-
- public String toString()
- {
- return getObjectInstanceName() + "[" + getType() + "]";
- }
-
- /**
- * Created the ObjectName as per the JMX Specs
- * @return ObjectName
- * @throws MalformedObjectNameException
- */
- public ObjectName getObjectName() throws MalformedObjectNameException
- {
- String name = getObjectInstanceName();
- StringBuffer objectName = new StringBuffer(ManagedObject.DOMAIN);
-
- objectName.append(":type=");
- objectName.append(getHierarchicalType(this));
-
- objectName.append(",");
- objectName.append(getHierarchicalName(this));
- objectName.append("name=").append(name);
-
- return new ObjectName(objectName.toString());
- }
-
- protected ObjectName getObjectNameForSingleInstanceMBean() throws MalformedObjectNameException
- {
- StringBuffer objectName = new StringBuffer(ManagedObject.DOMAIN);
-
- objectName.append(":type=");
- objectName.append(getHierarchicalType(this));
-
- String hierarchyName = getHierarchicalName(this);
- if (hierarchyName != null)
- {
- objectName.append(",");
- objectName.append(hierarchyName.substring(0, hierarchyName.lastIndexOf(",")));
- }
-
- return new ObjectName(objectName.toString());
- }
-
- protected String getHierarchicalType(ManagedObject obj)
- {
- if (obj.getParentObject() != null)
- {
- String parentType = getHierarchicalType(obj.getParentObject()).toString();
- return parentType + "." + obj.getType();
- }
- else
- {
- return obj.getType();
- }
- }
-
- protected String getHierarchicalName(ManagedObject obj)
- {
- if (obj.getParentObject() != null)
- {
- String parentName = obj.getParentObject().getType() + "=" +
- obj.getParentObject().getObjectInstanceName() + ","+
- getHierarchicalName(obj.getParentObject());
-
- return parentName;
- }
- else
- {
- return "";
- }
- }
-
- private MBeanInfo buildMBeanInfo() throws NotCompliantMBeanException
- {
- return new MBeanInfo(this.getClass().getName(),
- MBeanIntrospector.getMBeanDescription(this.getClass()),
- MBeanIntrospector.getMBeanAttributesInfo(getManagementInterface()),
- MBeanIntrospector.getMBeanConstructorsInfo(this.getClass()),
- MBeanIntrospector.getMBeanOperationsInfo(getManagementInterface()),
- this.getNotificationInfo());
- }
-
- public MBeanNotificationInfo[] getNotificationInfo()
- {
- return null;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
deleted file mode 100644
index 869a816cf1..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Proxy;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.rmi.AlreadyBoundException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.NotBoundException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-import java.security.Principal;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.Notification;
-import javax.management.NotificationFilterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.rmi.RMIConnection;
-import javax.management.remote.rmi.RMIConnectorServer;
-import javax.management.remote.rmi.RMIJRMPServerImpl;
-import javax.management.remote.rmi.RMIServerImpl;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.rmi.ssl.SslRMIServerSocketFactory;
-import javax.security.auth.Subject;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
-
-/**
- * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
- * security features implemented like user authentication and authorisation.
- */
-public class JMXManagedObjectRegistry implements ManagedObjectRegistry
-{
- private static final Logger _log = Logger.getLogger(JMXManagedObjectRegistry.class);
-
- private final MBeanServer _mbeanServer;
- private JMXConnectorServer _cs;
- private Registry _rmiRegistry;
- private boolean _useCustomSocketFactory;
-
- private final int _jmxPortRegistryServer;
- private final int _jmxPortConnectorServer;
-
- public JMXManagedObjectRegistry() throws AMQException
- {
- _log.info("Initialising managed object registry using platform MBean server");
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
-
- // Retrieve the config parameters
- _useCustomSocketFactory = appRegistry.getConfiguration().getUseCustomRMISocketFactory();
- boolean platformServer = appRegistry.getConfiguration().getPlatformMbeanserver();
-
- _mbeanServer =
- platformServer ? ManagementFactory.getPlatformMBeanServer()
- : MBeanServerFactory.createMBeanServer(ManagedObject.DOMAIN);
-
- _jmxPortRegistryServer = appRegistry.getConfiguration().getJMXPortRegistryServer();
- _jmxPortConnectorServer = appRegistry.getConfiguration().getJMXConnectorServerPort();
-
- }
-
- public void start() throws IOException, ConfigurationException
- {
-
- CurrentActor.get().message(ManagementConsoleMessages.STARTUP());
-
- //check if system properties are set to use the JVM's out-of-the-box JMXAgent
- if (areOutOfTheBoxJMXOptionsSet())
- {
- CurrentActor.get().message(ManagementConsoleMessages.READY(true));
- return;
- }
-
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
-
-
- //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
- RMIClientSocketFactory csf;
- RMIServerSocketFactory ssf;
-
- //check ssl enabled option in config, default to true if option is not set
- boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled();
-
- if (sslEnabled)
- {
- //set the SSL related system properties used by the SSL RMI socket factories to the values
- //given in the configuration file, unless command line settings have already been specified
- String keyStorePath;
-
- if(System.getProperty("javax.net.ssl.keyStore") != null)
- {
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
- }
- else
- {
- keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
- }
-
- //check the keystore path value is valid
- if (keyStorePath == null)
- {
- throw new ConfigurationException("JMX management SSL keystore path not defined, " +
- "unable to start SSL protected JMX ConnectorServer");
- }
- else
- {
- //ensure the system property is set
- System.setProperty("javax.net.ssl.keyStore", keyStorePath);
-
- //check the file is usable
- File ksf = new File(keyStorePath);
-
- if (!ksf.exists())
- {
- throw new FileNotFoundException("Cannot find JMX management SSL keystore file: " + ksf);
- }
- if (!ksf.canRead())
- {
- throw new FileNotFoundException("Cannot read JMX management SSL keystore file: "
- + ksf + ". Check permissions.");
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(ksf.getAbsolutePath()));
- }
-
- //check the key store password is set
- if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
- {
-
- if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null)
- {
- throw new ConfigurationException("JMX management SSL keystore password not defined, " +
- "unable to start requested SSL protected JMX server");
- }
- else
- {
- System.setProperty("javax.net.ssl.keyStorePassword",
- appRegistry.getConfiguration().getManagementKeyStorePassword());
- }
- }
-
- //create the SSL RMI socket factories
- csf = new SslRMIClientSocketFactory();
- ssf = new SslRMIServerSocketFactory();
- }
- else
- {
- //Do not specify any specific RMI socket factories, resulting in use of the defaults.
- csf = null;
- ssf = null;
- }
-
- //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
- RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
- rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager(new InetSocketAddress(_jmxPortRegistryServer)));
- HashMap<String,Object> env = new HashMap<String,Object>();
- env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
-
- /*
- * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub.
- * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
- * As a result, only binds made using the object reference will succeed, thus securing it from external change.
- */
- System.setProperty("java.rmi.server.randomIDs", "true");
- if(_useCustomSocketFactory)
- {
- _rmiRegistry = LocateRegistry.createRegistry(_jmxPortRegistryServer, null, new CustomRMIServerSocketFactory());
- }
- else
- {
- _rmiRegistry = LocateRegistry.createRegistry(_jmxPortRegistryServer, null, null);
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", _jmxPortRegistryServer));
-
- /*
- * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls
- * to bind the ConnectorServer to the registry, which will now fail as for security we have
- * locked it from any RMI based modifications, including our own. Instead, we will manually bind
- * the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
- *
- * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
- * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's.
- */
- final Map<String, String> connectionIdUsernameMap = new ConcurrentHashMap<String, String>();
- final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(_jmxPortConnectorServer, csf, ssf, env)
- {
-
- /**
- * Override makeClient so we can cache the username of the client in a Map keyed by connectionId.
- * ConnectionId is guaranteed to be unique per client connection, according to the JMS spec.
- * An instance of NotificationListener (mapCleanupListener) will be responsible for removing these Map
- * entries.
- *
- * @see javax.management.remote.rmi.RMIJRMPServerImpl#makeClient(java.lang.String, javax.security.auth.Subject)
- */
- @Override
- protected RMIConnection makeClient(String connectionId, Subject subject) throws IOException
- {
- final RMIConnection makeClient = super.makeClient(connectionId, subject);
- final Principal principal = subject.getPrincipals().iterator().next();
- connectionIdUsernameMap.put(connectionId, principal.getName());
- return makeClient;
- }
- };
-
- // Create a Listener responsible for removing the map entries add by the #makeClient entry above.
- final NotificationListener mapCleanupListener = new NotificationListener()
- {
-
- @Override
- public void handleNotification(Notification notification, Object handback)
- {
- final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
- connectionIdUsernameMap.remove(connectionId);
- }
- };
-
- String localHost;
- try
- {
- localHost = InetAddress.getLocalHost().getHostName();
- }
- catch(UnknownHostException ex)
- {
- localHost="127.0.0.1";
- }
- final String hostname = localHost;
- final JMXServiceURL externalUrl = new JMXServiceURL(
- "service:jmx:rmi://"+hostname+":"+(_jmxPortConnectorServer)+"/jndi/rmi://"+hostname+":"+_jmxPortRegistryServer+"/jmxrmi");
-
- final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, _jmxPortConnectorServer);
- _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
- {
- @Override
- public synchronized void start() throws IOException
- {
- try
- {
- //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent
- _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
- }
- catch (AlreadyBoundException abe)
- {
- //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means.
-
- //IOExceptions are the only checked type throwable by the method, wrap and rethrow
- IOException ioe = new IOException(abe.getMessage());
- ioe.initCause(abe);
- throw ioe;
- }
-
- //now do the normal tasks
- super.start();
- }
-
- @Override
- public synchronized void stop() throws IOException
- {
- try
- {
- if (_rmiRegistry != null)
- {
- _rmiRegistry.unbind("jmxrmi");
- }
- }
- catch (NotBoundException nbe)
- {
- //ignore
- }
-
- //now do the normal tasks
- super.stop();
- }
-
- @Override
- public JMXServiceURL getAddress()
- {
- //must return our pre-crafted url that includes the full details, inc JNDI details
- return externalUrl;
- }
-
- };
-
-
- //Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
- MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
- _cs.setMBeanServerForwarder(mbsf);
-
-
- // Get the handler that is used by the above MBInvocationHandler Proxy.
- // which is the MBeanInvocationHandlerImpl and so also a NotificationListener.
- final NotificationListener invocationHandler = (NotificationListener) Proxy.getInvocationHandler(mbsf);
-
- // Install a notification listener on OPENED, CLOSED, and FAILED,
- // passing the map of connection-ids to usernames as hand-back data.
- final NotificationFilterSupport invocationHandlerFilter = new NotificationFilterSupport();
- invocationHandlerFilter.enableType(JMXConnectionNotification.OPENED);
- invocationHandlerFilter.enableType(JMXConnectionNotification.CLOSED);
- invocationHandlerFilter.enableType(JMXConnectionNotification.FAILED);
- _cs.addNotificationListener(invocationHandler, invocationHandlerFilter, connectionIdUsernameMap);
-
- // Install a second notification listener on CLOSED AND FAILED only to remove the entry from the
- // Map. Here we rely on the fact that JMX will call the listeners in the order in which they are
- // installed.
- final NotificationFilterSupport mapCleanupHandlerFilter = new NotificationFilterSupport();
- mapCleanupHandlerFilter.enableType(JMXConnectionNotification.CLOSED);
- mapCleanupHandlerFilter.enableType(JMXConnectionNotification.FAILED);
- _cs.addNotificationListener(mapCleanupListener, mapCleanupHandlerFilter, null);
-
- _cs.start();
-
- String connectorServer = (sslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
- CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, _jmxPortConnectorServer));
-
- CurrentActor.get().message(ManagementConsoleMessages.READY(false));
- }
-
- /*
- * Custom RMIServerSocketFactory class, used to prevent updates to the RMI registry.
- * Supplied to the registry at creation, this will prevent RMI-based operations on the
- * registry such as attempting to bind a new object, thereby securing it from tampering.
- * This is accomplished by always returning null when attempting to determine the address
- * of the caller, thus ensuring the registry will refuse the attempt. Calls to bind etc
- * made using the object reference will not be affected and continue to operate normally.
- */
-
- private static class CustomRMIServerSocketFactory implements RMIServerSocketFactory
- {
-
- public ServerSocket createServerSocket(int port) throws IOException
- {
- return new NoLocalAddressServerSocket(port);
- }
-
- private static class NoLocalAddressServerSocket extends ServerSocket
- {
- NoLocalAddressServerSocket(int port) throws IOException
- {
- super(port);
- }
-
- @Override
- public Socket accept() throws IOException
- {
- Socket s = new NoLocalAddressSocket();
- super.implAccept(s);
- return s;
- }
- }
-
- private static class NoLocalAddressSocket extends Socket
- {
- @Override
- public InetAddress getInetAddress()
- {
- return null;
- }
- }
- }
-
-
- public void registerObject(ManagedObject managedObject) throws JMException
- {
- _mbeanServer.registerMBean(managedObject, managedObject.getObjectName());
- }
-
- public void unregisterObject(ManagedObject managedObject) throws JMException
- {
- _mbeanServer.unregisterMBean(managedObject.getObjectName());
- }
-
- // checks if the system properties are set which enable the JVM's out-of-the-box JMXAgent.
- private boolean areOutOfTheBoxJMXOptionsSet()
- {
- if (System.getProperty("com.sun.management.jmxremote") != null)
- {
- return true;
- }
-
- if (System.getProperty("com.sun.management.jmxremote.port") != null)
- {
- return true;
- }
-
- return false;
- }
-
- //Stops the JMXConnectorServer and RMIRegistry, then unregisters any remaining MBeans from the MBeanServer
- public void close()
- {
- if (_cs != null)
- {
- // Stopping the JMX ConnectorServer
- try
- {
- CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("JMX RMIConnectorServer", _cs.getAddress().getPort()));
- _cs.stop();
- }
- catch (IOException e)
- {
- _log.error("Exception while closing the JMX ConnectorServer: " + e.getMessage());
- }
- }
-
- if (_rmiRegistry != null)
- {
- // Stopping the RMI registry
- CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("RMI Registry", _jmxPortRegistryServer));
- try
- {
- UnicastRemoteObject.unexportObject(_rmiRegistry, false);
- }
- catch (NoSuchObjectException e)
- {
- _log.error("Exception while closing the RMI Registry: " + e.getMessage());
- }
- }
-
- //ObjectName query to gather all Qpid related MBeans
- ObjectName mbeanNameQuery = null;
- try
- {
- mbeanNameQuery = new ObjectName(ManagedObject.DOMAIN + ":*");
- }
- catch (Exception e1)
- {
- _log.warn("Unable to generate MBean ObjectName query for close operation");
- }
-
- for (ObjectName name : _mbeanServer.queryNames(mbeanNameQuery, null))
- {
- try
- {
- _mbeanServer.unregisterMBean(name);
- }
- catch (JMException e)
- {
- _log.error("Exception unregistering MBean '"+ name +"': " + e.getMessage());
- }
- }
-
- CurrentActor.get().message(ManagementConsoleMessages.STOPPED());
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java
deleted file mode 100644
index 89b74f939d..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter;
-
-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";
-
- private MBeanIntrospector()
- {
- }
-
- /**
- * 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())
- {
- 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);
- 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 = _defaultConstructorDescription;
- Annotation anno = cons.getAnnotation(MBeanConstructor.class);
- if (anno != null && MBeanConstructor.class.isInstance(anno))
- {
- desc = MBeanConstructor.class.cast(anno).value();
- if(desc == null)
- {
- desc = _defaultConstructorDescription;
- }
- }
-
- return new MBeanConstructorInfo(cons.getName(), 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;
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
deleted file mode 100644
index 651372db16..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.log4j.Logger;
-
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.access.Operation;
-
-import javax.management.Attribute;
-import javax.management.JMException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXPrincipal;
-import javax.management.remote.MBeanServerForwarder;
-import javax.security.auth.Subject;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates
- * JMX access decisions to the SecurityPlugin.
- */
-public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener
-{
- private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
-
- private final IApplicationRegistry _appRegistry = ApplicationRegistry.getInstance();
- private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
- private MBeanServer _mbs;
- private final ManagementActor _logActor = new ManagementActor(_appRegistry.getRootMessageLogger());
- private final boolean _managementRightsInferAllAccess =
- _appRegistry.getConfiguration().getManagementRightsInferAllAccess();
-
- public static MBeanServerForwarder newProxyInstance()
- {
- final InvocationHandler handler = new MBeanInvocationHandlerImpl();
- final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
-
- Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler);
- return MBeanServerForwarder.class.cast(proxy);
- }
-
- private boolean invokeDirectly(String methodName, Object[] args, Subject subject)
- {
- // Allow operations performed locally on behalf of the connector server itself
- if (subject == null)
- {
- return true;
- }
-
- if (args == null || DELEGATE.equals(args[0]))
- {
- return true;
- }
-
- // Allow querying available object names and mbeans
- if (methodName.equals("queryNames") || methodName.equals("queryMBeans"))
- {
- return true;
- }
-
- if (args[0] instanceof ObjectName)
- {
- ObjectName mbean = (ObjectName) args[0];
-
- if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
- {
- return true;
- }
- }
-
- return false;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- String methodName = method.getName();
-
- if (methodName.equals("getMBeanServer"))
- {
- return _mbs;
- }
-
- if (methodName.equals("setMBeanServer"))
- {
- if (args[0] == null)
- {
- throw new IllegalArgumentException("Null MBeanServer");
- }
- if (_mbs != null)
- {
- throw new IllegalArgumentException("MBeanServer object already initialized");
- }
- _mbs = (MBeanServer) args[0];
- return null;
- }
-
- // Restrict access to "createMBean" and "unregisterMBean" to any user
- if (methodName.equals("createMBean") || methodName.equals("unregisterMBean"))
- {
- _logger.debug("User trying to create or unregister an MBean");
- throw new SecurityException("Access denied: " + methodName);
- }
-
- // Retrieve Subject from current AccessControlContext
- AccessControlContext acc = AccessController.getContext();
- Subject subject = Subject.getSubject(acc);
-
- try
- {
- if(invokeDirectly(methodName, args, subject))
- {
- return method.invoke(_mbs, args);
- }
-
- // Retrieve JMXPrincipal from Subject
- Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
- if (principals == null || principals.isEmpty())
- {
- throw new SecurityException("Access denied: no JMX principal");
- }
-
- // Save the subject
- SecurityManager.setThreadSubject(subject);
-
- // Get the component, type and impact, which may be null
- String type = getType(method, args);
- String vhost = getVirtualHost(method, args);
- int impact = getImpact(method, args);
-
- // Get the security manager for the virtual host (if set)
- SecurityManager security;
- if (vhost == null)
- {
- security = _appRegistry.getSecurityManager();
- }
- else
- {
- security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
- }
-
- methodName = getMethodName(method, args);
- if (isAccessMethod(methodName) || impact == MBeanOperationInfo.INFO)
- {
- // Check for read-only method invocation permission
- if (!security.authoriseMethod(Operation.ACCESS, type, methodName))
- {
- throw new SecurityException("Permission denied: Access " + methodName);
- }
- }
- else
- {
- // Check for setting properties permission
- if (!security.authoriseMethod(Operation.UPDATE, type, methodName))
- {
- throw new SecurityException("Permission denied: Update " + methodName);
- }
- }
-
- boolean oldAccessChecksDisabled = false;
- if(_managementRightsInferAllAccess)
- {
- oldAccessChecksDisabled = SecurityManager.setAccessChecksDisabled(true);
- }
-
- try
- {
- // Actually invoke the method
- return method.invoke(_mbs, args);
- }
- finally
- {
- if(_managementRightsInferAllAccess)
- {
- SecurityManager.setAccessChecksDisabled(oldAccessChecksDisabled);
- }
- }
- }
- catch (InvocationTargetException e)
- {
- throw e.getTargetException();
- }
- }
-
- private String getType(Method method, Object[] args)
- {
- if (args[0] instanceof ObjectName)
- {
- ObjectName object = (ObjectName) args[0];
- String type = object.getKeyProperty("type");
-
- return type;
- }
- return null;
- }
-
- private String getVirtualHost(Method method, Object[] args)
- {
- if (args[0] instanceof ObjectName)
- {
- ObjectName object = (ObjectName) args[0];
- String vhost = object.getKeyProperty("VirtualHost");
-
- if(vhost != null)
- {
- try
- {
- //if the name is quoted in the ObjectName, unquote it
- vhost = ObjectName.unquote(vhost);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the name is not quoted
- //and can be left unchanged
- }
- }
-
- return vhost;
- }
- return null;
- }
-
- private String getMethodName(Method method, Object[] args)
- {
- String methodName = method.getName();
-
- // if arguments are set, try and work out real method name
- if (args != null && args.length >= 1 && args[0] instanceof ObjectName)
- {
- if (methodName.equals("getAttribute"))
- {
- methodName = "get" + (String) args[1];
- }
- else if (methodName.equals("setAttribute"))
- {
- methodName = "set" + ((Attribute) args[1]).getName();
- }
- else if (methodName.equals("invoke"))
- {
- methodName = (String) args[1];
- }
- }
-
- return methodName;
- }
-
- private int getImpact(Method method, Object[] args)
- {
- //handle invocation of other methods on mbeans
- if ((args[0] instanceof ObjectName) && (method.getName().equals("invoke")))
- {
- //get invoked method name
- String mbeanMethod = (args.length > 1) ? (String) args[1] : null;
- if (mbeanMethod == null)
- {
- return -1;
- }
-
- try
- {
- //Get the impact attribute
- MBeanInfo mbeanInfo = _mbs.getMBeanInfo((ObjectName) args[0]);
- if (mbeanInfo != null)
- {
- MBeanOperationInfo[] opInfos = mbeanInfo.getOperations();
- for (MBeanOperationInfo opInfo : opInfos)
- {
- if (opInfo.getName().equals(mbeanMethod))
- {
- return opInfo.getImpact();
- }
- }
- }
- }
- catch (JMException ex)
- {
- _logger.error("Unable to determine mbean impact for method : " + mbeanMethod, ex);
- }
- }
-
- return -1;
- }
-
- private boolean isAccessMethod(String methodName)
- {
- //handle standard get/query/is methods from MBeanServer
- return (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("is"));
- }
-
- /**
- * Receives notifications from the MBeanServer.
- */
- public void handleNotification(final Notification notification, final Object handback)
- {
- assert notification instanceof JMXConnectionNotification;
-
- final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
- final String type = notification.getType();
-
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Notification connectionId : " + connectionId + " type : " + type
- + " Notification handback : " + handback);
- }
-
- // Normally JMXManagedObjectRegistry provides a Map as handback data containing a map
- // between connection id and username.
- String user = null;
- if (handback instanceof Map)
- {
- final Map<String, String> connectionIdUsernameMap = (Map<String, String>) handback;
- user = connectionIdUsernameMap.get(connectionId);
- }
-
- // If user is still null, fallback to an unordered list of Principals from the connection id.
- if (user == null)
- {
- final String[] splitConnectionId = connectionId.split(" ");
- user = splitConnectionId[1];
- }
-
- if (JMXConnectionNotification.OPENED.equals(type))
- {
- _logActor.message(ManagementConsoleMessages.OPEN(user));
- }
- else if (JMXConnectionNotification.CLOSED.equals(type) ||
- JMXConnectionNotification.FAILED.equals(type))
- {
- _logActor.message(ManagementConsoleMessages.CLOSE(user));
- }
- }
-}
-
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java
deleted file mode 100644
index 483b325455..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.qpid.AMQException;
-
-import javax.management.JMException;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-/**
- * This should be implemented by all Managable objects.
- */
-public interface ManagedObject
-{
- static final String DOMAIN = "org.apache.qpid";
-
- /**
- * @return the name that uniquely identifies this object instance. It must be
- * unique only among objects of this type at this level in the hierarchy so
- * the uniqueness should not be too difficult to ensure.
- */
- String getObjectInstanceName();
-
- String getType();
-
- Class<?> getManagementInterface();
-
- ManagedObject getParentObject();
-
- void register() throws AMQException, JMException;
-
- void unregister() throws AMQException;
-
- /**
- * Returns the ObjectName required for the mbeanserver registration.
- * @return ObjectName
- * @throws MalformedObjectNameException
- */
- ObjectName getObjectName() throws MalformedObjectNameException;
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
deleted file mode 100644
index b3323c569c..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.common.Closeable;
-
-import javax.management.JMException;
-import java.io.IOException;
-
-/**
- * Handles the registration (and unregistration and so on) of managed objects.
- *
- * Managed objects are responsible for exposting attributes, operations and notifications. They will expose
- * these outside the JVM therefore it is important not to use implementation objects directly as managed objects.
- * Instead, creating inner classes and exposing those is an effective way of exposing internal state in a
- * controlled way.
- *
- * Although we do not explictly use them while targetting Java 5, the enhanced MXBean approach in Java 6 will
- * be the obvious choice for managed objects.
- *
- */
-public interface ManagedObjectRegistry extends Closeable
-{
- void start() throws IOException, ConfigurationException;
-
- void registerObject(ManagedObject managedObject) throws JMException;
-
- void unregisterObject(ManagedObject managedObject) throws JMException;
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
index faac14f8a7..63bd1e45a0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.message;
+import java.util.Collection;
import java.util.Set;
public interface AMQMessageHeader
@@ -28,6 +29,10 @@ public interface AMQMessageHeader
long getExpiration();
+ String getUserId();
+
+ String getAppId();
+
String getMessageId();
String getMimeType();
@@ -52,4 +57,5 @@ public interface AMQMessageHeader
boolean containsHeader(String name);
+ Collection<String> getHeaderNames();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
index e87b67d242..01c1021070 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.message;
+import java.util.Collection;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
@@ -50,6 +51,16 @@ public class ContentHeaderBodyAdapter implements AMQMessageHeader
return getProperties().getExpiration();
}
+ public String getUserId()
+ {
+ return getProperties().getUserIdAsString();
+ }
+
+ public String getAppId()
+ {
+ return getProperties().getAppIdAsString();
+ }
+
public String getMessageId()
{
return getProperties().getMessageIdAsString();
@@ -117,6 +128,13 @@ public class ContentHeaderBodyAdapter implements AMQMessageHeader
return true;
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ FieldTable ft = getProperties().getHeaders();
+ return ft.keys();
+ }
+
public boolean containsHeader(String name)
{
FieldTable ft = getProperties().getHeaders();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index 583f0c09a7..e890bf5ef8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.message;
+import java.util.Collection;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -242,6 +243,16 @@ public class MessageMetaData implements StorableMessageMetaData
return (BasicContentHeaderProperties) getContentHeaderBody().getProperties();
}
+ public String getUserId()
+ {
+ return getProperties().getUserIdAsString();
+ }
+
+ public String getAppId()
+ {
+ return getProperties().getAppIdAsString();
+ }
+
public String getCorrelationId()
{
return getProperties().getCorrelationIdAsString();
@@ -318,6 +329,12 @@ public class MessageMetaData implements StorableMessageMetaData
return true;
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ return getProperties().getHeaders().keys();
+ }
+
public boolean containsHeader(String name)
{
FieldTable ft = getProperties().getHeaders();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
index 7d030fe711..2cc1a92853 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
@@ -21,11 +21,7 @@
package org.apache.qpid.server.message;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import org.apache.qpid.amqp_1_0.codec.ValueHandler;
import org.apache.qpid.amqp_1_0.messaging.SectionDecoder;
import org.apache.qpid.amqp_1_0.type.AmqpErrorException;
@@ -486,6 +482,18 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
return null; //TODO
}
+ public String getAppId()
+ {
+ //TODO
+ return null;
+ }
+
+ public String getUserId()
+ {
+ // TODO
+ return null;
+ }
+
public Object getHeader(final String name)
{
return _appProperties == null ? null : _appProperties.get(name);
@@ -508,6 +516,16 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
return true;
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ if(_appProperties == null)
+ {
+ return Collections.emptySet();
+ }
+ return Collections.unmodifiableCollection(_appProperties.keySet());
+ }
+
public boolean containsHeader(final String name)
{
return _appProperties != null && _appProperties.containsKey(name);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
index 126e7c28cb..91384f7c22 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
@@ -20,14 +20,11 @@
*/
package org.apache.qpid.server.message;
+import java.util.*;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.MessageDeliveryPriority;
import org.apache.qpid.transport.MessageProperties;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
class MessageTransferHeader implements AMQMessageHeader
{
@@ -60,10 +57,22 @@ class MessageTransferHeader implements AMQMessageHeader
return _deliveryProps == null ? 0L : _deliveryProps.getExpiration();
}
+ public String getUserId()
+ {
+ byte[] userIdBytes = _messageProps == null ? null : _messageProps.getUserId();
+ return userIdBytes == null ? null : new String(userIdBytes);
+ }
+
+ public String getAppId()
+ {
+ byte[] appIdBytes = _messageProps == null ? null : _messageProps.getAppId();
+ return appIdBytes == null ? null : new String(appIdBytes);
+ }
+
public String getMessageId()
{
UUID id = _messageProps == null ? null : _messageProps.getMessageId();
-
+
return id == null ? null : String.valueOf(id);
}
@@ -93,7 +102,7 @@ class MessageTransferHeader implements AMQMessageHeader
public String getType()
{
Object type = getHeader(JMS_TYPE);
- return type instanceof String ? (String) type : null;
+ return type instanceof String ? (String) type : null;
}
public String getReplyTo()
@@ -145,6 +154,14 @@ class MessageTransferHeader implements AMQMessageHeader
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ Map<String, Object> appHeaders = _messageProps == null ? null : _messageProps.getApplicationHeaders();
+ return appHeaders != null ? Collections.unmodifiableCollection(appHeaders.keySet()) : Collections.EMPTY_SET ;
+
+ }
+
public boolean containsHeader(String name)
{
Map<String, Object> appHeaders = _messageProps == null ? null : _messageProps.getApplicationHeaders();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java
new file mode 100644
index 0000000000..4fccf47e0e
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java
@@ -0,0 +1,199 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+public abstract class Attribute<C extends ConfiguredObject, T>
+{
+ private final String _name;
+ public Attribute(String name)
+ {
+ _name = name;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ abstract public Class<T> getType();
+
+ public T getValue(C configuredObject)
+ {
+ Object o = configuredObject.getAttribute(_name);
+ if(getType().isInstance(o))
+ {
+ return (T) o;
+ }
+ return null;
+ }
+
+ public T setValue(T expected, T desired, C configuredObject)
+ {
+ return (T) configuredObject.setAttribute(_name, expected, desired);
+ }
+
+ abstract public T setValue(String stringValue, C configuredObject);
+
+ static class StringAttribute<C extends ConfiguredObject> extends Attribute<C, String>
+ {
+
+ public StringAttribute(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public Class<String> getType()
+ {
+ return String.class;
+ }
+
+ @Override
+ public String setValue(String stringValue, C configuredObject)
+ {
+ return setValue(getValue(configuredObject), stringValue, configuredObject);
+ }
+
+ }
+
+ static class IntegerAttribute<C extends ConfiguredObject> extends Attribute<C, Integer>
+ {
+
+ public IntegerAttribute(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public Class<Integer> getType()
+ {
+ return Integer.class;
+ }
+
+ @Override
+ public Integer setValue(String stringValue, C configuredObject)
+ {
+ try
+ {
+ Integer val = Integer.valueOf(stringValue);
+ return setValue(getValue(configuredObject), val, configuredObject);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+
+
+ static class LongAttribute<C extends ConfiguredObject> extends Attribute<C, Long>
+ {
+
+ public LongAttribute(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public Class<Long> getType()
+ {
+ return Long.class;
+ }
+
+ @Override
+ public Long setValue(String stringValue, C configuredObject)
+ {
+ try
+ {
+ Long val = Long.valueOf(stringValue);
+ return setValue(getValue(configuredObject), val, configuredObject);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+
+
+ static class DoubleAttribute<C extends ConfiguredObject> extends Attribute<C, Double>
+ {
+
+ public DoubleAttribute(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public Class<Double> getType()
+ {
+ return Double.class;
+ }
+
+ @Override
+ public Double setValue(String stringValue, C configuredObject)
+ {
+ try
+ {
+ Double val = Double.valueOf(stringValue);
+ return setValue(getValue(configuredObject), val, configuredObject);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+
+
+ static class FloatAttribute<C extends ConfiguredObject> extends Attribute<C, Float>
+ {
+
+ public FloatAttribute(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public Class<Float> getType()
+ {
+ return Float.class;
+ }
+
+ @Override
+ public Float setValue(String stringValue, C configuredObject)
+ {
+ try
+ {
+ Float val = Float.valueOf(stringValue);
+ return setValue(getValue(configuredObject), val, configuredObject);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+ }
+
+
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java
index 166a2a376d..7a5927a365 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java
@@ -7,9 +7,9 @@
* to you 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
@@ -18,17 +18,16 @@
* under the License.
*
*/
-package org.apache.qpid.server.management;
+package org.apache.qpid.server.model;
-/**
- * Any object that can return a related MBean should implement this interface.
- *
- * This enables other classes to get the managed object, which in turn is useful when
- * constructing relationships between managed objects without having to maintain
- * separate data structures containing MBeans.
- *
- */
-public interface Managable
+import java.util.Collection;
+
+public interface AuthenticationMethod extends ConfiguredObject
{
- ManagedObject getManagedObject();
+ // name is the SASL mech where this is a SASL authentication
+
+ // parents
+ VirtualHostAlias getVirtualHostAlias();
+ AuthenticationProvider getAuthenticationProvider();
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
new file mode 100644
index 0000000000..6000886956
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface AuthenticationProvider extends ConfiguredObject
+{
+
+ public static final String ID = "id";
+ public static final String DESCRIPTION = "description";
+ public static final String NAME = "name";
+ public static final String STATE = "state";
+ public static final String DURABLE = "durable";
+ public static final String LIFETIME_POLICY = "lifetimePolicy";
+ public static final String TIME_TO_LIVE = "timeToLive";
+ public static final String CREATED = "created";
+ public static final String UPDATED = "updated";
+ public static final String TYPE = "type";
+
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(ID,
+ NAME,
+ DESCRIPTION,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ TYPE));
+ //children
+ Collection<VirtualHostAlias> getVirtualHostPortBindings();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
new file mode 100644
index 0000000000..ca1de0f189
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+public interface Broker extends ConfiguredObject
+{
+
+ String BUILD_VERSION = "buildVersion";
+ String BYTES_RETAINED = "bytesRetained";
+ String OPERATING_SYSTEM = "operatingSystem";
+ String PLATFORM = "platform";
+ String PROCESS_PID = "processPid";
+ String PRODUCT_VERSION = "productVersion";
+ String STATISTICS_ENABLED = "statisticsEnabled";
+ String SUPPORTED_STORE_TYPES = "supportedStoreTypes";
+ String CREATED = "created";
+ String DURABLE = "durable";
+ String ID = "id";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String NAME = "name";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+ String UPDATED = "updated";
+
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(BUILD_VERSION,
+ BYTES_RETAINED,
+ OPERATING_SYSTEM,
+ PLATFORM,
+ PROCESS_PID,
+ PRODUCT_VERSION,
+ STATISTICS_ENABLED,
+ SUPPORTED_STORE_TYPES,
+ CREATED,
+ DURABLE,
+ ID,
+ LIFETIME_POLICY,
+ NAME,
+ STATE,
+ TIME_TO_LIVE,
+ UPDATED));
+
+ //children
+ Collection < VirtualHost > getVirtualHosts();
+
+ Collection<Port> getPorts();
+
+ Collection<AuthenticationProvider> getAuthenticationProviders();
+
+ VirtualHost createVirtualHost(String name, State initialState, boolean durable,
+ LifetimePolicy lifetime, long ttl, Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException;
+
+ void deleteVirtualHost(VirtualHost virtualHost)
+ throws AccessControlException, IllegalStateException;
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java
index 6477633a9b..78b98faffe 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java
@@ -30,7 +30,8 @@ public interface ConfigurationChangeListener
* @param newState the state after the change
*/
void stateChanged(ConfiguredObject object, State oldState, State newState);
-
+
+
void childAdded(ConfiguredObject object, ConfiguredObject child);
void childRemoved(ConfiguredObject object, ConfiguredObject child);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
index fb47a54d0a..414b2d083a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.model;
import java.security.AccessControlException;
import java.util.Collection;
+import java.util.Map;
import java.util.UUID;
public interface ConfiguredObject
@@ -81,7 +82,7 @@ public interface ConfiguredObject
* @param desiredState the state the caller wishes the object to attain
* @return the new current state
* @throws IllegalStateTransitionException the requested state tranisition is invalid
- * @throws AccessControlException the current context does not have sufficeint permissions to change the state
+ * @throws AccessControlException the current context does not have sufficient permissions to change the state
*/
State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
AccessControlException;
@@ -89,7 +90,7 @@ public interface ConfiguredObject
/**
* Get the actual state of the object.
*
- * This state is derived fromt the desired state of the object itself and
+ * This state is derived from the desired state of the object itself and
* the actual state of its parents. If an object "desires" to be ACTIVE, but one of its parents is STOPPED, then
* the actual state of the object will be STOPPED
*
@@ -126,7 +127,7 @@ public interface ConfiguredObject
/**
* Returns whether the the object configuration is durably stored
*
- * @return the durablity
+ * @return the durability
*/
boolean isDurable();
@@ -188,7 +189,7 @@ public interface ConfiguredObject
/**
* Get the names of attributes that are set on this object
*
- * Not that the returned collection is correct at the time the method is called, but will not reflect future
+ * Note that the returned collection is correct at the time the method is called, but will not reflect future
* additions or removals when they occur
*
* @return the collection of attribute names
@@ -226,4 +227,20 @@ public interface ConfiguredObject
* @return the Statistics holder for the ConfiguredObject (or null if none exists)
*/
Statistics getStatistics();
+
+ /**
+ * Return children of the ConfiguredObject of the given class
+ *
+ * @param clazz the class of the children to return
+ * @return the children
+ *
+ * @throws NullPointerException if the supplied class null
+ *
+ */
+ <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz);
+
+
+ <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
index e77350c3e4..6a7d6f8f7b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
@@ -7,9 +7,9 @@
* to you 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
@@ -18,41 +18,21 @@
* under the License.
*
*/
-package org.apache.qpid.server.management;
-
-import org.apache.log4j.Logger;
+package org.apache.qpid.server.model;
-import javax.management.JMException;
+import java.util.Collection;
-/**
- * This managed object registry does not actually register MBeans. This can be used in tests when management is
- * not required or when management has been disabled.
- *
- */
-public class NoopManagedObjectRegistry implements ManagedObjectRegistry
+public class ConfiguredObjectFinder
{
- private static final Logger _log = Logger.getLogger(NoopManagedObjectRegistry.class);
-
- public NoopManagedObjectRegistry()
- {
- _log.info("Management is disabled");
- }
-
- public void start()
- {
- //no-op
- }
-
- public void registerObject(ManagedObject managedObject) throws JMException
- {
- }
-
- public void unregisterObject(ManagedObject managedObject) throws JMException
- {
- }
-
- public void close()
+ public static <C extends ConfiguredObject> C findConfiguredObjectByName(Collection<C> configuredObjects, String name)
{
-
+ for (C configuredObject : configuredObjects)
+ {
+ if (name.equals(configuredObject.getName()))
+ {
+ return configuredObject;
+ }
+ }
+ return null;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java
new file mode 100644
index 0000000000..aaf6007afd
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java
@@ -0,0 +1,107 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface Connection extends ConfiguredObject
+{
+
+ // Statistics
+
+ String BYTES_IN = "bytesIn";
+ String BYTES_OUT = "bytesOut";
+ String LAST_IO_TIME = "lastIoTime";
+ String LOCAL_TRANSACTION_BEGINS = "localTransactionBegins";
+ String LOCAL_TRANSACTION_ROLLBACKS = "localTransactionRollbacks";
+ String MESSAGES_IN = "messagesIn";
+ String MESSAGES_OUT = "messagesOut";
+ String SESSION_COUNT = "sessionCount";
+ String STATE_CHANGED = "stateChanged";
+ String XA_TRANSACTION_BRANCH_ENDS = "xaTransactionBranchEnds";
+ String XA_TRANSACTION_BRANCH_STARTS = "xaTransactionBranchStarts";
+ String XA_TRANSACTION_BRANCH_SUSPENDS = "xaTransactionBranchSuspends";
+
+ public static final Collection<String> AVAILABLE_STATISTICS =
+ Collections.unmodifiableCollection(
+ Arrays.asList(BYTES_IN,
+ BYTES_OUT,
+ LAST_IO_TIME,
+ LOCAL_TRANSACTION_BEGINS,
+ LOCAL_TRANSACTION_ROLLBACKS,
+ MESSAGES_IN,
+ MESSAGES_OUT,
+ SESSION_COUNT,
+ STATE_CHANGED,
+ XA_TRANSACTION_BRANCH_ENDS,
+ XA_TRANSACTION_BRANCH_STARTS,
+ XA_TRANSACTION_BRANCH_SUSPENDS));
+
+ // Attributes
+
+ public static final String ID = "id";
+ public static final String NAME = "name";
+ public static final String STATE = "state";
+ public static final String DURABLE = "durable";
+ public static final String LIFETIME_POLICY = "lifetimePolicy";
+ public static final String TIME_TO_LIVE = "timeToLive";
+ public static final String CREATED = "created";
+ public static final String UPDATED = "updated";
+
+ public static final String CLIENT_ID = "clientId";
+ public static final String CLIENT_VERSION = "clientVersion";
+ public static final String INCOMING = "incoming";
+ public static final String LOCAL_ADDRESS = "localAddress";
+ public static final String PRINCIPAL = "principal";
+ public static final String PROPERTIES = "properties";
+ public static final String REMOTE_ADDRESS = "remoteAddress";
+ public static final String REMOTE_PROCESS_NAME = "remoteProcessName";
+ public static final String REMOTE_PROCESS_PID = "remoteProcessPid";
+ public static final String SESSION_COUNT_LIMIT = "sessionCountLimit";
+
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableCollection(
+ Arrays.asList( ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ CLIENT_ID,
+ CLIENT_VERSION,
+ INCOMING,
+ LOCAL_ADDRESS,
+ PRINCIPAL,
+ PROPERTIES,
+ REMOTE_ADDRESS,
+ REMOTE_PROCESS_NAME,
+ REMOTE_PROCESS_PID,
+ SESSION_COUNT_LIMIT));
+
+ //children
+ Collection<Session> getSessions();
+
+ void delete();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Event.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Event.java
new file mode 100644
index 0000000000..91b684f06e
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Event.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+abstract public class Event<T extends EventType>
+{
+ abstract public T getEventType();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java
new file mode 100644
index 0000000000..edd5ce4250
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A type of event generated by a ConfiguredObject.
+ */
+public abstract class EventType<T extends EventType<T>>
+{
+ private static final Map<Class<? extends EventType>, Integer> EVENT_TYPES =
+ new HashMap<Class<? extends EventType>, Integer>();
+
+ private final int _classId;
+
+ protected EventType()
+ {
+ synchronized (EVENT_TYPES)
+ {
+ if(EVENT_TYPES.containsKey(getClass()))
+ {
+ throw new IllegalArgumentException("Cannot define more one instance of the same EventType " +
+ getClass().getName());
+ }
+ else
+ {
+ _classId = EVENT_TYPES.size();
+ EVENT_TYPES.put(getClass(), _classId);
+ }
+ }
+ }
+
+ public final int getId()
+ {
+ return _classId;
+ }
+
+ abstract public Event<T> newEvent();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java
index e872273d05..e63c71e955 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java
@@ -77,7 +77,7 @@ public interface Exchange extends ConfiguredObject
//children
Collection<Binding> getBindings();
Collection<Publisher> getPublishers();
-
+
//operations
Binding createBinding(String bindingKey,
Queue queue,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
new file mode 100644
index 0000000000..fd429321c8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
@@ -0,0 +1,97 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Model
+{
+ private static final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>
+ PARENTS = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>();
+
+
+ private static final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>
+ CHILDREN = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>();
+
+ static void addRelationship(Class<? extends ConfiguredObject> parent, Class<? extends ConfiguredObject> child)
+ {
+ Collection<Class<? extends ConfiguredObject>> parents = PARENTS.get(child);
+ if(parents == null)
+ {
+ parents = new ArrayList<Class<? extends ConfiguredObject>>();
+ PARENTS.put(child, parents);
+ }
+ parents.add(parent);
+
+ Collection<Class<? extends ConfiguredObject>> children = CHILDREN.get(parent);
+ if(children == null)
+ {
+ children = new ArrayList<Class<? extends ConfiguredObject>>();
+ CHILDREN.put(parent, children);
+ }
+ children.add(child);
+ }
+
+ static
+ {
+ addRelationship(Broker.class, VirtualHost.class);
+ addRelationship(Broker.class, Port.class);
+ addRelationship(Broker.class, AuthenticationProvider.class);
+
+ addRelationship(VirtualHost.class, Exchange.class);
+ addRelationship(VirtualHost.class, Queue.class);
+ addRelationship(VirtualHost.class, Connection.class);
+ addRelationship(VirtualHost.class, VirtualHostAlias.class);
+
+ addRelationship(AuthenticationProvider.class, User.class);
+
+ addRelationship(Connection.class, Session.class);
+
+ addRelationship(Exchange.class, Binding.class);
+ addRelationship(Exchange.class, Publisher.class);
+
+ addRelationship(Queue.class, Binding.class);
+ addRelationship(Queue.class, Consumer.class);
+
+ addRelationship(Session.class, Consumer.class);
+ addRelationship(Session.class, Publisher.class);
+
+ }
+
+ public static Collection<Class<? extends ConfiguredObject>> getParentTypes(Class<? extends ConfiguredObject> child)
+ {
+ Collection<Class<? extends ConfiguredObject>> parentTypes = PARENTS.get(child);
+ return parentTypes == null ? Collections.EMPTY_LIST
+ : Collections.unmodifiableCollection(parentTypes);
+ }
+
+ public static Collection<Class<? extends ConfiguredObject>> getChildTypes(Class<? extends ConfiguredObject> parent)
+ {
+ Collection<Class<? extends ConfiguredObject>> childTypes = CHILDREN.get(parent);
+ return childTypes == null ? Collections.EMPTY_LIST
+ : Collections.unmodifiableCollection(childTypes);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java
new file mode 100644
index 0000000000..1027e5ce8c
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.security.auth.login.AccountNotFoundException;
+
+public interface PasswordCredentialManagingAuthenticationProvider extends AuthenticationProvider
+{
+ boolean createUser(String username, String password, Map<String, String> attributes);
+
+ void deleteUser(String user) throws AccountNotFoundException;
+
+ void setPassword(String username, String password) throws AccountNotFoundException;
+
+ Map<String, Map<String,String>> getUsers();
+
+ /**
+ * Refreshes the cache of user and password data from the underlying storage.
+ *
+ * If there is a failure whilst reloading the data, the implementation must
+ * throw an {@link IOException} and revert to using the previous cached username
+ * and password data. In this way, the broker will remain usable.
+ */
+ void reload() throws IOException;
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java
new file mode 100644
index 0000000000..50c0ebcd14
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface Port extends ConfiguredObject
+{
+ String CREATED = "created";
+ String DURABLE = "durable";
+ String ID = "id";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String NAME = "name";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+ String UPDATED = "updated";
+ String BINDING_ADDRESS = "bindingAddress";
+ String PORT = "port";
+ String PROTOCOLS = "protocols";
+ String TRANSPORTS = "transports";
+
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ BINDING_ADDRESS,
+ PORT,
+ PROTOCOLS,
+ TRANSPORTS
+ ));
+
+
+ String getBindingAddress();
+
+ int getPort();
+
+ Collection<Transport> getTransports();
+
+ void addTransport(Transport transport) throws IllegalStateException,
+ AccessControlException,
+ IllegalArgumentException;
+
+ Transport removeTransport(Transport transport) throws IllegalStateException,
+ AccessControlException,
+ IllegalArgumentException;
+
+
+ Collection<Protocol> getProtocols();
+
+ void addProtocol(Protocol protocol) throws IllegalStateException,
+ AccessControlException,
+ IllegalArgumentException;
+
+ Protocol removeProtocol(Protocol protocol) throws IllegalStateException,
+ AccessControlException,
+ IllegalArgumentException;
+
+
+ //children
+ Collection<VirtualHostAlias> getVirtualHostBindings();
+ Collection<Connection> getConnections();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java
new file mode 100644
index 0000000000..fecbcec194
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+public enum Protocol
+{
+ AMQP_0_8,
+ AMQP_0_9,
+ AMQP_0_9_1,
+ AMQP_0_10,
+ AMQP_1_0,
+ JMX,
+ HTTP
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java
index 7c4f0de22b..5dda4d66cd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java
@@ -25,7 +25,6 @@ import java.util.Collection;
import java.util.Collections;
import org.apache.qpid.server.queue.QueueEntryVisitor;
-
public interface Queue extends ConfiguredObject
{
public static final String BINDING_COUNT = "bindingCount";
@@ -71,6 +70,7 @@ public interface Queue extends ConfiguredObject
public static final String ID = "id";
+ public static final String DESCRIPTION = "description";
public static final String NAME = "name";
public static final String STATE = "state";
public static final String DURABLE = "durable";
@@ -78,6 +78,7 @@ public interface Queue extends ConfiguredObject
public static final String TIME_TO_LIVE = "timeToLive";
public static final String CREATED = "created";
public static final String UPDATED = "updated";
+ public static final String ARGUMENTS = "arguments";
public static final String ALERT_REPEAT_GAP = "alertRepeatGap";
public static final String ALERT_THRESHOLD_MESSAGE_AGE = "alertThresholdMessageAge";
@@ -106,6 +107,7 @@ public interface Queue extends ConfiguredObject
Collections.unmodifiableList(
Arrays.asList(ID,
NAME,
+ DESCRIPTION,
STATE,
DURABLE,
LIFETIME_POLICY,
@@ -143,4 +145,6 @@ public interface Queue extends ConfiguredObject
void visit(QueueEntryVisitor visitor);
void delete();
+
+ void setNotificationListener(QueueNotificationListener listener);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/QueueNotificationListener.java
index 959ca03c80..ab601f685c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/QueueNotificationListener.java
@@ -18,10 +18,11 @@
* under the License.
*
*/
-package org.apache.qpid.server.queue;
+package org.apache.qpid.server.model;
+import org.apache.qpid.server.queue.NotificationCheck;
public interface QueueNotificationListener
{
- void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg);
+ void notifyClients(NotificationCheck notification, Queue queue, String notificationMsg);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Session.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Session.java
new file mode 100644
index 0000000000..e813d0c129
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Session.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface Session extends ConfiguredObject
+{
+ // Statistics
+
+ public static final String BYTES_IN = "bytesIn";
+ public static final String BYTES_OUT = "bytesOut";
+ public static final String CONSUMER_COUNT = "consumerCount";
+ public static final String LOCAL_TRANSACTION_BEGINS = "localTransactionBegins";
+ public static final String LOCAL_TRANSACTION_OPEN = "localTransactionOpen";
+ public static final String LOCAL_TRANSACTION_ROLLBACKS = "localTransactionRollbacks";
+ public static final String STATE_CHANGED = "stateChanged";
+ public static final String UNACKNOWLEDGED_BYTES = "unacknowledgedBytes";
+ public static final String UNACKNOWLEDGED_MESSAGES = "unacknowledgedMessages";
+ public static final String XA_TRANSACTION_BRANCH_ENDS = "xaTransactionBranchEnds";
+ public static final String XA_TRANSACTION_BRANCH_STARTS = "xaTransactionBranchStarts";
+ public static final String XA_TRANSACTION_BRANCH_SUSPENDS = "xaTransactionBranchSuspends";
+
+ public static final Collection<String> AVAILABLE_STATISTICS =
+ Collections.unmodifiableCollection(Arrays.asList(BYTES_IN, BYTES_OUT, CONSUMER_COUNT,
+ LOCAL_TRANSACTION_BEGINS,
+ LOCAL_TRANSACTION_OPEN,
+ LOCAL_TRANSACTION_ROLLBACKS, STATE_CHANGED,
+ UNACKNOWLEDGED_BYTES, UNACKNOWLEDGED_MESSAGES,
+ XA_TRANSACTION_BRANCH_ENDS, XA_TRANSACTION_BRANCH_STARTS,
+ XA_TRANSACTION_BRANCH_SUSPENDS));
+
+
+ public static final String ID = "id";
+ public static final String NAME = "name";
+ public static final String STATE = "state";
+ public static final String DURABLE = "durable";
+ public static final String LIFETIME_POLICY = "lifetimePolicy";
+ public static final String TIME_TO_LIVE = "timeToLive";
+ public static final String CREATED = "created";
+ public static final String UPDATED = "updated";
+
+ public static final String CHANNEL_ID = "channelId";
+ // PRODUCER_FLOW_BLOCKED is exposed as an interim step. We will expose attribute(s) that exposing
+ // available credit of both producer and consumer sides.
+ public static final String PRODUCER_FLOW_BLOCKED = "producerFlowBlocked";
+
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableCollection(Arrays.asList(ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ CHANNEL_ID,
+ PRODUCER_FLOW_BLOCKED));
+
+ Collection<Consumer> getSubscriptions();
+ Collection<Publisher> getPublishers();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java
index 2cb81eae82..92d6f47741 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java
@@ -1,8 +1,4 @@
-package org.apache.qpid.server.model;
-
-import java.util.Collection;
-
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
@@ -18,6 +14,11 @@ import java.util.Collection;
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+package org.apache.qpid.server.model;
+
+import java.util.Collection;
+
public interface Statistics
{
Collection<String> getStatisticNames();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java
new file mode 100644
index 0000000000..03cd46be01
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+public enum Transport
+{
+ TCP,
+ SSL
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
index d8493c6df4..920088d61c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
@@ -40,11 +40,11 @@ public class UUIDGenerator
return UUID.nameUUIDFromBytes(sb.toString().getBytes());
}
- public static UUID generateExchangeUUID(String echangeName, String virtualHostName)
+ public static UUID generateExchangeUUID(String exchangeName, String virtualHostName)
{
- if(ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString().equals(echangeName) || echangeName.startsWith("amq.") || echangeName.startsWith("qpid."))
+ if(ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString().equals(exchangeName) || exchangeName.startsWith("amq.") || exchangeName.startsWith("qpid."))
{
- return generateUUID(echangeName, virtualHostName);
+ return generateUUID(exchangeName, virtualHostName);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java
new file mode 100644
index 0000000000..d97bf46d31
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/User.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+public interface User extends ConfiguredObject
+{
+ String CREATED = "created";
+ String DURABLE = "durable";
+ String ID = "id";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String NAME = "name";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+ String UPDATED = "updated";
+ String PASSWORD = "password";
+
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ PASSWORD
+ ));
+
+ public String getPassword();
+
+ public void setPassword(String password);
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
new file mode 100644
index 0000000000..53faefc954
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
@@ -0,0 +1,154 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import org.apache.qpid.server.queue.QueueEntry;
+import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+public interface VirtualHost extends ConfiguredObject
+{
+ // Statistics
+
+ public static final String BYTES_IN = "bytesIn";
+ public static final String BYTES_OUT = "bytesOut";
+ public static final String BYTES_RETAINED = "bytesRetained";
+ public static final String LOCAL_TRANSACTION_BEGINS = "localTransactionBegins";
+ public static final String LOCAL_TRANSACTION_ROLLBACKS = "localTransactionRollbacks";
+ public static final String MESSAGES_IN = "messagesIn";
+ public static final String MESSAGES_OUT = "messagesOut";
+ public static final String MESSAGES_RETAINED = "messagesRetained";
+ public static final String STATE_CHANGED = "stateChanged";
+ public static final String XA_TRANSACTION_BRANCH_ENDS = "xaTransactionBranchEnds";
+ public static final String XA_TRANSACTION_BRANCH_STARTS = "xaTransactionBranchStarts";
+ public static final String XA_TRANSACTION_BRANCH_SUSPENDS = "xaTransactionBranchSuspends";
+ public static final String QUEUE_COUNT = "queueCount";
+ public static final String EXCHANGE_COUNT = "exchangeCount";
+ public static final String CONNECTION_COUNT = "connectionCount";
+
+ public static final Collection<String> AVAILABLE_STATISTICS =
+ Collections.unmodifiableList(
+ Arrays.asList(BYTES_IN, BYTES_OUT, BYTES_RETAINED, LOCAL_TRANSACTION_BEGINS,
+ LOCAL_TRANSACTION_ROLLBACKS, MESSAGES_IN, MESSAGES_OUT, MESSAGES_RETAINED, STATE_CHANGED,
+ XA_TRANSACTION_BRANCH_ENDS, XA_TRANSACTION_BRANCH_STARTS, XA_TRANSACTION_BRANCH_SUSPENDS,
+ QUEUE_COUNT, EXCHANGE_COUNT, CONNECTION_COUNT));
+
+ String ALERT_REPEAT_GAP = "alertRepeatGap";
+ String ALERT_THRESHOLD_MESSAGE_AGE = "alertThresholdMessageAge";
+ String ALERT_THRESHOLD_MESSAGE_SIZE = "alertThresholdMessageSize";
+ String ALERT_THRESHOLD_QUEUE_DEPTH_BYTES = "alertThresholdQueueDepthBytes";
+ String ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES = "alertThresholdQueueDepthMessages";
+ String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled";
+ String FEDERATION_TAG = "federationTag";
+ String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod";
+ String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts";
+ String QUEUE_FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes";
+ String QUEUE_FLOW_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes";
+ String STORE_CONFIGURATION = "storeConfiguration";
+ String STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE = "storeTransactionIdleTimeoutClose";
+ String STORE_TRANSACTION_IDLE_TIMEOUT_WARN = "storeTransactionIdleTimeoutWarn";
+ String STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "storeTransactionOpenTimeoutClose";
+ String STORE_TRANSACTION_OPEN_TIMEOUT_WARN = "storeTransactionOpenTimeoutWarn";
+ String STORE_TYPE = "storeType";
+ String SUPPORTED_EXCHANGE_TYPES = "supportedExchangeTypes";
+ String SUPPORTED_QUEUE_TYPES = "supportedQueueTypes";
+ String CREATED = "created";
+ String DURABLE = "durable";
+ String ID = "id";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String NAME = "name";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+ String UPDATED = "updated";
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ SUPPORTED_EXCHANGE_TYPES,
+ SUPPORTED_QUEUE_TYPES,
+ DEAD_LETTER_QUEUE_ENABLED,
+ FEDERATION_TAG,
+ HOUSEKEEPING_CHECK_PERIOD,
+ MAXIMUM_DELIVERY_ATTEMPTS,
+ QUEUE_FLOW_CONTROL_SIZE_BYTES,
+ QUEUE_FLOW_RESUME_SIZE_BYTES,
+ STORE_TYPE,
+ STORE_CONFIGURATION,
+ STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE,
+ STORE_TRANSACTION_IDLE_TIMEOUT_WARN,
+ STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE,
+ STORE_TRANSACTION_OPEN_TIMEOUT_WARN,
+ ALERT_REPEAT_GAP,
+ ALERT_THRESHOLD_MESSAGE_AGE,
+ ALERT_THRESHOLD_MESSAGE_SIZE,
+ ALERT_THRESHOLD_QUEUE_DEPTH_BYTES,
+ ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES));
+
+
+
+ String getReplicationGroupName();
+
+ //children
+ Collection<VirtualHostAlias> getAliases();
+ Collection<Connection> getConnections();
+ Collection<Queue> getQueues();
+ Collection<Exchange> getExchanges();
+
+ Exchange createExchange(String name, State initialState, boolean durable,
+ LifetimePolicy lifetime, long ttl, String type, Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException;
+
+ Queue createQueue(String name, State initialState, boolean durable,
+ boolean exclusive, LifetimePolicy lifetime, long ttl, Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException;
+
+ void deleteQueue(Queue queue) throws AccessControlException, IllegalStateException;
+
+ Collection<String> getExchangeTypes();
+
+ public static interface Transaction
+ {
+ void dequeue(QueueEntry entry);
+
+ void copy(QueueEntry entry, Queue queue);
+
+ void move(QueueEntry entry, Queue queue);
+
+ }
+
+ public static interface TransactionalOperation
+ {
+ void withinTransaction(Transaction txn);
+ }
+
+ void executeTransaction(TransactionalOperation op);
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java
new file mode 100644
index 0000000000..31403d78e5
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+
+public interface VirtualHostAlias extends ConfiguredObject
+{
+ // parents
+ Port getPort();
+ VirtualHost getVirtualHost();
+
+ // children
+ Collection<AuthenticationMethod> getAuthenticationMethods();
+
+
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
new file mode 100644
index 0000000000..78880c232d
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.State;
+
+abstract class AbstractAdapter implements ConfiguredObject
+{
+ private final Map<String,Object> _attributes = new HashMap<String, Object>();
+ private final Map<Class<? extends ConfiguredObject>, ConfiguredObject> _parents =
+ new HashMap<Class<? extends ConfiguredObject>, ConfiguredObject>();
+ private final Collection<ConfigurationChangeListener> _changeListeners =
+ new ArrayList<ConfigurationChangeListener>();
+
+ private final UUID _id;
+
+ protected AbstractAdapter(String... names)
+ {
+ StringBuilder sb = new StringBuilder();
+ for(String name : names)
+ {
+ sb.append('/').append(name);
+ }
+ _id = UUID.nameUUIDFromBytes(sb.toString().getBytes());
+ }
+
+ protected AbstractAdapter()
+ {
+ _id = UUID.randomUUID();
+ }
+
+ static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal)
+ {
+ final Object value = attributes.get(name);
+ return value == null ? defaultVal : String.valueOf(value);
+ }
+
+ static Map getMapAttribute(String name, Map<String,Object> attributes, Map defaultVal)
+ {
+ final Object value = attributes.get(name);
+ if(value == null)
+ {
+ return defaultVal;
+ }
+ else if(value instanceof Map)
+ {
+ return (Map) value;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map");
+ }
+ }
+
+
+ static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal)
+ {
+ Object obj = attributes.get(name);
+ if(obj == null)
+ {
+ return defaultVal;
+ }
+ else if(clazz.isInstance(obj))
+ {
+ return (E) obj;
+ }
+ else if(obj instanceof String)
+ {
+ return (E) Enum.valueOf(clazz, (String)obj);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + clazz.getSimpleName());
+ }
+ }
+
+ static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue)
+ {
+ Object obj = attributes.get(name);
+ if(obj == null)
+ {
+ return defaultValue;
+ }
+ else if(obj instanceof Boolean)
+ {
+ return (Boolean) obj;
+ }
+ else if(obj instanceof String)
+ {
+ return Boolean.parseBoolean((String) obj);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Boolean");
+ }
+ }
+
+ static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue)
+ {
+ Object obj = attributes.get(name);
+ if(obj == null)
+ {
+ return defaultValue;
+ }
+ else if(obj instanceof Number)
+ {
+ return ((Number) obj).intValue();
+ }
+ else if(obj instanceof String)
+ {
+ return Integer.valueOf((String) obj);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Integer");
+ }
+ }
+
+ static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue)
+ {
+ Object obj = attributes.get(name);
+ if(obj == null)
+ {
+ return defaultValue;
+ }
+ else if(obj instanceof Number)
+ {
+ return ((Number) obj).longValue();
+ }
+ else if(obj instanceof String)
+ {
+ return Long.valueOf((String) obj);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long");
+ }
+ }
+
+ public final UUID getId()
+ {
+ return _id;
+ }
+
+ public State getDesiredState()
+ {
+ return null; //TODO
+ }
+
+ public State setDesiredState(final State currentState, final State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public void addChangeListener(final ConfigurationChangeListener listener)
+ {
+ if(listener == null)
+ {
+ throw new NullPointerException("Cannot add a null listener");
+ }
+ synchronized (this)
+ {
+ if(!_changeListeners.contains(listener))
+ {
+ _changeListeners.add(listener);
+ }
+ }
+ }
+
+ public boolean removeChangeListener(final ConfigurationChangeListener listener)
+ {
+ if(listener == null)
+ {
+ throw new NullPointerException("Cannot remove a null listener");
+ }
+ synchronized (this)
+ {
+ return _changeListeners.remove(listener);
+ }
+ }
+
+
+ protected void childAdded(ConfiguredObject child)
+ {
+ synchronized (this)
+ {
+ for(ConfigurationChangeListener listener : _changeListeners)
+ {
+ listener.childAdded(this, child);
+ }
+ }
+ }
+
+
+ protected void childRemoved(ConfiguredObject child)
+ {
+ synchronized (this)
+ {
+ for(ConfigurationChangeListener listener : _changeListeners)
+ {
+ listener.childRemoved(this, child);
+ }
+ }
+ }
+
+ public Object getAttribute(final String name)
+ {
+ synchronized (this)
+ {
+ return _attributes.get(name);
+ }
+ }
+
+ public Object setAttribute(final String name, final Object expected, final Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ synchronized (this)
+ {
+ Object currentValue = _attributes.get(name);
+ if((currentValue == null && expected == null)
+ || (currentValue != null && currentValue.equals(expected)))
+ {
+ _attributes.put(name, desired);
+ return desired;
+ }
+ else
+ {
+ return currentValue;
+ }
+ }
+ }
+
+ public <T extends ConfiguredObject> T getParent(final Class<T> clazz)
+ {
+ synchronized (this)
+ {
+ return (T) _parents.get(clazz);
+ }
+ }
+
+ protected <T extends ConfiguredObject> void addParent(Class<T> clazz, T parent)
+ {
+ synchronized (this)
+ {
+ _parents.put(clazz, parent);
+ }
+ }
+
+ protected <T extends ConfiguredObject> void removeParent(Class<T> clazz)
+ {
+ synchronized (this)
+ {
+ _parents.remove(clazz);
+ }
+ }
+
+ public Collection<String> getAttributeNames()
+ {
+ synchronized(_attributes)
+ {
+ return new ArrayList<String>(_attributes.keySet());
+ }
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
new file mode 100644
index 0000000000..8a75818f04
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
@@ -0,0 +1,487 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.security.auth.login.AccountNotFoundException;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.model.*;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
+public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider
+{
+ private static final Logger LOGGER = Logger.getLogger(AuthenticationProviderAdapter.class);
+
+ private final BrokerAdapter _broker;
+ private final T _authManager;
+
+ private AuthenticationProviderAdapter(BrokerAdapter brokerAdapter,
+ final T authManager)
+ {
+ _broker = brokerAdapter;
+ _authManager = authManager;
+ }
+
+ public static AuthenticationProviderAdapter createAuthenticationProviderAdapter(BrokerAdapter brokerAdapter,
+ final AuthenticationManager authManager)
+ {
+ return authManager instanceof PrincipalDatabaseAuthenticationManager
+ ? new PrincipalDatabaseAuthenticationManagerAdapter(brokerAdapter, (PrincipalDatabaseAuthenticationManager) authManager)
+ : new SimpleAuthenticationProviderAdapter(brokerAdapter, authManager);
+ }
+
+ T getAuthManager()
+ {
+ return _authManager;
+ }
+
+ @Override
+ public Collection<VirtualHostAlias> getVirtualHostPortBindings()
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getName()
+ {
+ return _authManager.getClass().getSimpleName();
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null;
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0;
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AuthenticationProvider.AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(TYPE.equals(name))
+ {
+ return _authManager.getClass().getSimpleName();
+ }
+ else if(CREATED.equals(name))
+ {
+ // TODO
+ }
+ else if(DURABLE.equals(name))
+ {
+ return true;
+ }
+ else if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return State.ACTIVE; // TODO
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ // TODO
+ }
+ else if(UPDATED.equals(name))
+ {
+ // TODO
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return null;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ return null;
+ }
+
+ private static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager>
+ {
+ public SimpleAuthenticationProviderAdapter(
+ BrokerAdapter brokerAdapter, AuthenticationManager authManager)
+ {
+ super(brokerAdapter,authManager);
+ }
+ }
+
+ private static class PrincipalDatabaseAuthenticationManagerAdapter
+ extends AuthenticationProviderAdapter<PrincipalDatabaseAuthenticationManager>
+ implements PasswordCredentialManagingAuthenticationProvider
+ {
+ public PrincipalDatabaseAuthenticationManagerAdapter(
+ BrokerAdapter brokerAdapter, PrincipalDatabaseAuthenticationManager authManager)
+ {
+ super(brokerAdapter, authManager);
+ }
+
+ @Override
+ public boolean createUser(String username, String password, Map<String, String> attributes)
+ {
+ return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray());
+ }
+
+ @Override
+ public void deleteUser(String username) throws AccountNotFoundException
+ {
+ if(getSecurityManager().authoriseMethod(Operation.DELETE,
+ "UserManagement",
+ "deleteUser"))
+ {
+
+ getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username));
+ }
+ else
+ {
+ throw new AccessControlException("Cannot delete user " + username);
+ }
+ }
+
+ private org.apache.qpid.server.security.SecurityManager getSecurityManager()
+ {
+ return ApplicationRegistry.getInstance().getSecurityManager();
+ }
+
+ private PrincipalDatabase getPrincipalDatabase()
+ {
+ return getAuthManager().getPrincipalDatabase();
+ }
+
+ @Override
+ public void setPassword(String username, String password) throws AccountNotFoundException
+ {
+ getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray());
+ }
+
+ public void reload() throws IOException
+ {
+ if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "reload"))
+ {
+ getPrincipalDatabase().reload();
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission to reload principal database");
+ }
+ }
+
+ @Override
+ public Map<String, Map<String, String>> getUsers()
+ {
+
+ Map<String, Map<String,String>> users = new HashMap<String, Map<String, String>>();
+ for(Principal principal : getPrincipalDatabase().getUsers())
+ {
+ users.put(principal.getName(), Collections.EMPTY_MAP);
+ }
+ return users;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ if(childClass == User.class)
+ {
+ Principal p = new UsernamePrincipal((String) attributes.get("name"));
+ if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "createUser"))
+ {
+ if(getPrincipalDatabase().createPrincipal(p, ((String)attributes.get("password")).toCharArray()))
+ {
+ return (C) new PrincipalAdapter(p);
+ }
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission to create a new user");
+ }
+
+ }
+
+ return super.createChild(childClass, attributes, otherParents);
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == User.class)
+ {
+ List<Principal> users = getPrincipalDatabase().getUsers();
+ Collection<User> principals = new ArrayList<User>(users.size());
+ for(Principal user : users)
+ {
+ principals.add(new PrincipalAdapter(user));
+ }
+ return (Collection<C>) Collections.unmodifiableCollection(principals);
+ }
+ else
+ {
+ return super.getChildren(clazz);
+ }
+ }
+
+ private class PrincipalAdapter extends AbstractAdapter implements User
+ {
+ private final Principal _user;
+
+
+ public PrincipalAdapter(Principal user)
+ {
+ super(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName());
+ _user = user;
+
+ }
+
+ @Override
+ public String getPassword()
+ {
+ return null;
+ }
+
+ @Override
+ public void setPassword(String password)
+ {
+ try
+ {
+ PrincipalDatabaseAuthenticationManagerAdapter.this.setPassword(_user.getName(), password);
+ }
+ catch (AccountNotFoundException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public String getName()
+ {
+ return _user.getName();
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException("Names cannot be updated");
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException("Durability cannot be updated");
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException("LifetimePolicy cannot be updated");
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException("ttl cannot be updated");
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return null;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return User.AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ if(name.equals(PASSWORD))
+ {
+ setPassword((String)desired);
+ }
+ return super.setAttribute(name,
+ expected,
+ desired);
+ }
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
+ {
+ if(desiredState == State.DELETED)
+ {
+ try
+ {
+ deleteUser(_user.getName());
+ }
+ catch (AccountNotFoundException e)
+ {
+ LOGGER.warn("Failed to delete user " + _user, e);
+ }
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
new file mode 100644
index 0000000000..d3d04be70f
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
@@ -0,0 +1,222 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.AMQInternalException;
+import org.apache.qpid.AMQSecurityException;
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+
+final class BindingAdapter extends AbstractAdapter implements Binding
+{
+ private final org.apache.qpid.server.binding.Binding _binding;
+ private Statistics _statistics = NoStatistics.getInstance();
+ private final ExchangeAdapter _exchange;
+ private QueueAdapter _queue;
+
+ public BindingAdapter(final org.apache.qpid.server.binding.Binding binding,
+ ExchangeAdapter exchangeAdapter,
+ QueueAdapter queueAdapter)
+ {
+ super(exchangeAdapter.getExchange().getVirtualHost().getName(),
+ exchangeAdapter.getName(),
+ queueAdapter.getName(),
+ binding.getBindingKey());
+ _binding = binding;
+ _exchange = exchangeAdapter;
+ _queue = queueAdapter;
+ addParent(Queue.class, queueAdapter);
+ addParent(Exchange.class, exchangeAdapter);
+ }
+
+
+ public ExchangeAdapter getExchange()
+ {
+ return _exchange;
+ }
+
+ public QueueAdapter getQueue()
+ {
+ return _queue;
+ }
+
+ public String getName()
+ {
+ return _binding.getBindingKey();
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return _binding.getQueue().isDurable() && _binding.getExchange().isDurable();
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new IllegalArgumentException("Cannot add children to a binding");
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return new HashMap<String, Object> (_binding.getArguments());
+ }
+
+ public void delete()
+ {
+ try
+ {
+ _queue.getAMQQueue().getVirtualHost().getBindingFactory().removeBinding(_binding);
+ }
+ catch(AMQSecurityException e)
+ {
+ throw new AccessControlException(e.getMessage());
+ }
+ catch(AMQInternalException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public Object getAttribute(final String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+
+ }
+ else if(DURABLE.equals(name))
+ {
+ return _queue.isDurable() && _exchange.isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return _queue.getLifetimePolicy() == LifetimePolicy.AUTO_DELETE || _exchange.getLifetimePolicy() == LifetimePolicy.AUTO_DELETE ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT;
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+
+ }
+ else if(CREATED.equals(name))
+ {
+
+ }
+ else if(UPDATED.equals(name))
+ {
+
+ }
+ else if(EXCHANGE.equals(name))
+ {
+ return _exchange.getName();
+ }
+ else if(QUEUE.equals(name))
+ {
+ return _queue.getName();
+ }
+ else if(ARGUMENTS.equals(name))
+ {
+ return getArguments();
+ }
+
+ return super.getAttribute(name); //TODO
+ }
+
+ @Override
+ public Object setAttribute(final String name, final Object expected, final Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Binding.AVAILABLE_ATTRIBUTES;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
new file mode 100644
index 0000000000..ad88dbc613
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -0,0 +1,484 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.net.InetSocketAddress;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
+import org.apache.qpid.server.transport.QpidAcceptor;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHostRegistry.RegistryChangeListener,
+ IApplicationRegistry.PortBindingListener,
+ IAuthenticationManagerRegistry.RegistryChangeListener
+{
+
+
+ private final IApplicationRegistry _applicationRegistry;
+ private String _name;
+ private final Map<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter> _vhostAdapters =
+ new HashMap<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter>();
+ private final StatisticsAdapter _statistics;
+ private final Map<QpidAcceptor, PortAdapter> _portAdapters = new HashMap<QpidAcceptor, PortAdapter>();
+ private HTTPPortAdapter _httpManagementPort;
+ private final Map<AuthenticationManager, AuthenticationProviderAdapter> _authManagerAdapters =
+ new HashMap<AuthenticationManager, AuthenticationProviderAdapter>();
+
+
+ public BrokerAdapter(final IApplicationRegistry instance)
+ {
+ _applicationRegistry = instance;
+ _name = "Broker";
+ _statistics = new StatisticsAdapter(instance);
+
+ instance.getVirtualHostRegistry().addRegistryChangeListener(this);
+ populateVhosts();
+ instance.addPortBindingListener(this);
+ populatePorts();
+ instance.addRegistryChangeListener(this);
+ populateAuthenticationManagers();
+ }
+
+ private void populateVhosts()
+ {
+ synchronized(_vhostAdapters)
+ {
+ Collection<org.apache.qpid.server.virtualhost.VirtualHost> actualVhosts =
+ _applicationRegistry.getVirtualHostRegistry().getVirtualHosts();
+ for(org.apache.qpid.server.virtualhost.VirtualHost vh : actualVhosts)
+ {
+ if(!_vhostAdapters.containsKey(vh))
+ {
+ _vhostAdapters.put(vh, new VirtualHostAdapter(this, vh));
+ }
+ }
+
+ }
+ }
+
+
+ public Collection<VirtualHost> getVirtualHosts()
+ {
+ synchronized(_vhostAdapters)
+ {
+ return new ArrayList<VirtualHost>(_vhostAdapters.values());
+ }
+
+ }
+ private void populatePorts()
+ {
+ synchronized (_portAdapters)
+ {
+ Map<InetSocketAddress, QpidAcceptor> acceptors = _applicationRegistry.getAcceptors();
+
+ for(Map.Entry<InetSocketAddress, QpidAcceptor> entry : acceptors.entrySet())
+ {
+ if(!_portAdapters.containsKey(entry.getValue()))
+ {
+ _portAdapters.put(entry.getValue(), new PortAdapter(this, entry.getValue(), entry.getKey()));
+ }
+ }
+ if(_applicationRegistry.useHTTPManagement())
+ {
+ _httpManagementPort = new HTTPPortAdapter(this, _applicationRegistry.getHTTPManagementPort());
+ }
+
+ }
+ }
+
+ public Collection<Port> getPorts()
+ {
+ synchronized (_portAdapters)
+ {
+ final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values());
+ if(_httpManagementPort != null)
+ {
+ ports.add(_httpManagementPort);
+ }
+ return ports;
+ }
+ }
+
+ private void populateAuthenticationManagers()
+ {
+ synchronized (_authManagerAdapters)
+ {
+ IAuthenticationManagerRegistry authenticationManagerRegistry =
+ _applicationRegistry.getAuthenticationManagerRegistry();
+ if(authenticationManagerRegistry != null)
+ {
+ Map<String, AuthenticationManager> authenticationManagers =
+ authenticationManagerRegistry.getAvailableAuthenticationManagers();
+
+ for(Map.Entry<String, AuthenticationManager> entry : authenticationManagers.entrySet())
+ {
+ if(!_authManagerAdapters.containsKey(entry.getValue()))
+ {
+ _authManagerAdapters.put(entry.getValue(),
+ AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this,
+ entry.getValue()));
+ }
+ }
+ }
+ }
+ }
+
+ public Collection<AuthenticationProvider> getAuthenticationProviders()
+ {
+ synchronized (_authManagerAdapters)
+ {
+ final ArrayList<AuthenticationProvider> authManagers =
+ new ArrayList<AuthenticationProvider>(_authManagerAdapters.values());
+ return authManagers;
+ }
+
+ }
+
+ public VirtualHost createVirtualHost(final String name,
+ final State initialState,
+ final boolean durable,
+ final LifetimePolicy lifetime,
+ final long ttl,
+ final Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public VirtualHost createVirtualHost(final Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public void deleteVirtualHost(final VirtualHost vhost)
+ throws AccessControlException, IllegalStateException
+ {
+ //TODO
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == VirtualHost.class)
+ {
+ return (Collection<C>) getVirtualHosts();
+ }
+ else if(clazz == Port.class)
+ {
+ return (Collection<C>) getPorts();
+ }
+ else if(clazz == AuthenticationProvider.class)
+ {
+ return (Collection<C>) getAuthenticationProviders();
+ }
+
+ return Collections.emptySet();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if(childClass == VirtualHost.class)
+ {
+ return (C) createVirtualHost(attributes);
+ }
+ else if(childClass == Port.class)
+ {
+ return (C) createPort(attributes);
+ }
+ else if(childClass == AuthenticationProvider.class)
+ {
+ return (C) createAuthenticationProvider(attributes);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Cannot create child of class " + childClass.getSimpleName());
+ }
+ }
+
+ private Port createPort(Map<String, Object> attributes)
+ {
+ // TODO
+ return null;
+ }
+
+ private AuthenticationProvider createAuthenticationProvider(Map<String,Object> attributes)
+ {
+ // TODO
+ return null;
+ }
+
+
+ public void virtualHostRegistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ {
+ VirtualHostAdapter adapter = null;
+ synchronized (_vhostAdapters)
+ {
+ if(!_vhostAdapters.containsKey(virtualHost))
+ {
+ adapter = new VirtualHostAdapter(this, virtualHost);
+ _vhostAdapters.put(virtualHost, adapter);
+ }
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+ }
+
+ public void virtualHostUnregistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ {
+ VirtualHostAdapter adapter = null;
+
+ synchronized (_vhostAdapters)
+ {
+ adapter = _vhostAdapters.remove(virtualHost);
+ }
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ @Override
+ public void authenticationManagerRegistered(AuthenticationManager authenticationManager)
+ {
+ AuthenticationProviderAdapter adapter = null;
+ synchronized (_authManagerAdapters)
+ {
+ if(!_authManagerAdapters.containsKey(authenticationManager))
+ {
+ adapter =
+ AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, authenticationManager);
+ _authManagerAdapters.put(authenticationManager, adapter);
+ }
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+ }
+
+ @Override
+ public void authenticationManagerUnregistered(AuthenticationManager authenticationManager)
+ {
+ AuthenticationProviderAdapter adapter;
+ synchronized (_authManagerAdapters)
+ {
+ adapter = _authManagerAdapters.remove(authenticationManager);
+ }
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+
+ @Override
+ public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress)
+ {
+ synchronized (_portAdapters)
+ {
+ if(!_portAdapters.containsKey(acceptor))
+ {
+ PortAdapter adapter = new PortAdapter(this, acceptor, bindAddress);
+ _portAdapters.put(acceptor, adapter);
+ childAdded(adapter);
+ }
+ }
+ }
+
+ @Override
+ public void unbound(QpidAcceptor acceptor)
+ {
+ PortAdapter adapter = null;
+
+ synchronized (_portAdapters)
+ {
+ adapter = _portAdapters.remove(acceptor);
+ }
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return State.ACTIVE;
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ // TODO
+ }
+ else if(CREATED.equals(name))
+ {
+ // TODO
+ }
+ else if(UPDATED.equals(name))
+ {
+ // TODO
+ }
+ else if(BUILD_VERSION.equals(name))
+ {
+ return QpidProperties.getBuildVersion();
+ }
+ else if(BYTES_RETAINED.equals(name))
+ {
+ // TODO
+ }
+ else if(OPERATING_SYSTEM.equals(name))
+ {
+ return System.getProperty("os.name") + " "
+ + System.getProperty("os.version") + " "
+ + System.getProperty("os.arch");
+ }
+ else if(PLATFORM.equals(name))
+ {
+ return System.getProperty("java.vendor") + " "
+ + System.getProperty("java.runtime.version", System.getProperty("java.version"));
+ }
+ else if(PROCESS_PID.equals(name))
+ {
+ // TODO
+ }
+ else if(PRODUCT_VERSION.equals(name))
+ {
+ return QpidProperties.getReleaseVersion();
+ }
+ else if(STATISTICS_ENABLED.equals(name))
+ {
+ // TODO
+ }
+ else if(SUPPORTED_STORE_TYPES.equals(name))
+ {
+ // TODO
+ }
+
+ return super.getAttribute(name); //TODO - Implement.
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement.
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
new file mode 100644
index 0000000000..8114156e3a
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
@@ -0,0 +1,315 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Session;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.protocol.AMQSessionModel;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+
+final class ConnectionAdapter extends AbstractAdapter implements Connection
+{
+
+
+
+
+ private AMQConnectionModel _connection;
+
+ private final Map<AMQSessionModel, SessionAdapter> _sessionAdapters =
+ new HashMap<AMQSessionModel, SessionAdapter>();
+ private final Statistics _statistics;
+
+ public ConnectionAdapter(final AMQConnectionModel conn)
+ {
+ _connection = conn;
+ _statistics = new ConnectionStatisticsAdapter(conn);
+ }
+
+ public Collection<Session> getSessions()
+ {
+ List<AMQSessionModel> actualSessions = _connection.getSessionModels();
+
+ synchronized (_sessionAdapters)
+ {
+ for(AMQSessionModel session : _sessionAdapters.keySet())
+ {
+ if(!actualSessions.contains(session))
+ {
+ _sessionAdapters.remove(session);
+ }
+ }
+ for(AMQSessionModel session : actualSessions)
+ {
+ if(!_sessionAdapters.containsKey(session))
+ {
+ _sessionAdapters.put(session, new SessionAdapter(session));
+ }
+ }
+ return new ArrayList<Session>(_sessionAdapters.values());
+ }
+ }
+
+ public void delete()
+ {
+ try
+ {
+ _connection.close(AMQConstant.CONNECTION_FORCED, "Connection closed by external action");
+ }
+ catch(AMQException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public String getName()
+ {
+ final String remoteAddressString = _connection.getRemoteAddressString();
+ return remoteAddressString.replaceAll("/","");
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return false; //TODO
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return null; //TODO
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+
+ if(name.equals(ID))
+ {
+ return getId();
+ }
+ else if (name.equals(NAME))
+ {
+ return getName();
+ }
+ else if(name.equals(CLIENT_ID))
+ {
+ return _connection.getClientId();
+ }
+ else if(name.equals(CLIENT_VERSION))
+ {
+ return _connection.getClientVersion();
+ }
+ else if(name.equals(INCOMING))
+ {
+
+ }
+ else if(name.equals(LOCAL_ADDRESS))
+ {
+
+ }
+ else if(name.equals(PRINCIPAL))
+ {
+ return _connection.getPrincipalAsString();
+ }
+ else if(name.equals(PROPERTIES))
+ {
+
+ }
+ else if(name.equals(REMOTE_ADDRESS))
+ {
+ return _connection.getRemoteAddressString();
+ }
+ else if(name.equals(REMOTE_PROCESS_NAME))
+ {
+
+ }
+ else if(name.equals(REMOTE_PROCESS_PID))
+ {
+
+ }
+ else if(name.equals(SESSION_COUNT_LIMIT))
+ {
+ return _connection.getSessionCountLimit();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ if(name.equals(CLIENT_ID))
+ {
+
+ }
+ else if(name.equals(CLIENT_VERSION))
+ {
+
+ }
+ else if(name.equals(INCOMING))
+ {
+
+ }
+ else if(name.equals(LOCAL_ADDRESS))
+ {
+
+ }
+ else if(name.equals(PRINCIPAL))
+ {
+
+ }
+ else if(name.equals(PROPERTIES))
+ {
+
+ }
+ else if(name.equals(REMOTE_ADDRESS))
+ {
+
+ }
+ else if(name.equals(REMOTE_PROCESS_NAME))
+ {
+
+ }
+ else if(name.equals(REMOTE_PROCESS_PID))
+ {
+
+ }
+ else if(name.equals(SESSION_COUNT_LIMIT))
+ {
+
+ }
+ return super.setAttribute(name, expected, desired);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ final HashSet<String> attrNames = new HashSet<String>(super.getAttributeNames());
+ attrNames.addAll(Connection.AVAILABLE_ATTRIBUTES);
+ return Collections.unmodifiableCollection(attrNames);
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Session.class)
+ {
+ return (Collection<C>) getSessions();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if(childClass == Session.class)
+ {
+ throw new IllegalStateException();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Cannot create a child of class " + childClass.getSimpleName());
+ }
+
+ }
+
+ private class ConnectionStatisticsAdapter extends StatisticsAdapter
+ {
+ public ConnectionStatisticsAdapter(StatisticsGatherer applicationRegistry)
+ {
+ super(applicationRegistry);
+ }
+
+ @Override
+ public Collection<String> getStatisticNames()
+ {
+ return Connection.AVAILABLE_STATISTICS;
+ }
+
+ @Override
+ public Object getStatistic(String name)
+ {
+ if(LAST_IO_TIME.equals(name))
+ {
+ return _connection.getLastIoTime();
+ }
+ else if(SESSION_COUNT.equals(name))
+ {
+ return _connection.getSessionModels().size();
+ }
+ return super.getStatistic(name);
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java
new file mode 100644
index 0000000000..6fb6f4971d
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java
@@ -0,0 +1,225 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.util.Map;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Consumer;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.subscription.Subscription;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+
+public class ConsumerAdapter extends AbstractAdapter implements Consumer
+{
+ private final Subscription _subscription;
+ private final QueueAdapter _queue;
+ private final ConsumerStatistics _statistics;
+
+ public ConsumerAdapter(final QueueAdapter queueAdapter, final Subscription subscription)
+ {
+ super(queueAdapter.getVirtualHost().getName(),
+ queueAdapter.getName(),
+ subscription.getSessionModel().getConnectionModel().getRemoteAddressString(),
+ String.valueOf(subscription.getSessionModel().getChannelId()),
+ subscription.getConsumerName() );
+
+ _subscription = subscription;
+ _queue = queueAdapter;
+ _statistics = new ConsumerStatistics();
+ //TODO
+ }
+
+ public String getName()
+ {
+ return _subscription.getConsumerName();
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return false; //TODO
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return null; //TODO
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Consumer.AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object setAttribute(final String name, final Object expected, final Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO
+ }
+
+ @Override
+ public Object getAttribute(final String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+
+ }
+ else if(DURABLE.equals(name))
+ {
+ return false;
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.AUTO_DELETE;
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+
+ }
+ else if(CREATED.equals(name))
+ {
+
+ }
+ else if(UPDATED.equals(name))
+ {
+
+ }
+ else if(DISTRIBUTION_MODE.equals(name))
+ {
+ return _subscription.acquires() ? "MOVE" : "COPY";
+ }
+ else if(SETTLEMENT_MODE.equals(name))
+ {
+
+ }
+ else if(EXCLUSIVE.equals(name))
+ {
+
+ }
+ else if(NO_LOCAL.equals(name))
+ {
+
+ }
+ else if(SELECTOR.equals(name))
+ {
+
+ }
+ return super.getAttribute(name); //TODO
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ private class ConsumerStatistics implements Statistics
+ {
+
+ public Collection<String> getStatisticNames()
+ {
+ return AVAILABLE_STATISTICS;
+ }
+
+ public Object getStatistic(String name)
+ {
+ if(name.equals(BYTES_OUT))
+ {
+ return _subscription.getBytesOut();
+ }
+ else if(name.equals(MESSAGES_OUT))
+ {
+ return _subscription.getMessagesOut();
+ }
+ else if(name.equals(STATE_CHANGED))
+ {
+
+ }
+ else if(name.equals(UNACKNOWLEDGED_BYTES))
+ {
+ return _subscription.getUnacknowledgedBytes();
+ }
+ else if(name.equals(UNACKNOWLEDGED_MESSAGES))
+ {
+ return _subscription.getUnacknowledgedMessages();
+ }
+ return null; // TODO - Implement
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
new file mode 100644
index 0000000000..dd22804355
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
@@ -0,0 +1,409 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInternalException;
+import org.apache.qpid.AMQSecurityException;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Publisher;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apache.qpid.server.exchange.Exchange.BindingListener
+{
+
+ private final org.apache.qpid.server.exchange.Exchange _exchange;
+ private final Map<Binding, BindingAdapter> _bindingAdapters =
+ new HashMap<Binding, BindingAdapter>();
+ private VirtualHostAdapter _vhost;
+ private final ExchangeStatistics _statistics;
+
+
+ public ExchangeAdapter(final VirtualHostAdapter virtualHostAdapter,
+ final org.apache.qpid.server.exchange.Exchange exchange)
+ {
+ super(virtualHostAdapter.getName(), exchange.getName());
+ _statistics = new ExchangeStatistics();
+ _vhost = virtualHostAdapter;
+ _exchange = exchange;
+ addParent(org.apache.qpid.server.model.VirtualHost.class, virtualHostAdapter);
+
+ exchange.addBindingListener(this);
+ populateBindings();
+ }
+
+ private void populateBindings()
+ {
+ Collection<Binding> actualBindings = _exchange.getBindings();
+ synchronized (_bindingAdapters)
+ {
+ for(Binding binding : actualBindings)
+ {
+ if(!_bindingAdapters.containsKey(binding))
+ {
+ QueueAdapter queueAdapter = _vhost.getQueueAdapter(binding.getQueue());
+ BindingAdapter adapter = new BindingAdapter(binding, this, queueAdapter);
+ _bindingAdapters.put(binding, adapter);
+
+ queueAdapter.bindingRegistered(binding, adapter);
+ }
+ }
+ }
+
+ }
+
+ public String getExchangeType()
+ {
+ return _exchange.getType().getName().toString();
+ }
+
+ public Collection<org.apache.qpid.server.model.Binding> getBindings()
+ {
+ synchronized (_bindingAdapters)
+ {
+ return new ArrayList<org.apache.qpid.server.model.Binding>(_bindingAdapters.values());
+ }
+
+ }
+
+ public Collection<Publisher> getPublishers()
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+
+ public org.apache.qpid.server.model.Binding createBinding(Queue queue,
+ Map<String, Object> attributes)
+ throws AccessControlException, IllegalStateException
+ {
+ attributes = new HashMap<String, Object>(attributes);
+ String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, "");
+ Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP);
+
+ attributes.remove(org.apache.qpid.server.model.Binding.NAME);
+ attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS);
+
+ return createBinding(bindingKey, queue, bindingArgs, attributes);
+
+ }
+
+ public org.apache.qpid.server.model.Binding createBinding(String bindingKey, Queue queue,
+ Map<String, Object> bindingArguments,
+ Map<String, Object> attributes)
+ throws AccessControlException, IllegalStateException
+ {
+ VirtualHost virtualHost = _vhost.getVirtualHost();
+
+
+ AMQQueue amqQueue = ((QueueAdapter)queue).getAMQQueue();
+
+ try
+ {
+ if(!virtualHost.getBindingFactory().addBinding(bindingKey, amqQueue, _exchange, bindingArguments))
+ {
+ Binding oldBinding = virtualHost.getBindingFactory().getBinding(bindingKey, amqQueue, _exchange,
+ bindingArguments);
+
+ Map<String, Object> oldArgs = oldBinding.getArguments();
+ if((oldArgs == null && !bindingArguments.isEmpty()) || (oldArgs != null && !oldArgs.equals(bindingArguments)))
+ {
+ //TODO: generate deterministic UUID
+ virtualHost.getBindingFactory().replaceBinding(UUIDGenerator.generateUUID(), bindingKey, amqQueue, _exchange, bindingArguments);
+ }
+ }
+ Binding binding = virtualHost.getBindingFactory().getBinding(bindingKey, amqQueue, _exchange, bindingArguments);
+
+ synchronized (_bindingAdapters)
+ {
+ return binding == null ? null : _bindingAdapters.get(binding);
+ }
+ }
+ catch(AMQSecurityException e)
+ {
+ throw new AccessControlException(e.toString());
+ }
+ catch(AMQInternalException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public void delete()
+ {
+ try
+ {
+ _vhost.getVirtualHost().getExchangeRegistry().unregisterExchange(getName(), false);
+ }
+ catch(AMQException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public String getName()
+ {
+ return _exchange.getName();
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return _exchange.isDurable();
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return _exchange.isAutoDelete() ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT;
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == org.apache.qpid.server.model.Binding.class)
+ {
+ return (Collection<C>) getBindings();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if(childClass == org.apache.qpid.server.model.Binding.class)
+ {
+ if(otherParents != null && otherParents.length == 1 && otherParents[0] instanceof Queue)
+ {
+ Queue queue = (Queue) otherParents[0];
+ if(queue.getParent(org.apache.qpid.server.model.VirtualHost.class) == getParent(org.apache.qpid.server.model.VirtualHost.class))
+ {
+ return (C) createBinding(queue, attributes);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Queue and Exchange parents of a binding must be on same virtual host");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("Other parent must be a queue");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public void bindingAdded(org.apache.qpid.server.exchange.Exchange exchange, Binding binding)
+ {
+ BindingAdapter adapter = null;
+ synchronized (_bindingAdapters)
+ {
+ if(!_bindingAdapters.containsKey(binding))
+ {
+ QueueAdapter queueAdapter = _vhost.getQueueAdapter(binding.getQueue());
+ adapter = new BindingAdapter(binding, this, queueAdapter);
+ _bindingAdapters.put(binding,adapter);
+ queueAdapter.bindingRegistered(binding,adapter);
+ }
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+ }
+
+ public void bindingRemoved(org.apache.qpid.server.exchange.Exchange exchange, Binding binding)
+ {
+ BindingAdapter adapter = null;
+ synchronized (_bindingAdapters)
+ {
+ adapter = _bindingAdapters.remove(binding);
+ }
+ if(adapter != null)
+ {
+ _vhost.getQueueAdapter(binding.getQueue()).bindingUnregistered(binding);
+ childRemoved(adapter);
+ }
+ }
+
+ org.apache.qpid.server.exchange.Exchange getExchange()
+ {
+ return _exchange;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return State.ACTIVE;
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return _exchange.isAutoDelete() ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT;
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+
+ }
+ else if(CREATED.equals(name))
+ {
+
+ }
+ else if(UPDATED.equals(name))
+ {
+
+ }
+ else if(ALTERNATE_EXCHANGE.equals(name))
+ {
+ return _exchange.getAlternateExchange();
+ }
+ else if(TYPE.equals(name))
+ {
+ return _exchange.getType().getName().asString();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ private class ExchangeStatistics implements Statistics
+ {
+
+ public Collection<String> getStatisticNames()
+ {
+ return AVAILABLE_STATISTICS;
+ }
+
+ public Object getStatistic(String name)
+ {
+ if(BINDING_COUNT.equals(name))
+ {
+ return _exchange.getBindingCount();
+ }
+ else if(BYTES_DROPPED.equals(name))
+ {
+ return _exchange.getByteDrops();
+ }
+ else if(BYTES_IN.equals(name))
+ {
+ return _exchange.getByteReceives();
+ }
+ else if(MESSAGES_DROPPED.equals(name))
+ {
+ return _exchange.getMsgDrops();
+ }
+ else if(MESSAGES_IN.equals(name))
+ {
+ return _exchange.getMsgReceives();
+ }
+ else if(PRODUCER_COUNT.equals(name))
+ {
+
+ }
+ else if(STATE_CHANGED.equals(name))
+ {
+
+ }
+ return null; // TODO - Implement
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
new file mode 100644
index 0000000000..fdcc5e0184
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
@@ -0,0 +1,262 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.VirtualHostAlias;
+
+public class HTTPPortAdapter extends AbstractAdapter implements Port
+{
+ private final BrokerAdapter _broker;
+ private int _port;
+ public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port)
+ {
+ _broker = brokerAdapter;
+ _port = port;
+
+ }
+
+ @Override
+ public String getBindingAddress()
+ {
+ return "0.0.0.0";
+ }
+
+ @Override
+ public int getPort()
+ {
+ return _port;
+ }
+
+ @Override
+ public Collection<Transport> getTransports()
+ {
+ return Collections.singleton(Transport.TCP);
+ }
+
+ @Override
+ public void addTransport(Transport transport)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Transport removeTransport(Transport transport)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Collection<Protocol> getProtocols()
+ {
+ return Collections.singleton(Protocol.HTTP);
+ }
+
+ @Override
+ public void addProtocol(Protocol protocol)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Protocol removeProtocol(Protocol protocol)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Collection<VirtualHostAlias> getVirtualHostBindings()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Collection<Connection> getConnections()
+ {
+ return Collections.emptySet(); // TODO - Implement
+ }
+
+ @Override
+ public String getName()
+ {
+ return getBindingAddress() + ":" + getPort(); // TODO - Implement
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return false; // TODO - Implement
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0; // TODO - Implement
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Connection.class)
+ {
+ return (Collection<C>) getConnections();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return getActualState();
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return getLifetimePolicy();
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ return getTimeToLive();
+ }
+ else if(CREATED.equals(name))
+ {
+
+ }
+ else if(UPDATED.equals(name))
+ {
+
+ }
+ else if(BINDING_ADDRESS.equals(name))
+ {
+ return getBindingAddress();
+ }
+ else if(PORT.equals(name))
+ {
+ return getPort();
+ }
+ else if(PROTOCOLS.equals(name))
+ {
+ return getProtocols();
+ }
+ else if(TRANSPORTS.equals(name))
+ {
+ return getTransports();
+ }
+
+ return super.getAttribute(name); //TODO - Implement
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java
new file mode 100644
index 0000000000..b83887ffe5
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java
@@ -0,0 +1,46 @@
+package org.apache.qpid.server.model.adapter;
+
+import org.apache.qpid.server.model.Statistics;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+public class NoStatistics implements Statistics
+{
+ private static final NoStatistics INSTANCE = new NoStatistics();
+
+ private NoStatistics()
+ {
+ }
+
+ public Collection<String> getStatisticNames()
+ {
+ return Collections.emptyList();
+ }
+
+ public Object getStatistic(String name)
+ {
+ return null;
+ }
+
+ public static NoStatistics getInstance()
+ {
+ return INSTANCE;
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
new file mode 100644
index 0000000000..0021431ee3
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
@@ -0,0 +1,318 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.util.Map;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostAlias;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.transport.QpidAcceptor;
+
+import java.net.InetSocketAddress;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class PortAdapter extends AbstractAdapter implements Port
+{
+ private final BrokerAdapter _broker;
+ private final QpidAcceptor _acceptor;
+ private final InetSocketAddress _address;
+ private final Collection<Protocol> _protocols;
+
+ public PortAdapter(BrokerAdapter brokerAdapter, QpidAcceptor acceptor, InetSocketAddress address)
+ {
+ _broker = brokerAdapter;
+ _acceptor = acceptor;
+ _address = address;
+
+ List<Protocol> protocols = new ArrayList<Protocol>();
+
+ for(AmqpProtocolVersion pv : _acceptor.getSupported())
+ {
+ switch(pv)
+ {
+ case v0_8:
+ protocols.add(Protocol.AMQP_0_8);
+ break;
+ case v0_9:
+ protocols.add(Protocol.AMQP_0_9);
+ break;
+ case v0_9_1:
+ protocols.add(Protocol.AMQP_0_9_1);
+ break;
+ case v0_10:
+ protocols.add(Protocol.AMQP_0_10);
+ break;
+ case v1_0_0:
+ protocols.add(Protocol.AMQP_1_0);
+ break;
+ }
+ }
+
+ _protocols = Collections.unmodifiableCollection(protocols);
+
+ }
+
+ @Override
+ public String getBindingAddress()
+ {
+ return _address.getHostName();
+ }
+
+ @Override
+ public int getPort()
+ {
+ return _address.getPort();
+ }
+
+ @Override
+ public Collection<Transport> getTransports()
+ {
+ switch (_acceptor.getTransport())
+ {
+ case TCP:
+ return Collections.singleton(Transport.TCP);
+ case SSL:
+ return Collections.singleton(Transport.SSL);
+ }
+
+ return null; // TODO - Implement
+ }
+
+ @Override
+ public void addTransport(Transport transport)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Transport removeTransport(Transport transport)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Collection<Protocol> getProtocols()
+ {
+ return _protocols;
+ }
+
+ @Override
+ public void addProtocol(Protocol protocol)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Protocol removeProtocol(Protocol protocol)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Collection<VirtualHostAlias> getVirtualHostBindings()
+ {
+ List<VirtualHostAlias> aliases = new ArrayList<VirtualHostAlias>();
+ for(VirtualHost vh : _broker.getVirtualHosts())
+ {
+ for(VirtualHostAlias alias : vh.getAliases())
+ {
+ if(alias.getPort().equals(this))
+ {
+ aliases.add(alias);
+ }
+ }
+ }
+ return Collections.unmodifiableCollection(aliases);
+ }
+
+ @Override
+ public Collection<Connection> getConnections()
+ {
+ return null; // TODO - Implement
+ }
+
+ @Override
+ public String getName()
+ {
+ return getBindingAddress() + ":" + getPort(); // TODO - Implement
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return State.ACTIVE;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return false; // TODO - Implement
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0; // TODO - Implement
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Connection.class)
+ {
+ return (Collection<C>) getConnections();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return getActualState();
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return getLifetimePolicy();
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ return getTimeToLive();
+ }
+ else if(CREATED.equals(name))
+ {
+
+ }
+ else if(UPDATED.equals(name))
+ {
+
+ }
+ else if(BINDING_ADDRESS.equals(name))
+ {
+ return getBindingAddress();
+ }
+ else if(PORT.equals(name))
+ {
+ return getPort();
+ }
+ else if(PROTOCOLS.equals(name))
+ {
+ return getProtocols();
+ }
+ else if(TRANSPORTS.equals(name))
+ {
+ return getTransports();
+ }
+
+ return super.getAttribute(name); //TODO - Implement
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
new file mode 100644
index 0000000000..5c35fe5f7b
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
@@ -0,0 +1,702 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQStoreException;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObjectFinder;
+import org.apache.qpid.server.model.Consumer;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.QueueNotificationListener;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.queue.*;
+import org.apache.qpid.server.subscription.Subscription;
+
+final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.SubscriptionRegistrationListener, AMQQueue.NotificationListener
+{
+
+ static final Map<String, String> ATTRIBUTE_MAPPINGS = new HashMap<String, String>();
+ static
+ {
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_REPEAT_GAP, "x-qpid-minimum-alert-repeat-gap");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, "x-qpid-maximum-message-size");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, "x-qpid-maximum-message-age");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, "x-qpid-maximum-message-count");
+
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, "x-qpid-maximum-delivery-count");
+
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, "x-qpid-capacity");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, "x-qpid-flow-resume-capacity");
+
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.SORT_KEY, "qpid.sort_key");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.LVQ_KEY, "qpid.last_value_queue_key");
+
+ }
+
+ private final AMQQueue _queue;
+ private final Map<Binding, BindingAdapter> _bindingAdapters =
+ new HashMap<Binding, BindingAdapter>();
+ private Map<org.apache.qpid.server.subscription.Subscription, ConsumerAdapter> _consumerAdapters =
+ new HashMap<org.apache.qpid.server.subscription.Subscription, ConsumerAdapter>();
+
+
+ private final VirtualHostAdapter _vhost;
+ private QueueStatisticsAdapter _statistics;
+ private QueueNotificationListener _queueNotificationListener;
+
+ public QueueAdapter(final VirtualHostAdapter virtualHostAdapter, final AMQQueue queue)
+ {
+ super(virtualHostAdapter.getName(), queue.getName());
+ _vhost = virtualHostAdapter;
+ addParent(org.apache.qpid.server.model.VirtualHost.class, virtualHostAdapter);
+
+ _queue = queue;
+ _queue.addSubscriptionRegistrationListener(this);
+ populateConsumers();
+ _statistics = new QueueStatisticsAdapter(queue);
+ _queue.setNotificationListener(this);
+ }
+
+ private void populateConsumers()
+ {
+ Collection<org.apache.qpid.server.subscription.Subscription> actualSubscriptions = _queue.getConsumers();
+
+ synchronized (_consumerAdapters)
+ {
+ Iterator<org.apache.qpid.server.subscription.Subscription> iter = _consumerAdapters.keySet().iterator();
+ for(org.apache.qpid.server.subscription.Subscription subscription : actualSubscriptions)
+ {
+ if(!_consumerAdapters.containsKey(subscription))
+ {
+ _consumerAdapters.put(subscription, new ConsumerAdapter(this, subscription));
+ }
+ }
+ }
+ }
+
+ public Collection<org.apache.qpid.server.model.Binding> getBindings()
+ {
+ synchronized (_bindingAdapters)
+ {
+ return new ArrayList<org.apache.qpid.server.model.Binding>(_bindingAdapters.values());
+ }
+ }
+
+ public Collection<Consumer> getConsumers()
+ {
+ synchronized (_consumerAdapters)
+ {
+ return new ArrayList<Consumer>(_consumerAdapters.values());
+ }
+
+ }
+
+ public void visit(final QueueEntryVisitor visitor)
+ {
+ _queue.visit(visitor);
+ }
+
+ public void delete()
+ {
+ try
+ {
+ _queue.delete();
+ if (_queue.isDurable())
+ {
+
+ _queue.getVirtualHost().getMessageStore().removeQueue(_queue);
+ }
+ }
+ catch(AMQException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public String getName()
+ {
+ return _queue.getName();
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return _queue.isDurable();
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return _queue.isAutoDelete() ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT;
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Queue.AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ try
+ {
+ if(ALERT_REPEAT_GAP.equals(name))
+ {
+ _queue.setMinimumAlertRepeatGap((Long)desired);
+ return desired;
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name))
+ {
+ _queue.setMaximumMessageAge((Long)desired);
+ return desired;
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name))
+ {
+ _queue.setMaximumMessageSize((Long)desired);
+ return desired;
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name))
+ {
+ _queue.setMaximumQueueDepth((Long)desired);
+ return desired;
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name))
+ {
+ _queue.setMaximumMessageCount((Long)desired);
+ return desired;
+ }
+ else if(ALTERNATE_EXCHANGE.equals(name))
+ {
+ // In future we may want to accept a UUID as an alternative way to identifying the exchange
+ ExchangeAdapter alternateExchange = (ExchangeAdapter) desired;
+ _queue.setAlternateExchange(alternateExchange == null ? null : alternateExchange.getExchange());
+ return desired;
+ }
+ else if(EXCLUSIVE.equals(name))
+ {
+ Boolean exclusiveFlag = (Boolean) desired;
+ _queue.setExclusive(exclusiveFlag);
+ return desired;
+ }
+ else if(MESSAGE_GROUP_KEY.equals(name))
+ {
+ // TODO
+ }
+ else if(MESSAGE_GROUP_DEFAULT_GROUP.equals(name))
+ {
+ // TODO
+ }
+ else if(MESSAGE_GROUP_SHARED_GROUPS.equals(name))
+ {
+ // TODO
+ }
+ else if(LVQ_KEY.equals(name))
+ {
+ // TODO
+ }
+ else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
+ {
+ _queue.setMaximumDeliveryCount((Integer)desired);
+ return desired;
+ }
+ else if(NO_LOCAL.equals(name))
+ {
+ // TODO
+ }
+ else if(OWNER.equals(name))
+ {
+ // TODO
+ }
+ else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name))
+ {
+ _queue.setCapacity((Long)desired);
+ return desired;
+ }
+ else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name))
+ {
+ _queue.setFlowResumeCapacity((Long)desired);
+ return desired;
+ }
+ else if(QUEUE_FLOW_STOPPED.equals(name))
+ {
+ // TODO
+ }
+ else if(SORT_KEY.equals(name))
+ {
+ // TODO
+ }
+ else if(TYPE.equals(name))
+ {
+ // TODO
+ }
+ else if (DESCRIPTION.equals(name))
+ {
+ _queue.setDescription((String) desired);
+ return desired;
+ }
+
+ return super.setAttribute(name, expected, desired);
+ }
+ finally
+ {
+ if (_queue.isDurable())
+ {
+ try
+ {
+ _queue.getVirtualHost().getMessageStore().updateQueue(_queue);
+ }
+ catch (AMQStoreException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+
+ if(ALERT_REPEAT_GAP.equals(name))
+ {
+ return _queue.getMinimumAlertRepeatGap();
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name))
+ {
+ return _queue.getMaximumMessageAge();
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name))
+ {
+ return _queue.getMaximumMessageSize();
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name))
+ {
+ return _queue.getMaximumQueueDepth();
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name))
+ {
+ return _queue.getMaximumMessageCount();
+ }
+ else if(ALTERNATE_EXCHANGE.equals(name))
+ {
+ org.apache.qpid.server.exchange.Exchange alternateExchange = _queue.getAlternateExchange();
+ return alternateExchange == null ? null :
+ ConfiguredObjectFinder.findConfiguredObjectByName(_vhost.getExchanges(),
+ alternateExchange.getName());
+ }
+ else if(EXCLUSIVE.equals(name))
+ {
+ return _queue.isExclusive();
+ }
+ else if(MESSAGE_GROUP_KEY.equals(name))
+ {
+ // TODO
+ }
+ else if(MESSAGE_GROUP_DEFAULT_GROUP.equals(name))
+ {
+ // TODO
+ }
+ else if(MESSAGE_GROUP_SHARED_GROUPS.equals(name))
+ {
+ // TODO
+ }
+ else if(LVQ_KEY.equals(name))
+ {
+ if(_queue instanceof ConflationQueue)
+ {
+ return ((ConflationQueue)_queue).getConflationKey();
+ }
+ }
+ else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
+ {
+ return _queue.getMaximumDeliveryCount();
+ }
+ else if(NO_LOCAL.equals(name))
+ {
+ // TODO
+ }
+ else if(OWNER.equals(name))
+ {
+ return _queue.getOwner() == null ? null : _queue.getOwner().asString();
+ }
+ else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name))
+ {
+ return _queue.getCapacity();
+ }
+ else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name))
+ {
+ return _queue.getFlowResumeCapacity();
+ }
+ else if(QUEUE_FLOW_STOPPED.equals(name))
+ {
+ return _queue.isOverfull();
+ }
+ else if(SORT_KEY.equals(name))
+ {
+ if(_queue instanceof SortedQueue)
+ {
+ return ((SortedQueue)_queue).getSortedPropertyName();
+ }
+ }
+ else if(TYPE.equals(name))
+ {
+ if(_queue instanceof SortedQueue)
+ {
+ return "sorted";
+ }
+ if(_queue instanceof ConflationQueue)
+ {
+ return "lvq";
+ }
+ if(_queue instanceof AMQPriorityQueue)
+ {
+ return "priority";
+ }
+ return "standard";
+ }
+ else if(CREATED.equals(name))
+ {
+ // TODO
+ }
+ else if(DURABLE.equals(name))
+ {
+ return _queue.isDurable();
+ }
+ else if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return _queue.isAutoDelete() ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT;
+ }
+ else if(NAME.equals(name))
+ {
+ return _queue.getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return State.ACTIVE; // TODO
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ // TODO
+ }
+ else if(UPDATED.equals(name))
+ {
+ // TODO
+ }
+ else if (DESCRIPTION.equals(name))
+ {
+ return _queue.getDescription();
+ }
+
+ return super.getAttribute(name);
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Consumer.class)
+ {
+ return (Collection<C>) getConsumers();
+ }
+ else if(clazz == org.apache.qpid.server.model.Binding.class)
+ {
+ return (Collection<C>) getBindings();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ public org.apache.qpid.server.model.Binding createBinding(Exchange exchange, Map<String, Object> attributes)
+ throws AccessControlException, IllegalStateException
+ {
+ attributes = new HashMap<String, Object>(attributes);
+ String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, "");
+ Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP);
+
+ attributes.remove(org.apache.qpid.server.model.Binding.NAME);
+ attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS);
+
+ return exchange.createBinding(bindingKey, this, bindingArgs, attributes);
+
+ }
+
+
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if(childClass == org.apache.qpid.server.model.Binding.class)
+ {
+ if(otherParents != null && otherParents.length == 1 && otherParents[0] instanceof Exchange)
+ {
+ Exchange exchange = (Exchange) otherParents[0];
+ if(exchange.getParent(org.apache.qpid.server.model.VirtualHost.class) == getParent(org.apache.qpid.server.model.VirtualHost.class))
+ {
+ return (C) createBinding(exchange, attributes);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Queue and Exchange parents of a binding must be on same virtual host");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("Other parent must be an exchange");
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ void bindingRegistered(Binding binding, BindingAdapter adapter)
+ {
+ synchronized (_bindingAdapters)
+ {
+ _bindingAdapters.put(binding, adapter);
+ }
+ childAdded(adapter);
+ }
+
+ void bindingUnregistered(Binding binding)
+ {
+ BindingAdapter adapter = null;
+ synchronized (_bindingAdapters)
+ {
+ adapter = _bindingAdapters.remove(binding);
+ }
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ AMQQueue getAMQQueue()
+ {
+ return _queue;
+ }
+
+ public void subscriptionRegistered(final AMQQueue queue, final Subscription subscription)
+ {
+ ConsumerAdapter adapter = null;
+ synchronized (_consumerAdapters)
+ {
+ if(!_consumerAdapters.containsKey(subscription))
+ {
+ adapter = new ConsumerAdapter(this, subscription);
+ _consumerAdapters.put(subscription,adapter);
+ // TODO - register with session
+ }
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+ }
+
+ public void subscriptionUnregistered(final AMQQueue queue, final Subscription subscription)
+ {
+ ConsumerAdapter adapter = null;
+
+ synchronized (_consumerAdapters)
+ {
+ adapter = _consumerAdapters.remove(subscription);
+ // TODO - register with session
+ }
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ VirtualHostAdapter getVirtualHost()
+ {
+ return _vhost;
+ }
+
+
+ private static class QueueStatisticsAdapter implements Statistics
+ {
+
+ private final AMQQueue _queue;
+
+ public QueueStatisticsAdapter(AMQQueue queue)
+ {
+ _queue = queue;
+ }
+
+ public Collection<String> getStatisticNames()
+ {
+ return Queue.AVAILABLE_STATISTICS;
+ }
+
+ public Object getStatistic(String name)
+ {
+ if(BINDING_COUNT.equals(name))
+ {
+ return _queue.getBindingCount();
+ }
+ else if(CONSUMER_COUNT.equals(name))
+ {
+ return _queue.getConsumerCount();
+ }
+ else if(CONSUMER_COUNT_WITH_CREDIT.equals(name))
+ {
+ return _queue.getActiveConsumerCount();
+ }
+ else if(DISCARDS_TTL_BYTES.equals(name))
+ {
+ return null; // TODO
+ }
+ else if(DISCARDS_TTL_MESSAGES.equals(name))
+ {
+ return null; // TODO
+ }
+ else if(PERSISTENT_DEQUEUED_BYTES.equals(name))
+ {
+ return _queue.getPersistentByteDequeues();
+ }
+ else if(PERSISTENT_DEQUEUED_MESSAGES.equals(name))
+ {
+ return _queue.getPersistentMsgDequeues();
+ }
+ else if(PERSISTENT_ENQUEUED_BYTES.equals(name))
+ {
+ return _queue.getPersistentByteEnqueues();
+ }
+ else if(PERSISTENT_ENQUEUED_MESSAGES.equals(name))
+ {
+ return _queue.getPersistentMsgEnqueues();
+ }
+ else if(QUEUE_DEPTH_BYTES.equals(name))
+ {
+ return _queue.getQueueDepth();
+ }
+ else if(QUEUE_DEPTH_MESSAGES.equals(name))
+ {
+ return _queue.getMessageCount();
+ }
+ else if(STATE_CHANGED.equals(name))
+ {
+ return null; // TODO
+ }
+ else if(TOTAL_DEQUEUED_BYTES.equals(name))
+ {
+ return _queue.getTotalDequeueSize();
+ }
+ else if(TOTAL_DEQUEUED_MESSAGES.equals(name))
+ {
+ return _queue.getTotalDequeueCount();
+ }
+ else if(TOTAL_ENQUEUED_BYTES.equals(name))
+ {
+ return _queue.getTotalEnqueueSize();
+ }
+ else if(TOTAL_ENQUEUED_MESSAGES.equals(name))
+ {
+ return _queue.getTotalEnqueueCount();
+ }
+ else if(UNACKNOWLEDGED_BYTES.equals(name))
+ {
+ return _queue.getUnackedMessageBytes();
+ }
+ else if(UNACKNOWLEDGED_MESSAGES.equals(name))
+ {
+ return _queue.getUnackedMessageCount();
+ }
+
+ return null;
+ }
+ }
+
+ @Override
+ public void setNotificationListener(QueueNotificationListener listener)
+ {
+ _queueNotificationListener = listener;
+ }
+
+ @Override
+ public void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg)
+ {
+ QueueNotificationListener listener = _queueNotificationListener;
+ if(listener != null)
+ {
+ listener.notifyClients(notification, this, notificationMsg);
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java
new file mode 100644
index 0000000000..25d9c6feb1
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java
@@ -0,0 +1,239 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+
+import java.util.Map;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Publisher;
+import org.apache.qpid.server.model.Session;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.Consumer;
+import org.apache.qpid.server.protocol.AMQSessionModel;
+
+final class SessionAdapter extends AbstractAdapter implements Session
+{
+ // Attributes
+
+
+ private AMQSessionModel _session;
+ private SessionStatistics _statistics;
+
+ public SessionAdapter(final AMQSessionModel session)
+ {
+ _session = session;
+ _statistics = new SessionStatistics();
+ }
+
+ public Collection<Consumer> getSubscriptions()
+ {
+ return null; //TODO
+ }
+
+ public Collection<Publisher> getPublishers()
+ {
+ return null; //TODO
+ }
+
+ public String getName()
+ {
+ return String.valueOf(_session.getChannelId());
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null; //TODO
+ }
+
+ public State getActualState()
+ {
+ return null; //TODO
+ }
+
+ public boolean isDurable()
+ {
+ return false; //TODO
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ //TODO
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return null; //TODO
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return null; //TODO
+ }
+
+ public long getTimeToLive()
+ {
+ return 0; //TODO
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return 0; //TODO
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ Collection<String> names = new HashSet<String>(super.getAttributeNames());
+ names.addAll(AVAILABLE_ATTRIBUTES);
+
+ return Collections.unmodifiableCollection(names);
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(name.equals(ID))
+ {
+ return getId();
+ }
+ else if (name.equals(NAME))
+ {
+ return getName();
+ }
+ else if(name.equals(CHANNEL_ID))
+ {
+ return _session.getChannelId();
+ }
+ else if(name.equals(PRODUCER_FLOW_BLOCKED))
+ {
+ return _session.getBlocking();
+ }
+ return super.getAttribute(name); //TODO - Implement
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Consumer.class)
+ {
+ return (Collection<C>) getSubscriptions();
+ }
+ else if(clazz == Publisher.class)
+ {
+ return (Collection<C>) getPublishers();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private class SessionStatistics implements Statistics
+ {
+
+ public SessionStatistics()
+ {
+ }
+
+ public Collection<String> getStatisticNames()
+ {
+ return AVAILABLE_STATISTICS;
+ }
+
+ public Object getStatistic(String name)
+ {
+ if(name.equals(BYTES_IN))
+ {
+ }
+ else if(name.equals(BYTES_OUT))
+ {
+ }
+ else if(name.equals(CONSUMER_COUNT))
+ {
+ final Collection<Consumer> subscriptions = getSubscriptions();
+ return subscriptions == null ? 0 : subscriptions.size();
+ }
+ else if(name.equals(LOCAL_TRANSACTION_BEGINS))
+ {
+ return _session.getTxnStart();
+ }
+ else if(name.equals(LOCAL_TRANSACTION_OPEN))
+ {
+ long open = _session.getTxnCount() - (_session.getTxnCommits() + _session.getTxnRejects());
+ return (Boolean) (open > 0l);
+ }
+ else if(name.equals(LOCAL_TRANSACTION_ROLLBACKS))
+ {
+ return _session.getTxnCommits();
+ }
+ else if(name.equals(STATE_CHANGED))
+ {
+ }
+ else if(name.equals(UNACKNOWLEDGED_BYTES))
+ {
+ }
+ else if(name.equals(UNACKNOWLEDGED_MESSAGES))
+ {
+ return _session.getUnacknowledgedMessageCount();
+ }
+ else if(name.equals(XA_TRANSACTION_BRANCH_ENDS))
+ {
+ }
+ else if(name.equals(XA_TRANSACTION_BRANCH_STARTS))
+ {
+ }
+ else if(name.equals(XA_TRANSACTION_BRANCH_SUSPENDS))
+ {
+
+ }
+
+ return null; // TODO - Implement
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java
new file mode 100644
index 0000000000..f98e46c911
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java
@@ -0,0 +1,67 @@
+package org.apache.qpid.server.model.adapter;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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
+* <p/>
+* http://www.apache.org/licenses/LICENSE-2.0
+* <p/>
+* 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.
+*/
+class StatisticsAdapter implements Statistics
+{
+
+ private final Map<String, StatisticsCounter> _statistics =
+ new HashMap<String, StatisticsCounter>();
+
+
+ private static final String BYTES_IN = "bytesIn";
+ private static final String BYTES_OUT = "bytesOut";
+ private static final String MESSAGES_IN = "messagesIn";
+ private static final String MESSAGES_OUT = "messagesOut";
+
+ private static final Collection<String> STATISTIC_NAMES =
+ Collections.unmodifiableCollection(Arrays.asList(BYTES_IN, BYTES_OUT, MESSAGES_IN, MESSAGES_OUT));
+
+
+
+ public StatisticsAdapter(StatisticsGatherer statGatherer)
+ {
+ _statistics.put(BYTES_OUT, statGatherer.getDataDeliveryStatistics());
+ _statistics.put(BYTES_IN, statGatherer.getDataReceiptStatistics());
+ _statistics.put(MESSAGES_OUT, statGatherer.getMessageDeliveryStatistics());
+ _statistics.put(MESSAGES_IN, statGatherer.getMessageReceiptStatistics());
+ }
+
+
+ public Collection<String> getStatisticNames()
+ {
+ return STATISTIC_NAMES;
+ }
+
+ public Object getStatistic(String name)
+ {
+ StatisticsCounter counter = _statistics.get(name);
+ return counter == null ? null : counter.getTotal();
+
+ }
+
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
new file mode 100644
index 0000000000..204054c8cb
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
@@ -0,0 +1,844 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.connection.IConnectionRegistry;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeType;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostAlias;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.txn.LocalTransaction;
+import org.apache.qpid.server.txn.ServerTransaction;
+
+final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener,
+ QueueRegistry.RegistryChangeListener,
+ IConnectionRegistry.RegistryChangeListener
+{
+
+ private final org.apache.qpid.server.virtualhost.VirtualHost _virtualHost;
+
+ private final Map<AMQConnectionModel, ConnectionAdapter> _connectionAdapters =
+ new HashMap<AMQConnectionModel, ConnectionAdapter>();
+
+ private final Map<AMQQueue, QueueAdapter> _queueAdapters =
+ new HashMap<AMQQueue, QueueAdapter>();
+
+ private final Map<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter> _exchangeAdapters =
+ new HashMap<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter>();
+
+ private final StatisticsAdapter _statistics;
+
+ private final BrokerAdapter _broker;
+
+ private final List<VirtualHostAlias> _aliases = new ArrayList<VirtualHostAlias>();
+
+
+ VirtualHostAdapter(BrokerAdapter brokerAdapter,
+ final org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ {
+ super(virtualHost.getName());
+ _broker = brokerAdapter;
+ _virtualHost = virtualHost;
+ _statistics = new VirtualHostStatisticsAdapter(virtualHost);
+ virtualHost.getQueueRegistry().addRegistryChangeListener(this);
+ populateQueues();
+ virtualHost.getExchangeRegistry().addRegistryChangeListener(this);
+ populateExchanges();
+ virtualHost.getConnectionRegistry().addRegistryChangeListener(this);
+ populateConnections();
+
+
+
+ for(Port port :_broker.getPorts())
+ {
+ _aliases.add(new VirtualHostAliasAdapter(this, port));
+ }
+ }
+
+
+ private void populateExchanges()
+ {
+ Collection<org.apache.qpid.server.exchange.Exchange> actualExchanges =
+ _virtualHost.getExchangeRegistry().getExchanges();
+
+ synchronized (_exchangeAdapters)
+ {
+ for(org.apache.qpid.server.exchange.Exchange exchange : actualExchanges)
+ {
+ if(!_exchangeAdapters.containsKey(exchange))
+ {
+ _exchangeAdapters.put(exchange, new ExchangeAdapter(this,exchange));
+ }
+ }
+ }
+ }
+
+
+ private void populateQueues()
+ {
+ Collection<AMQQueue> actualQueues = _virtualHost.getQueueRegistry().getQueues();
+
+ synchronized(_queueAdapters)
+ {
+ for(AMQQueue queue : actualQueues)
+ {
+ if(!_queueAdapters.containsKey(queue))
+ {
+ _queueAdapters.put(queue, new QueueAdapter(this,queue));
+ }
+ }
+ }
+ }
+
+ private void populateConnections()
+ {
+
+ List<AMQConnectionModel> actualConnections = _virtualHost.getConnectionRegistry().getConnections();
+
+ synchronized(_connectionAdapters)
+ {
+ for(AMQConnectionModel conn : actualConnections)
+ {
+ if(!_connectionAdapters.containsKey(conn))
+ {
+ _connectionAdapters.put(conn, new ConnectionAdapter(conn));
+ }
+ }
+ }
+
+ }
+
+ public String getReplicationGroupName()
+ {
+ return null; //TODO
+ }
+
+ public Collection<VirtualHostAlias> getAliases()
+ {
+ return Collections.unmodifiableCollection(_aliases);
+ }
+
+ public Collection<Connection> getConnections()
+ {
+ synchronized(_connectionAdapters)
+ {
+ return new ArrayList<Connection>(_connectionAdapters.values());
+ }
+
+ }
+
+ public Collection<Queue> getQueues()
+ {
+ synchronized(_queueAdapters)
+ {
+ return new ArrayList<Queue>(_queueAdapters.values());
+ }
+ }
+
+ public Collection<Exchange> getExchanges()
+ {
+ synchronized (_exchangeAdapters)
+ {
+ return new ArrayList<Exchange>(_exchangeAdapters.values());
+ }
+ }
+
+
+ public Exchange createExchange(Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ attributes = new HashMap<String, Object>(attributes);
+
+ String name = getStringAttribute(Exchange.NAME, attributes, null);
+ State state = getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE);
+ boolean durable = getBooleanAttribute(Exchange.DURABLE, attributes, false);
+ LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT);
+ String type = getStringAttribute(Exchange.TYPE, attributes, null);
+ long ttl = getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l);
+
+ attributes.remove(Exchange.NAME);
+ attributes.remove(Exchange.STATE);
+ attributes.remove(Exchange.DURABLE);
+ attributes.remove(Exchange.LIFETIME_POLICY);
+ attributes.remove(Exchange.TYPE);
+ attributes.remove(Exchange.TIME_TO_LIVE);
+
+ return createExchange(name, state, durable, lifetime, ttl, type, attributes);
+ }
+
+
+ public Exchange createExchange(final String name,
+ final State initialState,
+ final boolean durable,
+ final LifetimePolicy lifetime,
+ final long ttl,
+ final String type,
+ final Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ try
+ {
+ org.apache.qpid.server.exchange.Exchange exchange =
+ _virtualHost.getExchangeFactory().createExchange(name, type, durable,
+ lifetime == LifetimePolicy.AUTO_DELETE);
+ _virtualHost.getExchangeRegistry().registerExchange(exchange);
+ if(durable)
+ {
+ _virtualHost.getMessageStore().createExchange(exchange);
+ }
+
+ synchronized (_exchangeAdapters)
+ {
+ return _exchangeAdapters.get(exchange);
+ }
+ }
+ catch(AMQException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public Queue createQueue(Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ attributes = new HashMap<String, Object>(attributes);
+
+ String name = getStringAttribute(Queue.NAME, attributes, null);
+ State state = getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE);
+ boolean durable = getBooleanAttribute(Queue.DURABLE, attributes, false);
+ LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT);
+ long ttl = getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l);
+ boolean exclusive= getBooleanAttribute(Queue.EXCLUSIVE, attributes, false);
+
+ attributes.remove(Queue.NAME);
+ attributes.remove(Queue.STATE);
+ attributes.remove(Queue.DURABLE);
+ attributes.remove(Queue.LIFETIME_POLICY);
+ attributes.remove(Queue.TIME_TO_LIVE);
+
+ List<String> attrNames = new ArrayList<String>(attributes.keySet());
+ for(String attr : attrNames)
+ {
+ if(QueueAdapter.ATTRIBUTE_MAPPINGS.containsKey(attr))
+ {
+ attributes.put(QueueAdapter.ATTRIBUTE_MAPPINGS.get(attr),attributes.remove(attr));
+ }
+ }
+
+ return createQueue(name, state, durable, exclusive, lifetime, ttl, attributes);
+ }
+
+ public Queue createQueue(final String name,
+ final State initialState,
+ final boolean durable,
+ boolean exclusive,
+ final LifetimePolicy lifetime,
+ final long ttl,
+ final Map<String, Object> attributes)
+ throws AccessControlException, IllegalArgumentException
+ {
+ String owner = null;
+ if(exclusive)
+ {
+ Set<Principal> principals =
+ SecurityManager.getThreadSubject().getPrincipals();
+ if(principals != null && !principals.isEmpty())
+ {
+ owner = principals.iterator().next().getName();
+ }
+ }
+ try
+ {
+ if(_virtualHost.getQueueRegistry().getQueue(name)!=null)
+ {
+ throw new IllegalArgumentException("Queue with name "+name+" already exists");
+ }
+ AMQQueue queue =
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateUUID(name, _virtualHost.getName()), name,
+ durable, owner, lifetime == LifetimePolicy.AUTO_DELETE,
+ exclusive, _virtualHost, attributes);
+ _virtualHost.getBindingFactory().addBinding(name, queue, _virtualHost.getExchangeRegistry().getDefaultExchange(), null);
+
+ if(durable)
+ {
+ _virtualHost.getMessageStore().createQueue(queue, FieldTable.convertToFieldTable(attributes));
+ }
+ synchronized (_queueAdapters)
+ {
+ return _queueAdapters.get(queue);
+ }
+
+ }
+ catch(AMQException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+
+ }
+
+ public String getName()
+ {
+ return _virtualHost.getName();
+ }
+
+ public String setName(final String currentName, final String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException();
+ }
+
+ public State getActualState()
+ {
+ return getDesiredState();
+ }
+
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ public void setDurable(final boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ public LifetimePolicy setLifetimePolicy(final LifetimePolicy expected, final LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ public long setTimeToLive(final long expected, final long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ public Statistics getStatistics()
+ {
+ return _statistics;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if(clazz == Exchange.class)
+ {
+ return (Collection<C>) getExchanges();
+ }
+ else if(clazz == Queue.class)
+ {
+ return (Collection<C>) getQueues();
+ }
+ else if(clazz == Connection.class)
+ {
+ return (Collection<C>) getConnections();
+ }
+ else if(clazz == VirtualHostAlias.class)
+ {
+ return (Collection<C>) getAliases();
+ }
+ else
+ {
+ return Collections.emptySet();
+ }
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if(childClass == Exchange.class)
+ {
+ return (C) createExchange(attributes);
+ }
+ else if(childClass == Queue.class)
+ {
+ return (C) createQueue(attributes);
+ }
+ else if(childClass == VirtualHostAlias.class)
+ {
+ throw new UnsupportedOperationException();
+ }
+ else if(childClass == Connection.class)
+ {
+ throw new UnsupportedOperationException();
+ }
+ throw new IllegalArgumentException("Cannot create a child of class " + childClass.getSimpleName());
+ }
+
+ public void exchangeRegistered(org.apache.qpid.server.exchange.Exchange exchange)
+ {
+ ExchangeAdapter adapter = null;
+ synchronized (_exchangeAdapters)
+ {
+ if(!_exchangeAdapters.containsKey(exchange))
+ {
+ adapter = new ExchangeAdapter(this, exchange);
+ _exchangeAdapters.put(exchange, adapter);
+
+ }
+
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+
+ }
+
+
+ public void exchangeUnregistered(org.apache.qpid.server.exchange.Exchange exchange)
+ {
+ ExchangeAdapter adapter;
+ synchronized (_exchangeAdapters)
+ {
+ adapter = _exchangeAdapters.remove(exchange);
+
+ }
+
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ public void queueRegistered(AMQQueue queue)
+ {
+ QueueAdapter adapter = null;
+ synchronized (_queueAdapters)
+ {
+ if(!_queueAdapters.containsKey(queue))
+ {
+ adapter = new QueueAdapter(this, queue);
+ _queueAdapters.put(queue, adapter);
+
+ }
+
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+
+ }
+
+ public void queueUnregistered(AMQQueue queue)
+ {
+
+ QueueAdapter adapter;
+ synchronized (_queueAdapters)
+ {
+ adapter = _queueAdapters.remove(queue);
+
+ }
+
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ public void connectionRegistered(AMQConnectionModel connection)
+ {
+ ConnectionAdapter adapter = null;
+ synchronized (_connectionAdapters)
+ {
+ if(!_connectionAdapters.containsKey(connection))
+ {
+ adapter = new ConnectionAdapter(connection);
+ _connectionAdapters.put(connection, adapter);
+
+ }
+
+ }
+ if(adapter != null)
+ {
+ childAdded(adapter);
+ }
+ }
+
+ public void connectionUnregistered(AMQConnectionModel connection)
+ {
+
+ ConnectionAdapter adapter;
+ synchronized (_connectionAdapters)
+ {
+ adapter = _connectionAdapters.remove(connection);
+
+ }
+
+ if(adapter != null)
+ {
+ childRemoved(adapter);
+ }
+ }
+
+ QueueAdapter getQueueAdapter(AMQQueue queue)
+ {
+ synchronized (_queueAdapters)
+ {
+ return _queueAdapters.get(queue);
+ }
+ }
+
+ public void deleteQueue(Queue queue)
+ throws AccessControlException, IllegalStateException
+ {
+ // TODO
+ throw new UnsupportedOperationException("Not Yet Implemented");
+ }
+
+ public Collection<String> getExchangeTypes()
+ {
+ Collection<ExchangeType<? extends org.apache.qpid.server.exchange.Exchange>> types =
+ _virtualHost.getExchangeFactory().getRegisteredTypes();
+
+ Collection<String> exchangeTypes = new ArrayList<String>();
+
+ for(ExchangeType<? extends org.apache.qpid.server.exchange.Exchange> type : types)
+ {
+ exchangeTypes.add(type.getName().asString());
+ }
+ return Collections.unmodifiableCollection(exchangeTypes);
+ }
+
+ public void executeTransaction(TransactionalOperation op)
+ {
+ MessageStore store = _virtualHost.getMessageStore();
+ final LocalTransaction txn = new LocalTransaction(store);
+
+ op.withinTransaction(new Transaction()
+ {
+ public void dequeue(final QueueEntry entry)
+ {
+ if(entry.acquire())
+ {
+ txn.dequeue(entry.getQueue(), entry.getMessage(), new ServerTransaction.Action()
+ {
+ public void postCommit()
+ {
+ entry.discard();
+ }
+
+ public void onRollback()
+ {
+ }
+ });
+ }
+ }
+
+ public void copy(QueueEntry entry, Queue queue)
+ {
+ final ServerMessage message = entry.getMessage();
+ final AMQQueue toQueue = ((QueueAdapter)queue).getAMQQueue();
+
+ txn.enqueue(toQueue, message, new ServerTransaction.Action()
+ {
+ public void postCommit()
+ {
+ try
+ {
+ toQueue.enqueue(message);
+ }
+ catch(AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void onRollback()
+ {
+ }
+ });
+
+ }
+
+ public void move(final QueueEntry entry, Queue queue)
+ {
+ final ServerMessage message = entry.getMessage();
+ final AMQQueue toQueue = ((QueueAdapter)queue).getAMQQueue();
+ if(entry.acquire())
+ {
+ txn.enqueue(toQueue, message,
+ new ServerTransaction.Action()
+ {
+
+ public void postCommit()
+ {
+ try
+ {
+ toQueue.enqueue(message);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void onRollback()
+ {
+ entry.release();
+ }
+ });
+ txn.dequeue(entry.getQueue(), message,
+ new ServerTransaction.Action()
+ {
+
+ public void postCommit()
+ {
+ entry.discard();
+ }
+
+ public void onRollback()
+ {
+
+ }
+ });
+ }
+ }
+
+ });
+ txn.commit();
+ }
+
+ org.apache.qpid.server.virtualhost.VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(ID.equals(name))
+ {
+ return getId();
+ }
+ else if(NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(STATE.equals(name))
+ {
+ return State.ACTIVE;
+ }
+ else if(DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(LIFETIME_POLICY.equals(name))
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+ else if(TIME_TO_LIVE.equals(name))
+ {
+ // TODO
+ }
+ else if(CREATED.equals(name))
+ {
+ // TODO
+ }
+ else if(UPDATED.equals(name))
+ {
+ // TODO
+ }
+ else if(SUPPORTED_EXCHANGE_TYPES.equals(name))
+ {
+ List<String> types = new ArrayList<String>();
+ for(ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes())
+ {
+ types.add(type.getName().asString());
+ }
+ return Collections.unmodifiableCollection(types);
+ }
+ else if(SUPPORTED_QUEUE_TYPES.equals(name))
+ {
+ // TODO
+ }
+ else if(DEAD_LETTER_QUEUE_ENABLED.equals(name))
+ {
+ return _virtualHost.getConfiguration().isDeadLetterQueueEnabled();
+ }
+ else if(FEDERATION_TAG.equals(name))
+ {
+ return _virtualHost.getFederationTag();
+ }
+ else if(HOUSEKEEPING_CHECK_PERIOD.equals(name))
+ {
+ return _virtualHost.getConfiguration().getHousekeepingCheckPeriod();
+ }
+ else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMaxDeliveryCount();
+ }
+ else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name))
+ {
+ return _virtualHost.getConfiguration().getCapacity();
+ }
+ else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name))
+ {
+ return _virtualHost.getConfiguration().getFlowResumeCapacity();
+ }
+ else if(STORE_TYPE.equals(name))
+ {
+ return _virtualHost.getMessageStore().getStoreType();
+ }
+ else if(STORE_CONFIGURATION.equals(name))
+ {
+ // TODO
+ }
+ else if(STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE.equals(name))
+ {
+ return _virtualHost.getConfiguration().getTransactionTimeoutIdleClose();
+ }
+ else if(STORE_TRANSACTION_IDLE_TIMEOUT_WARN.equals(name))
+ {
+ return _virtualHost.getConfiguration().getTransactionTimeoutIdleWarn();
+ }
+ else if(STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE.equals(name))
+ {
+ return _virtualHost.getConfiguration().getTransactionTimeoutOpenClose();
+ }
+ else if(STORE_TRANSACTION_OPEN_TIMEOUT_WARN.equals(name))
+ {
+ return _virtualHost.getConfiguration().getTransactionTimeoutOpenWarn();
+ }
+ else if(ALERT_REPEAT_GAP.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMinimumAlertRepeatGap();
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMaximumMessageAge();
+ }
+ else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMaximumMessageSize();
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMaximumQueueDepth();
+ }
+ else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name))
+ {
+ return _virtualHost.getConfiguration().getMaximumMessageCount();
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public Object setAttribute(String name, Object expected, Object desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ return super.setAttribute(name, expected, desired); //TODO - Implement
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ private static class VirtualHostStatisticsAdapter extends StatisticsAdapter
+ {
+ private final org.apache.qpid.server.virtualhost.VirtualHost _vhost;
+
+ private static final Collection<String> VHOST_STATS = Arrays.asList(
+ VirtualHost.QUEUE_COUNT,
+ VirtualHost.EXCHANGE_COUNT,
+ VirtualHost.CONNECTION_COUNT);
+
+ public VirtualHostStatisticsAdapter(org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ {
+ super(virtualHost);
+ _vhost = virtualHost;
+ }
+
+ @Override
+ public Collection<String> getStatisticNames()
+ {
+ Set<String> stats = new HashSet<String>(super.getStatisticNames());
+ stats.addAll(VHOST_STATS);
+ return stats;
+ }
+
+ @Override
+ public Object getStatistic(String name)
+ {
+ if(VirtualHost.QUEUE_COUNT.equals(name))
+ {
+ return _vhost.getQueueRegistry().getQueues().size();
+ }
+ else if(VirtualHost.EXCHANGE_COUNT.equals(name))
+ {
+ return _vhost.getExchangeRegistry().getExchanges().size();
+ }
+ else if(VirtualHost.CONNECTION_COUNT.equals(name))
+ {
+ return _vhost.getConnectionRegistry().getConnections().size();
+ }
+ else
+ {
+ return super.getStatistic(name);
+ }
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java
new file mode 100644
index 0000000000..22ea2e612b
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java
@@ -0,0 +1,142 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.model.adapter;
+
+import java.util.Map;
+import org.apache.qpid.server.model.AuthenticationMethod;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostAlias;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+
+public class VirtualHostAliasAdapter extends AbstractAdapter implements VirtualHostAlias
+{
+ private VirtualHostAdapter _vhost;
+ private Port _port;
+
+ public VirtualHostAliasAdapter(VirtualHostAdapter virtualHostAdapter, Port port)
+ {
+ super(virtualHostAdapter.getName(), port.getName());
+ _vhost = virtualHostAdapter;
+ _port = port;
+ }
+
+ @Override
+ public Port getPort()
+ {
+ return _port;
+ }
+
+ @Override
+ public VirtualHost getVirtualHost()
+ {
+ return _vhost;
+ }
+
+ @Override
+ public Collection<AuthenticationMethod> getAuthenticationMethods()
+ {
+ return Collections.emptySet(); // TODO - Implement
+ }
+
+ @Override
+ public String getName()
+ {
+ return _vhost.getName();
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return State.ACTIVE; // TODO - Implement
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true; // TODO - Implement
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT; // TODO - Implement
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0; // TODO - Implement
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired)
+ throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException(); // TODO - Implement
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return NoStatistics.getInstance();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
index badeffca05..4677d4b9e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
@@ -31,12 +31,24 @@
javax.management.openmbean=1.0.0
javax.management=1.0.0
+javax.management.remote.rmi=1.0.0
+javax.management.remote=1.0.0
+javax.management.monitor=1.0.0
+
+javax.crypto=1
+javax.crypto.spec=1
+
+javax.servlet=2
+javax.servlet.http=2
javax.security.auth=1.0.0
javax.security.auth.callback=1.0.0
+javax.security.auth.login=1.0.0
javax.security.sasl=1.0.0
javax.security=1.0.0
+javax.rmi.ssl=1.0.0
+
org.xml.sax=1.0.0
org.xml.sax.helpers=1.0.0
@@ -46,37 +58,57 @@ org.osgi.service.startlevel=1.0.0
org.osgi.service.url=1.0.0
org.osgi.util.tracker=1.0.0
+org.apache.commons.codec=1.3.0
+org.apache.commons.codec.binary=1.3.0
+
org.apache.commons.configuration=1.0.0
org.apache.commons.lang=1.0.0
org.apache.commons.lang.builder=1.0.0
+org.apache.commons.lang.time=1.0.0
org.apache.commons.logging=1.0.0
-org.apache.log4j=1.2.12
+org.apache.log4j=1.2.16
org.slf4j=1.6.1
+org.eclipse.jetty=7.6.3
+org.eclipse.jetty.http=7.6.3
+org.eclipse.jetty.io=7.6.3
+org.eclipse.jetty.io.nio=7.6.3
+org.eclipse.jetty.security=7.6.3
+org.eclipse.jetty.server=7.6.3
+org.eclipse.jetty.server.session=7.6.3
+org.eclipse.jetty.servlet=7.6.3
+
+org.codehaus.jackson=1.9.0
+org.codehaus.jackson.map=1.9.0
+
# For Qpid packages (org.apache.qpid), the version number is automatically overridden by QpidPropertis#getReleaseVersion()
-org.apache.qpid.junit.extensions.util=0.0.0
org.apache.qpid=0.0.0
org.apache.qpid.common=0.0.0
org.apache.qpid.exchange=0.0.0
org.apache.qpid.framing=0.0.0
org.apache.qpid.management.common.mbeans.annotations=0.0.0
+org.apache.qpid.management.common.mbeans=0.0.0
org.apache.qpid.protocol=0.0.0
org.apache.qpid.transport=0.0.0
org.apache.qpid.transport.codec=0.0.0
org.apache.qpid.server.binding=0.0.0
+org.apache.qpid.server.model=0.0.0
+org.apache.qpid.server.model.adapter=0.0.0
+org.apache.qpid.server.model.impl=0.0.0
org.apache.qpid.server.configuration=0.0.0
org.apache.qpid.server.configuration.plugins=0.0.0
org.apache.qpid.server.configuration.management=0.0.0
+org.apache.qpid.server.connection=0.0.0
org.apache.qpid.server.exchange=0.0.0
org.apache.qpid.server.logging=0.0.0
org.apache.qpid.server.logging.actors=0.0.0
+org.apache.qpid.server.logging.messages=0.0.0
org.apache.qpid.server.logging.subjects=0.0.0
org.apache.qpid.server.message=0.0.0
-org.apache.qpid.server.management=0.0.0
org.apache.qpid.server.persistent=0.0.0
org.apache.qpid.server.plugins=0.0.0
org.apache.qpid.server.protocol=0.0.0
@@ -88,7 +120,10 @@ org.apache.qpid.server.security.access.plugins=0.0.0
org.apache.qpid.server.security.auth=0.0.0
org.apache.qpid.server.security.auth.sasl=0.0.0
org.apache.qpid.server.security.auth.manager=0.0.0
+org.apache.qpid.server.security.auth.rmi=0.0.0
+org.apache.qpid.server.stats=0.0.0
org.apache.qpid.server.virtualhost=0.0.0
org.apache.qpid.server.virtualhost.plugins=0.0.0
org.apache.qpid.util=0.0.0
+org.apache.qpid.server.store.berkeleydb=0.0.0
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
index b7fd2387a5..69ba7279bc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
@@ -77,4 +77,16 @@ public interface AMQConnectionModel extends StatisticsGatherer
public String getUserName();
public boolean isSessionNameUnique(byte[] name);
+
+ String getRemoteAddressString();
+
+ String getClientId();
+
+ String getClientVersion();
+
+ String getPrincipalAsString();
+
+ long getSessionCountLimit();
+
+ long getLastIoTime();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index 5db336649f..850e293c3b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -34,7 +34,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.management.JMException;
import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import org.apache.log4j.Logger;
@@ -62,8 +61,6 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.ManagementActor;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
import org.apache.qpid.server.logging.subjects.ConnectionLogSubject;
-import org.apache.qpid.server.management.Managable;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.output.ProtocolOutputConverterRegistry;
import org.apache.qpid.server.queue.QueueEntry;
@@ -81,7 +78,7 @@ import org.apache.qpid.transport.TransportException;
import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.util.BytesDataOutput;
-public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
+public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession, ConnectionConfig
{
private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class);
@@ -106,8 +103,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private AMQCodecFactory _codecFactory;
- private AMQProtocolSessionMBean _managedObject;
-
private SaslServer _saslServer;
private Object _lastReceived;
@@ -148,8 +143,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private final ConfigStore _configStore;
private long _createTime = System.currentTimeMillis();
- private ApplicationRegistry _registry;
- private boolean _statisticsEnabled = false;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private NetworkConnection _network;
@@ -159,11 +152,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private long _lastReceivedTime;
private boolean _blocking;
- public ManagedObject getManagedObject()
- {
- return _managedObject;
- }
-
public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network, final long connectionId)
{
_stateManager = new AMQStateManager(virtualHostRegistry, this);
@@ -181,8 +169,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false));
- _registry = virtualHostRegistry.getApplicationRegistry();
initialiseStatistics();
+
}
public void setNetworkConnection(NetworkConnection network)
@@ -196,11 +184,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_sender = sender;
}
- private AMQProtocolSessionMBean createMBean() throws JMException
- {
- return new AMQProtocolSessionMBean(this);
- }
-
public long getSessionID()
{
return _connectionID;
@@ -649,17 +632,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
{
_cachedChannels[channelId] = channel;
}
-
- checkForNotification();
- }
-
- private void checkForNotification()
- {
- int channelsCount = _channelMap.size();
- if (_managedObject != null && channelsCount >= _maxNoOfChannels)
- {
- _managedObject.notifyClients("Channel count (" + channelsCount + ") has reached the threshold value");
- }
}
public Long getMaximumNumberOfChannels()
@@ -811,13 +783,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
getConfigStore().removeConfiguredObject(this);
- if (_managedObject != null)
- {
- _managedObject.unregister();
- // Ensure we only do this once.
- _managedObject = null;
- }
-
for (Task task : _taskList)
{
task.doTask(this);
@@ -1004,16 +969,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_virtualHost.getConnectionRegistry().registerConnection(this);
_configStore.addConfiguredObject(this);
-
- try
- {
- _managedObject = createMBean();
- _managedObject.register();
- }
- catch (JMException e)
- {
- _logger.error(e);
- }
}
public void addSessionCloseTask(Task task)
@@ -1170,6 +1125,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
return _clientVersion;
}
+ public String getPrincipalAsString()
+ {
+ return getAuthId();
+ }
+
+ public long getSessionCountLimit()
+ {
+ return getMaximumNumberOfChannels();
+ }
+
public Boolean isIncoming()
{
return true;
@@ -1400,12 +1365,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
public List<AMQSessionModel> getSessionModels()
{
- List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
- for (AMQChannel channel : getChannels())
- {
- sessions.add((AMQSessionModel) channel);
- }
- return sessions;
+ return new ArrayList<AMQSessionModel>(getChannels());
}
public LogSubject getLogSubject()
@@ -1415,21 +1375,15 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
public void registerMessageDelivered(long messageSize)
{
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
+ _messagesDelivered.registerEvent(1L);
+ _dataDelivered.registerEvent(messageSize);
_virtualHost.registerMessageDelivered(messageSize);
}
public void registerMessageReceived(long messageSize, long timestamp)
{
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
+ _messagesReceived.registerEvent(1L, timestamp);
+ _dataReceived.registerEvent(messageSize, timestamp);
_virtualHost.registerMessageReceived(messageSize, timestamp);
}
@@ -1463,29 +1417,26 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
public void initialiseStatistics()
{
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _registry.getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
_messagesDelivered = new StatisticsCounter("messages-delivered-" + getSessionID());
_dataDelivered = new StatisticsCounter("data-delivered-" + getSessionID());
_messagesReceived = new StatisticsCounter("messages-received-" + getSessionID());
_dataReceived = new StatisticsCounter("data-received-" + getSessionID());
}
- public boolean isStatisticsEnabled()
+ public boolean isSessionNameUnique(byte[] name)
{
- return _statisticsEnabled;
+ // 0-8/0-9/0-9-1 sessions don't have names
+ return true;
}
- public void setStatisticsEnabled(boolean enabled)
+ public String getRemoteAddressString()
{
- _statisticsEnabled = enabled;
+ return String.valueOf(getRemoteAddress());
}
- public boolean isSessionNameUnique(byte[] name)
+ public String getClientId()
{
- // 0-8/0-9/0-9-1 sessions don't have names
- return true;
+ return String.valueOf(getContextKey());
}
public void setDeferFlush(boolean deferFlush)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
deleted file mode 100644
index e70720600e..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- *
- */
-/*
- *
- * 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.protocol;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ConnectionCloseBody;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AbstractAMQManagedConnectionObject;
-import org.apache.qpid.server.management.ManagedObject;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.util.Date;
-import java.util.List;
-
-/**
- * This MBean class implements the management interface. In order to make more attributes, operations and notifications
- * available over JMX simply augment the ManagedConnection interface and add the appropriate implementation here.
- */
-@MBeanDescription("Management Bean for an AMQ Broker 0-9-1/0-9/0-8 Connections")
-public class AMQProtocolSessionMBean extends AbstractAMQManagedConnectionObject
-{
- private AMQProtocolSession _protocolSession = null;
-
- private static final AMQShortString BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION =
- new AMQShortString(BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION_STR);
-
- @MBeanConstructor("Creates an MBean exposing an AMQ Broker 0-9-1/0-9/0-8 Connection")
- public AMQProtocolSessionMBean(AMQProtocolSession amqProtocolSession) throws NotCompliantMBeanException, OpenDataException
- {
- super(amqProtocolSession.getRemoteAddress().toString());
- _protocolSession = amqProtocolSession;
- }
-
- public String getClientId()
- {
- return String.valueOf(_protocolSession.getContextKey());
- }
-
- public String getAuthorizedId()
- {
- return (_protocolSession.getAuthorizedPrincipal() != null ) ? _protocolSession.getAuthorizedPrincipal().getName() : null;
- }
-
- public String getVersion()
- {
- return _protocolSession.getClientVersion();
- }
-
- public Date getLastIoTime()
- {
- return new Date(_protocolSession.getLastIoTime());
- }
-
- public String getRemoteAddress()
- {
- return _protocolSession.getRemoteAddress().toString();
- }
-
- public ManagedObject getParentObject()
- {
- return _protocolSession.getVirtualHost().getManagedObject();
- }
-
- public Long getWrittenBytes()
- {
- return _protocolSession.getWrittenBytes();
- }
-
- public Long getReadBytes()
- {
- return _protocolSession.getWrittenBytes();
- }
-
- public Long getMaximumNumberOfChannels()
- {
- return _protocolSession.getMaximumNumberOfChannels();
- }
-
- /**
- * commits transactions for a transactional channel
- *
- * @param channelId
- * @throws JMException if channel with given id doesn't exist or if commit fails
- */
- public void commitTransactions(int channelId) throws JMException
- {
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- AMQChannel channel = _protocolSession.getChannel(channelId);
- if (channel == null)
- {
- throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
- }
-
- _protocolSession.commitTransactions(channel);
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex, ex.toString());
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- /**
- * rollsback the transactions for a transactional channel
- *
- * @param channelId
- * @throws JMException if channel with given id doesn't exist or if rollback fails
- */
- public void rollbackTransactions(int channelId) throws JMException
- {
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- AMQChannel channel = _protocolSession.getChannel(channelId);
- if (channel == null)
- {
- throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
- }
-
- _protocolSession.rollbackTransactions(channel);
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex, ex.toString());
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- /**
- * Creates the list of channels in tabular form from the _channelMap.
- *
- * @return list of channels in tabular form.
- * @throws OpenDataException
- */
- public TabularData channels() throws OpenDataException
- {
- TabularDataSupport channelsList = new TabularDataSupport(_channelsType);
- List<AMQChannel> list = _protocolSession.getChannels();
-
- for (AMQChannel channel : list)
- {
- Object[] itemValues =
- {
- channel.getChannelId(), channel.isTransactional(),
- (channel.getDefaultQueue() != null) ? channel.getDefaultQueue().getNameShortString().asString() : null,
- channel.getUnacknowledgedMessageMap().size(), channel.getBlocking()
- };
-
- CompositeData channelData = new CompositeDataSupport(_channelType,
- COMPOSITE_ITEM_NAMES_DESC.toArray(new String[COMPOSITE_ITEM_NAMES_DESC.size()]), itemValues);
- channelsList.put(channelData);
- }
-
- return channelsList;
- }
-
- /**
- * closes the connection. The administrator can use this management operation to close connection to free up
- * resources.
- * @throws JMException
- */
- public void closeConnection() throws JMException
- {
-
- MethodRegistry methodRegistry = _protocolSession.getMethodRegistry();
- ConnectionCloseBody responseBody =
- methodRegistry.createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(),
- // replyCode
- BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION,
- // replyText,
- 0,
- 0);
-
- // This seems ugly but because we use closeConnection in both normal
- // broker operation and as part of the management interface it cannot
- // be avoided. The Current Actor will be null when this method is
- // called via the Management interface. This is because we allow the
- // Local API connection with JConsole. If we did not allow that option
- // then the CurrentActor could be set in our JMX Proxy object.
- // As it is we need to set the CurrentActor on all MBean methods
- // Ideally we would not have a single method that can be called from
- // two contexts.
- boolean removeActor = false;
- if (CurrentActor.get() == null)
- {
- removeActor = true;
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- }
-
- try
- {
- _protocolSession.writeFrame(responseBody.generateFrame(0));
-
- try
- {
-
- _protocolSession.closeSession();
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex, ex.toString());
- }
- }
- finally
- {
- if (removeActor)
- {
- CurrentActor.remove();
- }
- }
- }
-
- public void resetStatistics() throws Exception
- {
- _protocolSession.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return _protocolSession.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return _protocolSession.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return _protocolSession.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return _protocolSession.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return _protocolSession.isStatisticsEnabled();
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _protocolSession.setStatisticsEnabled(enabled);
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
index 0896499cda..efc64d9d91 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
@@ -55,7 +55,7 @@ public interface AMQSessionModel extends Comparable<AMQSessionModel>
* is logged or the connection is closed, depending on the configuration. An open
* transaction is one that has recent activity. The transaction age is counted
* from the time the transaction was started. An idle transaction is one that
- * has had no activity, such as publishing or acknowledgeing messages.
+ * has had no activity, such as publishing or acknowledging messages.
*
* @param openWarn time in milliseconds before alerting on open transaction
* @param openClose time in milliseconds before closing connection with open transaction
@@ -72,6 +72,16 @@ public interface AMQSessionModel extends Comparable<AMQSessionModel>
void unblock();
+ boolean getBlocking();
boolean onSameConnection(InboundMessage inbound);
+
+ int getUnacknowledgedMessageCount();
+
+ Long getTxnCount();
+ Long getTxnStart();
+ Long getTxnCommits();
+ Long getTxnRejects();
+
+ int getChannelId();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java
index 08926d000d..b4195d7e5a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java
@@ -49,6 +49,7 @@ import org.apache.qpid.amqp_1_0.type.transport.Transfer;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.subscription.Subscription;
@@ -631,4 +632,46 @@ class Subscription_1_0 implements Subscription
{
_filters = filters;
}
+
+ @Override
+ public AMQSessionModel getSessionModel()
+ {
+ // TODO
+ return null;
+ }
+
+ @Override
+ public long getBytesOut()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public long getMessagesOut()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public long getUnacknowledgedBytes()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public long getUnacknowledgedMessages()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public String getConsumerName()
+ {
+ //TODO
+ return "TODO";
+ }
}
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 e643338c3d..d3efd63ee0 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
@@ -28,21 +28,25 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeReferrer;
import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.management.Managable;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.security.AuthorizationHolder;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
-public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue,
+public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue,
QueueConfig
{
+ public interface NotificationListener
+ {
+ void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg);
+ }
+
boolean getDeleteOnNoConsumers();
void setDeleteOnNoConsumers(boolean b);
@@ -57,6 +61,12 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
LogSubject getLogSubject();
+ long getUnackedMessageBytes();
+
+ long getTotalDequeueCount();
+
+ long getTotalEnqueueCount();
+
public interface Context
{
QueueEntry getLastSeenEntry();
@@ -79,6 +89,17 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void unregisterSubscription(final Subscription subscription) throws AMQException;
+ Collection<Subscription> getConsumers();
+
+ interface SubscriptionRegistrationListener
+ {
+ void subscriptionRegistered(AMQQueue queue, Subscription subscription);
+ void subscriptionUnregistered(AMQQueue queue, Subscription subscription);
+ }
+
+ void addSubscriptionRegistrationListener(SubscriptionRegistrationListener listener);
+ void removeSubscriptionRegistrationListener(SubscriptionRegistrationListener listener);
+
int getConsumerCount();
@@ -109,7 +130,7 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void dequeue(QueueEntry entry, Subscription sub);
- void decrementUnackedMsgCount();
+ void decrementUnackedMsgCount(QueueEntry queueEntry);
boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException;
@@ -139,20 +160,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
*/
public List<QueueEntry> getMessagesRangeOnTheQueue(final long fromPosition, final long toPosition);
+ void visit(QueueEntryVisitor visitor);
- void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName);
-
- void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName);
-
- void removeMessagesFromQueue(long fromMessageId, long toMessageId);
-
- static interface Visitor
- {
- boolean visit(QueueEntry entry);
- }
-
- void visit(Visitor visitor);
-
long getMaximumMessageSize();
@@ -216,8 +225,6 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void setAlternateExchange(Exchange exchange);
- void setAlternateExchange(String exchangeName);
-
Map<String, Object> getArguments();
void checkCapacity(AMQSessionModel channel);
@@ -245,12 +252,12 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
}
/**
- * ExistingSubscriptionPreventsExclusive signals a failure to create an exclusize subscription, as a subscription
+ * ExistingSubscriptionPreventsExclusive signals a failure to create an exclusive subscription, as a subscription
* already exists.
*
* <p/><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Represent failure to create an exclusize subscription, as a subscription already exists.
+ * <tr><td> Represent failure to create an exclusive subscription, as a subscription already exists.
* </table>
*
* @todo Not an AMQP exception as no status code.
@@ -274,9 +281,7 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
ConfigurationPlugin getConfiguration();
- ManagedObject getManagedObject();
-
- void setExclusive(boolean exclusive) throws AMQException;
+ void setExclusive(boolean exclusive);
/**
* Gets the maximum delivery count. If a message on this queue
@@ -295,4 +300,19 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
*/
public void setMaximumDeliveryCount(final int maximumDeliveryCount);
+ void setNotificationListener(NotificationListener listener);
+
+ /**
+ * Sets the free text description of this queue.
+ *
+ * @param description
+ *
+ */
+ void setDescription(String description);
+
+ /**
+ * Gets the free text description of this queue.
+ */
+ String getDescription();
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
index f2b7d7c56b..d93af2fc25 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.queue;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -41,6 +42,7 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
public class AMQQueueFactory
{
public static final String X_QPID_PRIORITIES = "x-qpid-priorities";
+ public static final String X_QPID_DESCRIPTION = "x-qpid-description";
public static final String QPID_LVQ_KEY = "qpid.LVQ_key";
public static final String QPID_LAST_VALUE_QUEUE = "qpid.last_value_queue";
public static final String QPID_LAST_VALUE_QUEUE_KEY = "qpid.last_value_queue_key";
@@ -350,32 +352,7 @@ public class AMQQueueFactory
boolean autodelete = config.getAutoDelete();
boolean exclusive = config.getExclusive();
String owner = config.getOwner();
- Map<String,Object> arguments = null;
-
- if(config.isLVQ() || config.getLVQKey() != null)
- {
- arguments = new HashMap<String,Object>();
- arguments.put(QPID_LAST_VALUE_QUEUE, 1);
- arguments.put(QPID_LAST_VALUE_QUEUE_KEY, config.getLVQKey() == null ? QPID_LVQ_KEY : config.getLVQKey());
- }
- else if (config.getPriority() || config.getPriorities() > 0)
- {
- arguments = new HashMap<String,Object>();
- arguments.put(X_QPID_PRIORITIES, config.getPriorities() < 0 ? 10 : config.getPriorities());
- }
- else if (config.getQueueSortKey() != null && !"".equals(config.getQueueSortKey()))
- {
- arguments = new HashMap<String,Object>();
- arguments.put(QPID_QUEUE_SORT_KEY, config.getQueueSortKey());
- }
- if (!config.getAutoDelete() && config.isDeadLetterQueueEnabled())
- {
- if (arguments == null)
- {
- arguments = new HashMap<String,Object>();
- }
- arguments.put(X_QPID_DLQ_ENABLED, true);
- }
+ Map<String, Object> arguments = createQueueArgumentsFromConfig(config);
// we need queues that are defined in config to have deterministic ids.
UUID id = UUIDGenerator.generateUUID(queueName, host.getName());
@@ -385,7 +362,6 @@ public class AMQQueueFactory
return q;
}
-
/**
* Validates DLQ and DLE names
* <p>
@@ -475,4 +451,43 @@ public class AMQQueueFactory
String dlExchangeName = name + serverConfig.getDeadLetterExchangeSuffix();
return dlExchangeName;
}
+
+ private static Map<String, Object> createQueueArgumentsFromConfig(QueueConfiguration config)
+ {
+ Map<String,Object> arguments = new HashMap<String,Object>();
+
+ if(config.isLVQ() || config.getLVQKey() != null)
+ {
+ arguments.put(QPID_LAST_VALUE_QUEUE, 1);
+ arguments.put(QPID_LAST_VALUE_QUEUE_KEY, config.getLVQKey() == null ? QPID_LVQ_KEY : config.getLVQKey());
+ }
+ else if (config.getPriority() || config.getPriorities() > 0)
+ {
+ arguments.put(X_QPID_PRIORITIES, config.getPriorities() < 0 ? 10 : config.getPriorities());
+ }
+ else if (config.getQueueSortKey() != null && !"".equals(config.getQueueSortKey()))
+ {
+ arguments.put(QPID_QUEUE_SORT_KEY, config.getQueueSortKey());
+ }
+
+ if (!config.getAutoDelete() && config.isDeadLetterQueueEnabled())
+ {
+ arguments.put(X_QPID_DLQ_ENABLED, true);
+ }
+
+ if (config.getDescription() != null && !"".equals(config.getDescription()))
+ {
+ arguments.put(X_QPID_DESCRIPTION, config.getDescription());
+ }
+
+ if (arguments.isEmpty())
+ {
+ return Collections.emptyMap();
+ }
+ else
+ {
+ return arguments;
+ }
+ }
+
}
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
deleted file mode 100644
index b0d4cb3486..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.queue;
-
-import org.apache.commons.lang.time.FastDateFormat;
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.AMQMessageHeader;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.transport.MessageProperties;
-
-import javax.management.JMException;
-import javax.management.MBeanException;
-import javax.management.MBeanNotificationInfo;
-import javax.management.Notification;
-import javax.management.ObjectName;
-import javax.management.OperationsException;
-import javax.management.monitor.MonitorNotification;
-import javax.management.openmbean.ArrayType;
-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 java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-
-/**
- * AMQQueueMBean is the management bean for an {@link AMQQueue}.
- *
- * <p/><table id="crc"><caption>CRC Caption</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * </table>
- */
-@MBeanDescription("Management Interface for AMQQueue")
-public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, QueueNotificationListener
-{
-
- /** Used for debugging purposes. */
- private static final Logger LOGGER = Logger.getLogger(AMQQueueMBean.class);
-
- /** Date/time format used for message expiration and message timestamp formatting */
- public static final String JMSTIMESTAMP_DATETIME_FORMAT = "MM-dd-yy HH:mm:ss.SSS z";
-
- private static final FastDateFormat FAST_DATE_FORMAT = FastDateFormat.getInstance(JMSTIMESTAMP_DATETIME_FORMAT);
-
- private final AMQQueue _queue;
- private final String _queueName;
- // OpenMBean data types for viewMessages method
-
- private static OpenType[] _msgAttributeTypes = new OpenType[6]; // AMQ message attribute types.
- private static CompositeType _messageDataType = null; // Composite type for representing AMQ Message data.
- private static TabularType _messagelistDataType = null; // Datatype for representing AMQ messages list.
-
- // OpenMBean data types for viewMessageContent method
- private static CompositeType _msgContentType = null;
- private static OpenType[] _msgContentAttributeTypes = new OpenType[4];
-
- private final long[] _lastNotificationTimes = new long[NotificationCheck.values().length];
- private Notification _lastNotification = null;
-
-
-
-
- @MBeanConstructor("Creates an MBean exposing an AMQQueue")
- public AMQQueueMBean(AMQQueue queue) throws JMException
- {
- super(ManagedQueue.class, ManagedQueue.TYPE);
- _queue = queue;
- _queueName = queue.getName();
- }
-
- public ManagedObject getParentObject()
- {
- return _queue.getVirtualHost().getManagedObject();
- }
-
- static
- {
- try
- {
- init();
- }
- catch (JMException ex)
- {
- // This is not expected to ever occur.
- throw new RuntimeException("Got JMException in static initializer.", ex);
- }
- }
-
- /**
- * initialises the openmbean data types
- */
- private static void init() throws OpenDataException
- {
- _msgContentAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgContentAttributeTypes[1] = SimpleType.STRING; // For MimeType
- _msgContentAttributeTypes[2] = SimpleType.STRING; // For Encoding
- _msgContentAttributeTypes[3] = new ArrayType(1, SimpleType.BYTE); // For message content
- _msgContentType = new CompositeType("Message Content", "AMQ Message Content",
- VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.toArray(new String[VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.size()]),
- VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.toArray(new String[VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.size()]),
- _msgContentAttributeTypes);
-
- _msgAttributeTypes[0] = SimpleType.LONG; // For message id
- _msgAttributeTypes[1] = new ArrayType(1, SimpleType.STRING); // For header attributes
- _msgAttributeTypes[2] = SimpleType.LONG; // For size
- _msgAttributeTypes[3] = SimpleType.BOOLEAN; // For redelivered
- _msgAttributeTypes[4] = SimpleType.LONG; // For queue position
- _msgAttributeTypes[5] = SimpleType.INTEGER; // For delivery count
-
- _messageDataType = new CompositeType("Message", "AMQ Message",
- VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.toArray(new String[VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.size()]),
- VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.toArray(new String[VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.size()]), _msgAttributeTypes);
- _messagelistDataType = new TabularType("Messages", "List of messages", _messageDataType,
- VIEW_MSGS_TABULAR_UNIQUE_INDEX.toArray(new String[VIEW_MSGS_TABULAR_UNIQUE_INDEX.size()]));
- }
-
- public String getObjectInstanceName()
- {
- return ObjectName.quote(_queueName);
- }
-
- public String getName()
- {
- return _queueName;
- }
-
- public boolean isDurable()
- {
- return _queue.isDurable();
- }
-
- public String getOwner()
- {
- return String.valueOf(_queue.getOwner());
- }
-
- public boolean isAutoDelete()
- {
- return _queue.isAutoDelete();
- }
-
- public Integer getMessageCount()
- {
- return _queue.getMessageCount();
- }
-
- public Integer getMaximumDeliveryCount()
- {
- return _queue.getMaximumDeliveryCount();
- }
-
- public Long getMaximumMessageSize()
- {
- return _queue.getMaximumMessageSize();
- }
-
- public Long getMaximumMessageAge()
- {
- return _queue.getMaximumMessageAge();
- }
-
- public void setMaximumMessageAge(Long maximumMessageAge)
- {
- _queue.setMaximumMessageAge(maximumMessageAge);
- }
-
- public void setMaximumMessageSize(Long value)
- {
- _queue.setMaximumMessageSize(value);
- }
-
- public Integer getConsumerCount()
- {
- return _queue.getConsumerCount();
- }
-
- public Integer getActiveConsumerCount()
- {
- return _queue.getActiveConsumerCount();
- }
-
- public Long getReceivedMessageCount()
- {
- return _queue.getReceivedMessageCount();
- }
-
- public Long getMaximumMessageCount()
- {
- return _queue.getMaximumMessageCount();
- }
-
- public void setMaximumMessageCount(Long value)
- {
- _queue.setMaximumMessageCount(value);
- }
-
- /**
- * returns the maximum total size of messages(bytes) in the queue.
- */
- public Long getMaximumQueueDepth()
- {
- return _queue.getMaximumQueueDepth();
- }
-
- public void setMaximumQueueDepth(Long value)
- {
- _queue.setMaximumQueueDepth(value);
- }
-
- /**
- * returns the total size of messages(bytes) in the queue.
- */
- public Long getQueueDepth() throws JMException
- {
- return _queue.getQueueDepth();
- }
-
- public Long getCapacity()
- {
- return _queue.getCapacity();
- }
-
- public void setCapacity(Long capacity) throws IllegalArgumentException
- {
- if( _queue.getFlowResumeCapacity() > capacity )
- {
- throw new IllegalArgumentException("Capacity must not be less than FlowResumeCapacity");
- }
-
- _queue.setCapacity(capacity);
- }
-
- public Long getFlowResumeCapacity()
- {
- return _queue.getFlowResumeCapacity();
- }
-
- public void setFlowResumeCapacity(Long flowResumeCapacity) throws IllegalArgumentException
- {
- if( _queue.getCapacity() < flowResumeCapacity )
- {
- throw new IllegalArgumentException("FlowResumeCapacity must not exceed Capacity");
- }
-
- _queue.setFlowResumeCapacity(flowResumeCapacity);
- }
-
- public boolean isFlowOverfull()
- {
- return _queue.isOverfull();
- }
-
- public boolean isExclusive()
- {
- return _queue.isExclusive();
- }
-
- public void setExclusive(boolean exclusive) throws JMException
- {
- try
- {
- _queue.setExclusive(exclusive);
- }
- catch (AMQException e)
- {
- throw new JMException(e.toString());
- }
- }
-
- public void setAlternateExchange(String exchangeName)
- {
- _queue.setAlternateExchange(exchangeName);
- }
-
- public String getAlternateExchange()
- {
- Exchange exchange = _queue.getAlternateExchange();
- String name = exchange == null ? null : exchange.getName();
- return name == null ? null : name;
- }
-
- /**
- * Checks if there is any notification to be send to the listeners
- */
- public void checkForNotification(ServerMessage msg) throws AMQException
- {
-
- final Set<NotificationCheck> notificationChecks = _queue.getNotificationChecks();
-
- if(!notificationChecks.isEmpty())
- {
- final long currentTime = System.currentTimeMillis();
- final long thresholdTime = currentTime - _queue.getMinimumAlertRepeatGap();
-
- for (NotificationCheck check : notificationChecks)
- {
- if (check.isMessageSpecific() || (_lastNotificationTimes[check.ordinal()] < thresholdTime))
- {
- if (check.notifyIfNecessary(msg, _queue, this))
- {
- _lastNotificationTimes[check.ordinal()] = currentTime;
- }
- }
- }
- }
-
- }
-
- /**
- * Sends the notification to the listeners
- */
- public void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg)
- {
- // important : add log to the log file - monitoring tools may be looking for this
- LOGGER.info(notification.name() + " On Queue " + queue.getNameShortString() + " - " + notificationMsg);
- notificationMsg = notification.name() + " " + notificationMsg;
-
- _lastNotification =
- new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, incrementAndGetSequenceNumber(),
- System.currentTimeMillis(), notificationMsg);
-
- getBroadcaster().sendNotification(_lastNotification);
- }
-
- public Notification getLastNotification()
- {
- return _lastNotification;
- }
-
- /**
- * @see AMQQueue#deleteMessageFromTop
- */
- public void deleteMessageFromTop() throws JMException
- {
- _queue.deleteMessageFromTop();
- }
-
- /**
- * Clears the queue of non-acquired messages
- *
- * @return the number of messages deleted
- * @see AMQQueue#clearQueue
- */
- public Long clearQueue() throws JMException
- {
- try
- {
- return _queue.clearQueue();
- }
- catch (AMQException ex)
- {
- throw new MBeanException(ex, "Error clearing queue " + _queueName);
- }
- }
-
- /**
- * returns message content as byte array and related attributes for the given message id.
- */
- public CompositeData viewMessageContent(long msgId) throws JMException
- {
- QueueEntry entry = _queue.getMessageOnTheQueue(msgId);
-
- if (entry == null)
- {
- throw new OperationsException("AMQMessage with message id = " + msgId + " is not in the " + _queueName);
- }
-
- ServerMessage serverMsg = entry.getMessage();
- final int bodySize = (int) serverMsg.getSize();
-
-
- List<Byte> msgContent = new ArrayList<Byte>();
-
- java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(bodySize);
- int position = 0;
-
- while(position < bodySize)
- {
- position += serverMsg.getContent(buf, position);
- buf.flip();
- for(int i = 0; i < buf.limit(); i++)
- {
- msgContent.add(buf.get(i));
- }
- buf.clear();
- }
-
- AMQMessageHeader header = serverMsg.getMessageHeader();
-
- String mimeType = null, encoding = null;
- if (header != null)
- {
- mimeType = header.getMimeType();
-
- encoding = header.getEncoding();
- }
-
-
- Object[] itemValues = { msgId, mimeType, encoding, msgContent.toArray(new Byte[0]) };
-
- return new CompositeDataSupport(_msgContentType,
- VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.toArray(
- new String[VIEW_MSG_CONTENT_COMPOSITE_ITEM_NAMES_DESC.size()]), itemValues);
-
- }
-
- /**
- * 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
- {
- 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 = " + 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.getMessagesRangeOnTheQueue(startPosition,endPosition);
- TabularDataSupport _messageList = new TabularDataSupport(_messagelistDataType);
-
- try
- {
- // Create the tabular list of message header contents
- int size = list.size();
-
- for (int i = 0; i < size ; i++)
- {
- long position = startPosition + i;
- final QueueEntry queueEntry = list.get(i);
- ServerMessage serverMsg = queueEntry.getMessage();
-
- String[] headerAttributes = null;
- Object[] itemValues = null;
-
- if(serverMsg instanceof AMQMessage)
- {
- AMQMessage msg = (AMQMessage) serverMsg;
- ContentHeaderBody headerBody = msg.getContentHeaderBody();
- // Create header attributes list
- headerAttributes = getMessageHeaderProperties(headerBody);
- itemValues = new Object[]{msg.getMessageId(), headerAttributes, headerBody.getBodySize(), queueEntry.isRedelivered(), position, queueEntry.getDeliveryCount()};
- }
- else if(serverMsg instanceof MessageTransferMessage)
- {
- // We have a 0-10 message
- MessageTransferMessage msg = (MessageTransferMessage) serverMsg;
-
- // Create header attributes list
- headerAttributes = getMessageTransferMessageHeaderProps(msg);
- itemValues = new Object[]{msg.getMessageNumber(), headerAttributes, msg.getSize(), queueEntry.isRedelivered(), position, queueEntry.getDeliveryCount()};
- }
- else
- {
- //unknown message
- headerAttributes = new String[]{"N/A"};
- itemValues = new Object[]{serverMsg.getMessageNumber(), headerAttributes, serverMsg.getSize(), queueEntry.isRedelivered(), position, queueEntry.getDeliveryCount()};
- }
-
- CompositeData messageData = new CompositeDataSupport(_messageDataType,
- VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.toArray(new String[VIEW_MSGS_COMPOSITE_ITEM_NAMES_DESC.size()]), itemValues);
- _messageList.put(messageData);
- }
- }
- catch (AMQException e)
- {
- JMException jme = new JMException("Error creating message contents: " + e);
- jme.initCause(e);
- throw jme;
- }
-
- return _messageList;
- }
-
- private String[] getMessageHeaderProperties(ContentHeaderBody headerBody)
- {
- List<String> list = new ArrayList<String>();
- BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.getProperties();
- list.add("reply-to = " + headerProperties.getReplyToAsString());
- list.add("propertyFlags = " + headerProperties.getPropertyFlags());
- list.add("ApplicationID = " + headerProperties.getAppIdAsString());
- list.add("ClusterID = " + headerProperties.getClusterIdAsString());
- list.add("UserId = " + headerProperties.getUserIdAsString());
- list.add("JMSMessageID = " + headerProperties.getMessageIdAsString());
- list.add("JMSCorrelationID = " + headerProperties.getCorrelationIdAsString());
-
- int delMode = headerProperties.getDeliveryMode();
- list.add("JMSDeliveryMode = " +
- ((delMode == BasicContentHeaderProperties.PERSISTENT) ? "Persistent" : "Non_Persistent"));
-
- list.add("JMSPriority = " + headerProperties.getPriority());
- list.add("JMSType = " + headerProperties.getType());
-
- final long expirationDate = headerProperties.getExpiration();
- final long timestampDate = headerProperties.getTimestamp();
-
- addStringifiedJMSTimestamoAndJMSExpiration(list, expirationDate,
- timestampDate);
-
- return list.toArray(new String[list.size()]);
- }
-
- private String[] getMessageTransferMessageHeaderProps(MessageTransferMessage msg)
- {
- List<String> list = new ArrayList<String>();
-
- AMQMessageHeader header = msg.getMessageHeader();
- MessageProperties msgProps = msg.getHeader().getMessageProperties();
-
- String appID = null;
- String userID = null;
-
- if(msgProps != null)
- {
- appID = msgProps.getAppId() == null ? "null" : new String(msgProps.getAppId());
- userID = msgProps.getUserId() == null ? "null" : new String(msgProps.getUserId());
- }
-
- list.add("reply-to = " + header.getReplyTo());
- list.add("propertyFlags = "); //TODO
- list.add("ApplicationID = " + appID);
- list.add("ClusterID = "); //TODO
- list.add("UserId = " + userID);
- list.add("JMSMessageID = " + header.getMessageId());
- list.add("JMSCorrelationID = " + header.getCorrelationId());
- list.add("JMSDeliveryMode = " + (msg.isPersistent() ? "Persistent" : "Non_Persistent"));
- list.add("JMSPriority = " + header.getPriority());
- list.add("JMSType = " + header.getType());
-
- final long expirationDate = header.getExpiration();
- final long timestampDate = header.getTimestamp();
- addStringifiedJMSTimestamoAndJMSExpiration(list, expirationDate, timestampDate);
-
- return list.toArray(new String[list.size()]);
- }
-
- private void addStringifiedJMSTimestamoAndJMSExpiration(final List<String> list,
- final long expirationDate, final long timestampDate)
- {
- final String formattedExpirationDate = (expirationDate != 0) ? FAST_DATE_FORMAT.format(expirationDate) : null;
- final String formattedTimestampDate = (timestampDate != 0) ? FAST_DATE_FORMAT.format(timestampDate) : null;
- list.add("JMSExpiration = " + formattedExpirationDate);
- list.add("JMSTimestamp = " + formattedTimestampDate);
- }
-
- /**
- * @see ManagedQueue#moveMessages
- * @param fromMessageId
- * @param toMessageId
- * @param toQueueName
- * @throws JMException
- */
- public void moveMessages(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.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName);
- }
-
- /**
- * @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);
- }
-
- /**
- * @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);
- }
-
- /**
- * returns Notifications sent by this MBean.
- */
- @Override
- public MBeanNotificationInfo[] getNotificationInfo()
- {
- String[] notificationTypes = new String[] { MonitorNotification.THRESHOLD_VALUE_EXCEEDED };
- String name = MonitorNotification.class.getName();
- String description = "Either Message count or Queue depth or Message size has reached threshold high value";
- MBeanNotificationInfo info1 = new MBeanNotificationInfo(notificationTypes, name, description);
-
- return new MBeanNotificationInfo[] { info1 };
- }
-
-} // End of AMQQueueMBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
index 2493974d45..27a9e13617 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
@@ -20,12 +20,10 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,11 +31,11 @@ import java.util.concurrent.ConcurrentMap;
public class DefaultQueueRegistry implements QueueRegistry
{
- private static final Logger LOGGER = Logger.getLogger(DefaultExchangeRegistry.class);
-
private ConcurrentMap<AMQShortString, AMQQueue> _queueMap = new ConcurrentHashMap<AMQShortString, AMQQueue>();
private final VirtualHost _virtualHost;
+ private final Collection<RegistryChangeListener> _listeners =
+ new ArrayList<RegistryChangeListener>();
public DefaultQueueRegistry(VirtualHost virtualHost)
{
@@ -52,11 +50,28 @@ public class DefaultQueueRegistry implements QueueRegistry
public void registerQueue(AMQQueue queue)
{
_queueMap.put(queue.getNameShortString(), queue);
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.queueRegistered(queue);
+ }
+ }
}
public void unregisterQueue(AMQShortString name)
{
- _queueMap.remove(name);
+ AMQQueue q = _queueMap.remove(name);
+ if(q != null)
+ {
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.queueUnregistered(q);
+ }
+ }
+ }
}
public AMQQueue getQueue(AMQShortString name)
@@ -79,19 +94,30 @@ public class DefaultQueueRegistry implements QueueRegistry
return getQueue(new AMQShortString(queue));
}
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ synchronized(_listeners)
+ {
+ _listeners.add(listener);
+ }
+ }
+
@Override
public void stopAllAndUnregisterMBeans()
{
for (final AMQQueue queue : getQueues())
{
queue.stop();
- try
- {
- queue.getManagedObject().unregister();
- }
- catch (AMQException e)
+
+ //TODO: this is a bit of a hack, what if the listeners aren't aware
+ //that we are just unregistering the MBean because of HA, and aren't
+ //actually removing the queue as such.
+ synchronized (_listeners)
{
- LOGGER.warn("Failed to unregister mbean", e);
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.queueUnregistered(queue);
+ }
}
}
_queueMap.clear();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
index c1ebbe412f..3efef9ab98 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.queue;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.message.ServerMessage;
public enum NotificationCheck
@@ -27,13 +28,16 @@ public enum NotificationCheck
MESSAGE_COUNT_ALERT
{
- boolean notifyIfNecessary(ServerMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ public boolean notifyIfNecessary(ServerMessage<?> msg, AMQQueue queue, AMQQueue.NotificationListener listener)
{
int msgCount;
final long maximumMessageCount = queue.getMaximumMessageCount();
if (maximumMessageCount!= 0 && (msgCount = queue.getMessageCount()) >= maximumMessageCount)
{
- listener.notifyClients(this, queue, msgCount + ": Maximum count on queue threshold ("+ maximumMessageCount +") breached.");
+ String notificationMsg = msgCount + ": Maximum count on queue threshold ("+ maximumMessageCount +") breached.";
+
+ logNotification(this, queue, notificationMsg);
+ listener.notifyClients(this, queue, notificationMsg);
return true;
}
return false;
@@ -41,7 +45,7 @@ public enum NotificationCheck
},
MESSAGE_SIZE_ALERT(true)
{
- boolean notifyIfNecessary(ServerMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ public boolean notifyIfNecessary(ServerMessage<?> msg, AMQQueue queue, AMQQueue.NotificationListener listener)
{
final long maximumMessageSize = queue.getMaximumMessageSize();
if(maximumMessageSize != 0)
@@ -50,10 +54,12 @@ public enum NotificationCheck
long messageSize;
messageSize = (msg == null) ? 0 : msg.getSize();
-
if (messageSize >= maximumMessageSize)
{
- listener.notifyClients(this, queue, messageSize + "b : Maximum message size threshold ("+ maximumMessageSize +") breached. [Message ID=" + msg.getMessageNumber() + "]");
+ String notificationMsg = messageSize + "b : Maximum message size threshold ("+ maximumMessageSize +") breached. [Message ID=" + msg.getMessageNumber() + "]";
+
+ logNotification(this, queue, notificationMsg);
+ listener.notifyClients(this, queue, notificationMsg);
return true;
}
}
@@ -63,7 +69,7 @@ public enum NotificationCheck
},
QUEUE_DEPTH_ALERT
{
- boolean notifyIfNecessary(ServerMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ public boolean notifyIfNecessary(ServerMessage<?> msg, AMQQueue queue, AMQQueue.NotificationListener listener)
{
// Check for threshold queue depth in bytes
final long maximumQueueDepth = queue.getMaximumQueueDepth();
@@ -74,7 +80,10 @@ public enum NotificationCheck
if (queueDepth >= maximumQueueDepth)
{
- listener.notifyClients(this, queue, (queueDepth>>10) + "Kb : Maximum queue depth threshold ("+(maximumQueueDepth>>10)+"Kb) breached.");
+ String notificationMsg = (queueDepth>>10) + "Kb : Maximum queue depth threshold ("+(maximumQueueDepth>>10)+"Kb) breached.";
+
+ logNotification(this, queue, notificationMsg);
+ listener.notifyClients(this, queue, notificationMsg);
return true;
}
}
@@ -84,7 +93,7 @@ public enum NotificationCheck
},
MESSAGE_AGE_ALERT
{
- boolean notifyIfNecessary(ServerMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ public boolean notifyIfNecessary(ServerMessage<?> msg, AMQQueue queue, AMQQueue.NotificationListener listener)
{
final long maxMessageAge = queue.getMaximumMessageAge();
@@ -97,7 +106,10 @@ public enum NotificationCheck
if(firstArrivalTime < thresholdTime)
{
long oldestAge = currentTime - firstArrivalTime;
- listener.notifyClients(this, queue, (oldestAge/1000) + "s : Maximum age on queue threshold ("+(maxMessageAge /1000)+"s) breached.");
+ String notificationMsg = (oldestAge/1000) + "s : Maximum age on queue threshold ("+(maxMessageAge /1000)+"s) breached.";
+
+ logNotification(this, queue, notificationMsg);
+ listener.notifyClients(this, queue, notificationMsg);
return true;
}
@@ -109,6 +121,8 @@ public enum NotificationCheck
}
;
+ private static final Logger LOGGER = Logger.getLogger(NotificationCheck.class);
+
private final boolean _messageSpecific;
NotificationCheck()
@@ -126,6 +140,11 @@ public enum NotificationCheck
return _messageSpecific;
}
- abstract boolean notifyIfNecessary(ServerMessage msg, AMQQueue queue, QueueNotificationListener listener);
+ public abstract boolean notifyIfNecessary(ServerMessage<?> msg, AMQQueue queue, AMQQueue.NotificationListener listener);
+ //A bit of a hack, only for use until we do the logging listener
+ private static void logNotification(NotificationCheck notification, AMQQueue queue, String notificationMsg)
+ {
+ LOGGER.info(notification.name() + " On Queue " + queue.getNameShortString() + " - " + notificationMsg);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index 209553e8fa..25e771a9cf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
@@ -233,7 +233,7 @@ public abstract class QueueEntryImpl implements QueueEntry
if(state instanceof SubscriptionAcquiredState)
{
- getQueue().decrementUnackedMsgCount();
+ getQueue().decrementUnackedMsgCount(this);
Subscription subscription = ((SubscriptionAcquiredState)state).getSubscription();
if (subscription != null)
{
@@ -369,7 +369,7 @@ public abstract class QueueEntryImpl implements QueueEntry
Subscription s = null;
if (state instanceof SubscriptionAcquiredState)
{
- getQueue().decrementUnackedMsgCount();
+ getQueue().decrementUnackedMsgCount(this);
s = ((SubscriptionAcquiredState) state).getSubscription();
s.onDequeue(this);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
index 72a54c9889..e8c34128e9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
@@ -42,7 +42,15 @@ public interface QueueRegistry
AMQQueue getQueue(String queue);
+ void addRegistryChangeListener(RegistryChangeListener listener);
+
void stopAllAndUnregisterMBeans();
AMQQueue getQueue(UUID queueId);
+
+ interface RegistryChangeListener
+ {
+ void queueRegistered(AMQQueue queue);
+ void queueUnregistered(AMQQueue queue);
+ }
}
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 d7eb304c92..3d54bba48f 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
@@ -19,8 +19,10 @@
package org.apache.qpid.server.queue;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,8 +34,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import javax.management.JMException;
-
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
@@ -52,7 +52,6 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.QueueActor;
import org.apache.qpid.server.logging.messages.QueueMessages;
import org.apache.qpid.server.logging.subjects.QueueLogSubject;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -70,6 +69,7 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, MessageGroupManager.SubscriptionResetHelper
{
private static final Logger _logger = Logger.getLogger(SimpleAMQQueue.class);
+
private static final String QPID_GROUP_HEADER_KEY = "qpid.group_header_key";
private static final String QPID_SHARED_MSG_GROUP = "qpid.shared_msg_group";
private static final String QPID_DEFAULT_MESSAGE_GROUP = "qpid.default-message-group";
@@ -77,11 +77,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
// TODO - should make this configurable at the vhost / broker level
private static final int DEFAULT_MAX_GROUPS = 255;
-
private final VirtualHost _virtualHost;
private final AMQShortString _name;
- private final String _resourceName;
/** null means shared */
private final AMQShortString _owner;
@@ -118,6 +116,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private final AtomicLong _dequeueCount = new AtomicLong();
private final AtomicLong _dequeueSize = new AtomicLong();
+ private final AtomicLong _enqueueCount = new AtomicLong();
private final AtomicLong _enqueueSize = new AtomicLong();
private final AtomicLong _persistentMessageEnqueueSize = new AtomicLong();
private final AtomicLong _persistentMessageDequeueSize = new AtomicLong();
@@ -130,6 +129,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private final AtomicLong _byteTxnDequeues = new AtomicLong(0);
private final AtomicLong _unackedMsgCount = new AtomicLong(0);
private final AtomicLong _unackedMsgCountHigh = new AtomicLong(0);
+ private final AtomicLong _unackedMsgBytes = new AtomicLong();
private final AtomicInteger _bindingCountHigh = new AtomicInteger();
@@ -173,7 +173,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private LogSubject _logSubject;
private LogActor _logActor;
- private AMQQueueMBean _managedObject;
private static final String SUB_FLUSH_RUNNER = "SUB_FLUSH_RUNNER";
private boolean _nolocal;
@@ -191,6 +190,12 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private int _maximumDeliveryCount = ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount();
private final MessageGroupManager _messageGroupManager;
+ private final Collection<SubscriptionRegistrationListener> _subscriptionListeners =
+ new ArrayList<SubscriptionRegistrationListener>();
+
+ private AMQQueue.NotificationListener _notificationListener;
+ private final long[] _lastNotificationTimes = new long[NotificationCheck.values().length];
+
protected SimpleAMQQueue(UUID id, AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, boolean exclusive, VirtualHost virtualHost, Map<String,Object> arguments)
{
this(id, name, durable, owner, autoDelete, exclusive,virtualHost, new SimpleQueueEntryList.Factory(), arguments);
@@ -227,14 +232,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
_name = name;
- _resourceName = String.valueOf(name);
_durable = durable;
_owner = owner;
_autoDelete = autoDelete;
_exclusive = exclusive;
_virtualHost = virtualHost;
_entries = entryListFactory.createQueueEntryList(this);
- _arguments = arguments;
+ _arguments = arguments == null ? new HashMap<String, Object>() : new HashMap<String, Object>(arguments);
_id = id;
@@ -255,16 +259,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
getConfigStore().addConfiguredObject(this);
- try
- {
- _managedObject = new AMQQueueMBean(this);
- _managedObject.register();
- }
- catch (JMException e)
- {
- _logger.error("AMQQueue MBean creation has failed ", e);
- }
-
if(arguments != null && arguments.containsKey(QPID_GROUP_HEADER_KEY))
{
if(arguments.containsKey(QPID_SHARED_MSG_GROUP) && String.valueOf(arguments.get(QPID_SHARED_MSG_GROUP)).equals("1"))
@@ -339,15 +333,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
return _exclusive;
}
-
- public void setExclusive(boolean exclusive) throws AMQException
+
+ public void setExclusive(boolean exclusive)
{
_exclusive = exclusive;
-
- if(isDurable())
- {
- getVirtualHost().getMessageStore().updateQueue(this);
- }
}
public Exchange getAlternateExchange()
@@ -368,22 +357,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
_alternateExchange = exchange;
}
- public void setAlternateExchange(String exchangeName)
- {
- if(exchangeName == null || exchangeName.equals(""))
- {
- _alternateExchange = null;
- return;
- }
-
- Exchange exchange = getVirtualHost().getExchangeRegistry().getExchange(new AMQShortString(exchangeName));
- if (exchange == null)
- {
- throw new RuntimeException("Exchange '" + exchangeName + "' is not registered with the VirtualHost.");
- }
- setAlternateExchange(exchange);
- }
-
+ /**
+ * Arguments used to create this queue. The caller is assured
+ * that null will never be returned.
+ */
public Map<String, Object> getArguments()
{
return _arguments;
@@ -430,8 +407,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
throw new AMQSecurityException("Permission denied");
}
-
-
+
+
if (hasExclusiveSubscriber())
{
throw new ExistingExclusiveSubscription();
@@ -463,15 +440,24 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
subscription.setNoLocal(_nolocal);
}
+
+ synchronized (_subscriptionListeners)
+ {
+ for(SubscriptionRegistrationListener listener : _subscriptionListeners)
+ {
+ listener.subscriptionRegistered(this, subscription);
+ }
+ }
+
_subscriptionList.add(subscription);
-
+
//Increment consumerCountHigh if necessary. (un)registerSubscription are both
//synchronized methods so we don't need additional synchronization here
if(_counsumerCountHigh.get() < getConsumerCount())
{
_counsumerCountHigh.incrementAndGet();
}
-
+
if (isDeleted())
{
subscription.queueDeleted(this);
@@ -507,6 +493,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
resetSubPointersForGroups(subscription, true);
}
+ synchronized (_subscriptionListeners)
+ {
+ for(SubscriptionRegistrationListener listener : _subscriptionListeners)
+ {
+ listener.subscriptionUnregistered(this, subscription);
+ }
+ }
+
// auto-delete queues must be deleted if there are no remaining subscribers
if (_autoDelete && getDeleteOnNoConsumers() && !subscription.isTransient() && getConsumerCount() == 0 )
@@ -526,6 +520,34 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
+ public Collection<Subscription> getConsumers()
+ {
+ List<Subscription> consumers = new ArrayList<Subscription>();
+ SubscriptionList.SubscriptionNodeIterator iter = _subscriptionList.iterator();
+ while(iter.advance())
+ {
+ consumers.add(iter.getNode().getSubscription());
+ }
+ return consumers;
+
+ }
+
+ public void addSubscriptionRegistrationListener(final SubscriptionRegistrationListener listener)
+ {
+ synchronized (_subscriptionListeners)
+ {
+ _subscriptionListeners.add(listener);
+ }
+ }
+
+ public void removeSubscriptionRegistrationListener(final SubscriptionRegistrationListener listener)
+ {
+ synchronized (_subscriptionListeners)
+ {
+ _subscriptionListeners.remove(listener);
+ }
+ }
+
public void resetSubPointersForGroups(Subscription subscription, boolean clearAssignments)
{
QueueEntry entry = _messageGroupManager.findEarliestAssignedAvailableEntry(subscription);
@@ -576,10 +598,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
break;
}
}
-
+
reconfigure();
}
-
+
private void reconfigure()
{
//Reconfigure the queue for to reflect this new binding.
@@ -604,7 +626,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
public void removeBinding(final Binding binding)
{
_bindings.remove(binding);
-
+
reconfigure();
}
@@ -718,10 +740,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
}
- if(_managedObject != null)
- {
- _managedObject.checkForNotification(entry.getMessage());
- }
+ checkForNotification(entry.getMessage());
if(action != null)
{
@@ -738,8 +757,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
try
{
- if (!sub.isSuspended()
- && subscriptionReadyAndHasInterest(sub, entry)
+ if (!sub.isSuspended()
+ && subscriptionReadyAndHasInterest(sub, entry)
&& mightAssign(sub, entry)
&& !sub.wouldSuspend(entry))
{
@@ -788,6 +807,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
long size = message.getSize();
getAtomicQueueSize().addAndGet(size);
+ _enqueueCount.incrementAndGet();
_enqueueSize.addAndGet(size);
if(message.isPersistent() && isDurable())
{
@@ -796,19 +816,29 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
}
+ public long getTotalDequeueCount()
+ {
+ return _dequeueCount.get();
+ }
+
+ public long getTotalEnqueueCount()
+ {
+ return _enqueueCount.get();
+ }
+
private void incrementQueueCount()
{
getAtomicQueueCount().incrementAndGet();
}
-
+
private void incrementTxnEnqueueStats(final ServerMessage message)
{
_msgTxnEnqueues.incrementAndGet();
_byteTxnEnqueues.addAndGet(message.getSize());
}
-
+
private void incrementTxnDequeueStats(QueueEntry entry)
- {
+ {
_msgTxnDequeues.incrementAndGet();
_byteTxnDequeues.addAndGet(entry.getSize());
}
@@ -819,7 +849,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
setLastSeenEntry(sub, entry);
_deliveredMessages.incrementAndGet();
- incrementUnackedMsgCount();
+ incrementUnackedMsgCount(entry);
sub.send(entry, batch);
}
@@ -887,7 +917,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
_deliveredMessages.decrementAndGet();
}
-
+
if(sub != null && sub.isSessionTransactional())
{
incrementTxnDequeueStats(entry);
@@ -940,11 +970,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
}
+
+
public int getConsumerCount()
{
return _subscriptionList.size();
}
-
+
public int getConsumerCountHigh()
{
return _counsumerCountHigh.get();
@@ -1148,7 +1180,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
- public void visit(final Visitor visitor)
+ public void visit(final QueueEntryVisitor visitor)
{
QueueEntryIterator queueListIterator = _entries.iterator();
@@ -1195,192 +1227,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
- public void moveMessagesToAnotherQueue(final long fromMessageId,
- final long toMessageId,
- String destinationQueueName) throws IllegalArgumentException
- {
-
- final AMQQueue toQueue = getValidatedDestinationQueue(destinationQueueName);
-
- List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter()
- {
-
- public boolean accept(QueueEntry entry)
- {
- final long messageId = entry.getMessage().getMessageNumber();
- return (messageId >= fromMessageId)
- && (messageId <= toMessageId)
- && entry.acquire();
- }
-
- public boolean filterComplete()
- {
- return false;
- }
- });
-
-
- final ServerTransaction txn = new LocalTransaction(getVirtualHost().getMessageStore());
- boolean shouldRollback = true;
- try
- {
- // Move the messages in on the message store.
- for (final QueueEntry entry : entries)
- {
- final ServerMessage message = entry.getMessage();
- txn.enqueue(toQueue, message,
- new ServerTransaction.Action()
- {
-
- public void postCommit()
- {
- try
- {
- toQueue.enqueue(message);
- }
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- public void onRollback()
- {
- entry.release();
- }
- });
- txn.dequeue(this, message,
- new ServerTransaction.Action()
- {
-
- public void postCommit()
- {
- entry.discard();
- }
-
- public void onRollback()
- {
-
- }
- });
- }
- txn.commit();
- shouldRollback = false;
- }
- finally
- {
- if (shouldRollback)
- {
- txn.rollback();
- }
- }
-
- }
-
- public void copyMessagesToAnotherQueue(final long fromMessageId,
- final long toMessageId,
- String destinationQueueName) throws IllegalArgumentException
- {
- final AMQQueue toQueue = getValidatedDestinationQueue(destinationQueueName);
-
- List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter()
- {
-
- public boolean accept(QueueEntry entry)
- {
- final long messageId = entry.getMessage().getMessageNumber();
- return ((messageId >= fromMessageId)
- && (messageId <= toMessageId));
- }
-
- public boolean filterComplete()
- {
- return false;
- }
- });
-
- final ServerTransaction txn = new LocalTransaction(_virtualHost.getMessageStore());
- boolean shouldRollback = true;
- try
- {
- // Copy the messages in on the message store.
- for (QueueEntry entry : entries)
- {
- final ServerMessage message = entry.getMessage();
-
- txn.enqueue(toQueue, message, new ServerTransaction.Action()
- {
- public void postCommit()
- {
- try
- {
- toQueue.enqueue(message);
- }
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- public void onRollback()
- {
- }
- });
-
- }
-
- txn.commit();
- shouldRollback = false;
- }
- finally
- {
- if (shouldRollback)
- {
- txn.rollback();
- }
- }
-
- }
-
- private AMQQueue getValidatedDestinationQueue(String queueName)
- {
- final AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName));
- if (toQueue == null)
- {
- throw new IllegalArgumentException("Queue '" + queueName + "' is not registered with the virtualhost.");
- }
- else if (toQueue == this)
- {
- throw new IllegalArgumentException("The destination queue can't be the same as the source queue");
- }
- return toQueue;
- }
-
- public void removeMessagesFromQueue(long fromMessageId, long toMessageId)
- {
-
- QueueEntryIterator queueListIterator = _entries.iterator();
-
- while (queueListIterator.advance())
- {
- QueueEntry node = queueListIterator.getNode();
-
- final ServerMessage message = node.getMessage();
- if(message != null)
- {
- final long messageId = message.getMessageNumber();
-
- if ((messageId >= fromMessageId)
- && (messageId <= toMessageId)
- && node.acquire())
- {
- dequeueEntry(node);
- }
- }
- }
-
- }
-
public void purge(final long request) throws AMQException
{
clear(request);
@@ -1393,6 +1239,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
// ------ Management functions
+ // TODO - now only used by the tests
public void deleteMessageFromTop()
{
QueueEntryIterator queueListIterator = _entries.iterator();
@@ -1411,7 +1258,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
public long clearQueue() throws AMQException
- {
+ {
return clear(0l);
}
@@ -1422,7 +1269,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
throw new AMQSecurityException("Permission denied: queue " + getName());
}
-
+
QueueEntryIterator queueListIterator = _entries.iterator();
long count = 0;
@@ -1489,7 +1336,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
throw new AMQSecurityException("Permission denied: " + getName());
}
-
+
if (!_deleted.getAndSet(true))
{
@@ -1617,12 +1464,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
txn.commit();
-
- if(_managedObject!=null)
- {
- _managedObject.unregister();
- }
-
for (Task task : _deleteTaskList)
{
task.doTask(this);
@@ -2101,16 +1942,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
else
{
- if (_managedObject != null)
+ // There is a chance that the node could be deleted by
+ // the time the check actually occurs. So verify we
+ // can actually get the message to perform the check.
+ ServerMessage msg = node.getMessage();
+ if (msg != null)
{
- // There is a chance that the node could be deleted by
- // the time the check actually occurs. So verify we
- // can actually get the message to perform the check.
- ServerMessage msg = node.getMessage();
- if (msg != null)
- {
- _managedObject.checkForNotification(msg);
- }
+ checkForNotification(msg);
}
}
}
@@ -2235,11 +2073,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
return _notificationChecks;
}
- public ManagedObject getManagedObject()
- {
- return _managedObject;
- }
-
private final class QueueEntryListener implements QueueEntry.StateChangeListener
{
@@ -2330,12 +2163,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
return _queueConfiguration;
}
- public String getResourceName()
- {
- return _resourceName;
- }
-
-
public ConfigStore getConfigStore()
{
return getVirtualHost().getConfigStore();
@@ -2355,22 +2182,22 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
return _dequeueSize.get();
}
-
+
public long getByteTxnEnqueues()
{
return _byteTxnEnqueues.get();
}
-
+
public long getByteTxnDequeues()
{
return _byteTxnDequeues.get();
}
-
+
public long getMsgTxnEnqueues()
{
return _msgTxnEnqueues.get();
}
-
+
public long getMsgTxnDequeues()
{
return _msgTxnDequeues.get();
@@ -2407,21 +2234,28 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
return _unackedMsgCountHigh.get();
}
-
+
public long getUnackedMessageCount()
{
return _unackedMsgCount.get();
}
-
- public void decrementUnackedMsgCount()
+
+ public long getUnackedMessageBytes()
+ {
+ return _unackedMsgBytes.get();
+ }
+
+ public void decrementUnackedMsgCount(QueueEntry queueEntry)
{
_unackedMsgCount.decrementAndGet();
+ _unackedMsgBytes.addAndGet(-queueEntry.getSize());
}
-
- private void incrementUnackedMsgCount()
+
+ private void incrementUnackedMsgCount(QueueEntry entry)
{
long unackedMsgCount = _unackedMsgCount.incrementAndGet();
-
+ _unackedMsgBytes.addAndGet(entry.getSize());
+
long unackedMsgCountHigh;
while(unackedMsgCount > (unackedMsgCountHigh = _unackedMsgCountHigh.get()))
{
@@ -2447,4 +2281,54 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
_maximumDeliveryCount = maximumDeliveryCount;
}
+ /**
+ * Checks if there is any notification to send to the listeners
+ */
+ private void checkForNotification(ServerMessage<?> msg) throws AMQException
+ {
+ final Set<NotificationCheck> notificationChecks = getNotificationChecks();
+ final AMQQueue.NotificationListener listener = _notificationListener;
+
+ if(listener != null && !notificationChecks.isEmpty())
+ {
+ final long currentTime = System.currentTimeMillis();
+ final long thresholdTime = currentTime - getMinimumAlertRepeatGap();
+
+ for (NotificationCheck check : notificationChecks)
+ {
+ if (check.isMessageSpecific() || (_lastNotificationTimes[check.ordinal()] < thresholdTime))
+ {
+ if (check.notifyIfNecessary(msg, this, listener))
+ {
+ _lastNotificationTimes[check.ordinal()] = currentTime;
+ }
+ }
+ }
+ }
+ }
+
+ public void setNotificationListener(AMQQueue.NotificationListener listener)
+ {
+ _notificationListener = listener;
+ }
+
+ @Override
+ public void setDescription(String description)
+ {
+ if (description == null)
+ {
+ _arguments.remove(AMQQueueFactory.X_QPID_DESCRIPTION);
+ }
+ else
+ {
+ _arguments.put(AMQQueueFactory.X_QPID_DESCRIPTION, description);
+ }
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return (String) _arguments.get(AMQQueueFactory.X_QPID_DESCRIPTION);
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 80a91be262..10c69b7f97 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -22,9 +22,9 @@ package org.apache.qpid.server.registry;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.*;
import org.osgi.framework.BundleContext;
-import org.apache.qpid.AMQException;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.qmf.QMFService;
@@ -35,18 +35,13 @@ import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.SystemConfig;
import org.apache.qpid.server.configuration.SystemConfigImpl;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.logging.CompositeStartupMessageLogger;
-import org.apache.qpid.server.logging.Log4jMessageLogger;
-import org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.logging.RootMessageLogger;
-import org.apache.qpid.server.logging.SystemOutMessageLogger;
import org.apache.qpid.server.logging.actors.AbstractActor;
import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.logging.messages.VirtualHostMessages;
-import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.management.NoopManagedObjectRegistry;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.adapter.BrokerAdapter;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
@@ -72,6 +67,7 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public abstract class ApplicationRegistry implements IApplicationRegistry
{
+
private static final Logger _logger = Logger.getLogger(ApplicationRegistry.class);
private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null);
@@ -81,11 +77,9 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private final Map<InetSocketAddress, QpidAcceptor> _acceptors =
Collections.synchronizedMap(new HashMap<InetSocketAddress, QpidAcceptor>());
- private ManagedObjectRegistry _managedObjectRegistry;
-
private IAuthenticationManagerRegistry _authenticationManagerRegistry;
- private VirtualHostRegistry _virtualHostRegistry;
+ private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(this);
private SecurityManager _securityManager;
@@ -101,30 +95,32 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private QMFService _qmfService;
- private BrokerConfig _broker;
+ private BrokerConfig _brokerConfig;
+
+ private Broker _broker;
private ConfigStore _configStore;
-
+
private Timer _reportingTimer;
- private boolean _statisticsEnabled = false;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private BundleContext _bundleContext;
+ private final List<PortBindingListener> _portBindingListeners = new ArrayList<PortBindingListener>();
- protected Map<InetSocketAddress, QpidAcceptor> getAcceptors()
- {
- return _acceptors;
- }
+ private int _httpManagementPort = -1;
- protected void setManagedObjectRegistry(ManagedObjectRegistry managedObjectRegistry)
- {
- _managedObjectRegistry = managedObjectRegistry;
- }
+ private LogRecorder _logRecorder;
+
+ private List<IAuthenticationManagerRegistry.RegistryChangeListener> _authManagerChangeListeners =
+ new ArrayList<IAuthenticationManagerRegistry.RegistryChangeListener>();
- protected void setVirtualHostRegistry(VirtualHostRegistry virtualHostRegistry)
+ public Map<InetSocketAddress, QpidAcceptor> getAcceptors()
{
- _virtualHostRegistry = virtualHostRegistry;
+ synchronized (_acceptors)
+ {
+ return new HashMap<InetSocketAddress, QpidAcceptor>(_acceptors);
+ }
}
protected void setSecurityManager(SecurityManager securityManager)
@@ -191,11 +187,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
store.setRoot(new SystemConfigImpl(store));
instance.setConfigStore(store);
- BrokerConfig broker = new BrokerConfigAdapter(instance);
+ final BrokerConfig brokerConfig = new BrokerConfigAdapter(instance);
- SystemConfig system = store.getRoot();
- system.addBroker(broker);
- instance.setBroker(broker);
+ final SystemConfig system = store.getRoot();
+ system.addBroker(brokerConfig);
+ instance.setBrokerConfig(brokerConfig);
try
{
@@ -208,7 +204,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
//remove the Broker instance, then re-throw
try
{
- system.removeBroker(broker);
+ system.removeBroker(brokerConfig);
}
catch(Throwable t)
{
@@ -283,18 +279,28 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
public void initialise() throws Exception
{
+ _logRecorder = new LogRecorder();
//Create the RootLogger to be used during broker operation
_rootMessageLogger = new Log4jMessageLogger(_configuration);
//Create the composite (log4j+SystemOut MessageLogger to be used during startup
RootMessageLogger[] messageLoggers = {new SystemOutMessageLogger(), _rootMessageLogger};
_startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers);
-
- CurrentActor.set(new BrokerActor(_startupMessageLogger));
+
+ BrokerActor actor = new BrokerActor(_startupMessageLogger);
+ CurrentActor.setDefault(actor);
+ CurrentActor.set(actor);
try
{
- initialiseManagedObjectRegistry();
+ initialiseStatistics();
+
+ if(_configuration.getHTTPManagementEnabled())
+ {
+ _httpManagementPort = _configuration.getHTTPManagementPort();
+ }
+
+ _broker = new BrokerAdapter(this);
configure();
@@ -302,13 +308,23 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
logStartupMessages(CurrentActor.get());
- _virtualHostRegistry = new VirtualHostRegistry(this);
-
_securityManager = new SecurityManager(_configuration, _pluginManager);
_authenticationManagerRegistry = createAuthenticationManagerRegistry(_configuration, _pluginManager);
- _managedObjectRegistry.start();
+ if(!_authManagerChangeListeners.isEmpty())
+ {
+ for(IAuthenticationManagerRegistry.RegistryChangeListener listener : _authManagerChangeListeners)
+ {
+
+ _authenticationManagerRegistry.addRegistryChangeListener(listener);
+ for(AuthenticationManager authMgr : _authenticationManagerRegistry.getAvailableAuthenticationManagers().values())
+ {
+ listener.authenticationManagerRegistered(authMgr);
+ }
+ }
+ _authManagerChangeListeners.clear();
+ }
}
finally
{
@@ -319,7 +335,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
initialiseVirtualHosts();
- initialiseStatistics();
initialiseStatisticsReporting();
}
finally
@@ -344,23 +359,18 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost());
}
- protected void initialiseManagedObjectRegistry() throws AMQException
- {
- _managedObjectRegistry = new NoopManagedObjectRegistry();
- }
-
public void initialiseStatisticsReporting()
{
long report = _configuration.getStatisticsReportingPeriod() * 1000; // convert to ms
final boolean broker = _configuration.isStatisticsGenerationBrokerEnabled();
final boolean virtualhost = _configuration.isStatisticsGenerationVirtualhostsEnabled();
final boolean reset = _configuration.isStatisticsReportResetEnabled();
-
+
/* add a timer task to report statistics if generation is enabled for broker or virtualhosts */
if (report > 0L && (broker || virtualhost))
{
_reportingTimer = new Timer("Statistics-Reporting", true);
-
+
_reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(broker, virtualhost, reset),
@@ -495,9 +505,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
close(_pluginManager);
- close(_managedObjectRegistry);
-
- BrokerConfig broker = getBroker();
+ BrokerConfig broker = getBrokerConfig();
if(broker != null)
{
broker.getSystem().removeBroker(broker);
@@ -513,12 +521,14 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private void unbind()
{
+ List<QpidAcceptor> removedAcceptors = new ArrayList<QpidAcceptor>();
synchronized (_acceptors)
{
for (InetSocketAddress bindAddress : _acceptors.keySet())
{
QpidAcceptor acceptor = _acceptors.get(bindAddress);
+ removedAcceptors.add(acceptor);
try
{
acceptor.getNetworkTransport().close();
@@ -531,6 +541,16 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(acceptor.toString(), bindAddress.getPort()));
}
}
+ synchronized (_portBindingListeners)
+ {
+ for(QpidAcceptor acceptor : removedAcceptors)
+ {
+ for(PortBindingListener listener : _portBindingListeners)
+ {
+ listener.unbound(acceptor);
+ }
+ }
+ }
}
public ServerConfiguration getConfiguration()
@@ -544,6 +564,13 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_acceptors.put(bindAddress, acceptor);
}
+ synchronized (_portBindingListeners)
+ {
+ for(PortBindingListener listener : _portBindingListeners)
+ {
+ listener.bound(acceptor, bindAddress);
+ }
+ }
}
public VirtualHostRegistry getVirtualHostRegistry()
@@ -556,15 +583,16 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _securityManager;
}
- public ManagedObjectRegistry getManagedObjectRegistry()
+ @Override
+ public AuthenticationManager getAuthenticationManager(SocketAddress address)
{
- return _managedObjectRegistry;
+ return _authenticationManagerRegistry.getAuthenticationManager(address);
}
@Override
- public AuthenticationManager getAuthenticationManager(SocketAddress address)
+ public IAuthenticationManagerRegistry getAuthenticationManagerRegistry()
{
- return _authenticationManagerRegistry.getAuthenticationManager(address);
+ return _authenticationManagerRegistry;
}
public PluginManager getPluginManager()
@@ -581,7 +609,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
return _rootMessageLogger;
}
-
+
public RootMessageLogger getCompositeStartupMessageLogger()
{
return _startupMessageLogger;
@@ -597,69 +625,63 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _qmfService;
}
- public BrokerConfig getBroker()
+ public BrokerConfig getBrokerConfig()
{
- return _broker;
+ return _brokerConfig;
}
- public void setBroker(final BrokerConfig broker)
+ public void setBrokerConfig(final BrokerConfig broker)
{
- _broker = broker;
+ _brokerConfig = broker;
}
public VirtualHost createVirtualHost(final VirtualHostConfiguration vhostConfig) throws Exception
{
VirtualHostImpl virtualHost = new VirtualHostImpl(this, vhostConfig);
_virtualHostRegistry.registerVirtualHost(virtualHost);
- getBroker().addVirtualHost(virtualHost);
+ getBrokerConfig().addVirtualHost(virtualHost);
return virtualHost;
}
-
+
public void registerMessageDelivered(long messageSize)
{
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
+ _messagesDelivered.registerEvent(1L);
+ _dataDelivered.registerEvent(messageSize);
}
-
+
public void registerMessageReceived(long messageSize, long timestamp)
{
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
+ _messagesReceived.registerEvent(1L, timestamp);
+ _dataReceived.registerEvent(messageSize, timestamp);
}
-
+
public StatisticsCounter getMessageReceiptStatistics()
{
return _messagesReceived;
}
-
+
public StatisticsCounter getDataReceiptStatistics()
{
return _dataReceived;
}
-
+
public StatisticsCounter getMessageDeliveryStatistics()
{
return _messagesDelivered;
}
-
+
public StatisticsCounter getDataDeliveryStatistics()
{
return _dataDelivered;
}
-
+
public void resetStatistics()
{
_messagesDelivered.reset();
_dataDelivered.reset();
_messagesReceived.reset();
_dataReceived.reset();
-
+
for (VirtualHost vhost : _virtualHostRegistry.getVirtualHosts())
{
vhost.resetStatistics();
@@ -668,25 +690,12 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
public void initialiseStatistics()
{
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- getConfiguration().isStatisticsGenerationBrokerEnabled());
-
_messagesDelivered = new StatisticsCounter("messages-delivered");
_dataDelivered = new StatisticsCounter("bytes-delivered");
_messagesReceived = new StatisticsCounter("messages-received");
_dataReceived = new StatisticsCounter("bytes-received");
}
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
-
private void logStartupMessages(LogActor logActor)
{
logActor.message(BrokerMessages.STARTUP(QpidProperties.getReleaseVersion(), QpidProperties.getBuildVersion()));
@@ -700,4 +709,48 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
logActor.message(BrokerMessages.MAX_MEMORY(Runtime.getRuntime().maxMemory()));
}
+ public Broker getBroker()
+ {
+ return _broker;
+ }
+
+ @Override
+ public void addPortBindingListener(PortBindingListener listener)
+ {
+ synchronized (_portBindingListeners)
+ {
+ _portBindingListeners.add(listener);
+ }
+ }
+
+
+ @Override
+ public boolean useHTTPManagement()
+ {
+ return _httpManagementPort != -1;
+ }
+
+ @Override
+ public int getHTTPManagementPort()
+ {
+ return _httpManagementPort;
+ }
+
+ public LogRecorder getLogRecorder()
+ {
+ return _logRecorder;
+ }
+
+ @Override
+ public void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener)
+ {
+ if(_authenticationManagerRegistry == null)
+ {
+ _authManagerChangeListeners.add(registryChangeListener);
+ }
+ else
+ {
+ _authenticationManagerRegistry.addRegistryChangeListener(registryChangeListener);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index b28e3d6c89..774d0338ef 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
@@ -25,8 +25,6 @@ import org.osgi.framework.BundleContext;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.management.JMXManagedObjectRegistry;
-import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import java.io.File;
@@ -41,18 +39,4 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
super(new ServerConfiguration(configurationURL), bundleContext);
}
-
- @Override
- protected void initialiseManagedObjectRegistry() throws AMQException
- {
- if (getConfiguration().getManagementEnabled())
- {
- setManagedObjectRegistry(new JMXManagedObjectRegistry());
- }
- else
- {
- setManagedObjectRegistry(new NoopManagedObjectRegistry());
- }
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index 35e7fe3f61..2baf7ed5ee 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -27,10 +27,11 @@ import org.apache.qpid.server.configuration.ConfigurationManager;
import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.logging.RootMessageLogger;
-import org.apache.qpid.server.management.ManagedObjectRegistry;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -38,6 +39,7 @@ import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.util.Map;
import java.util.UUID;
public interface IApplicationRegistry extends StatisticsGatherer
@@ -61,8 +63,6 @@ public interface IApplicationRegistry extends StatisticsGatherer
*/
ServerConfiguration getConfiguration();
- ManagedObjectRegistry getManagedObjectRegistry();
-
/**
* Get the AuthenticationManager for the given socket address
*
@@ -74,6 +74,8 @@ public interface IApplicationRegistry extends StatisticsGatherer
*/
AuthenticationManager getAuthenticationManager(SocketAddress address);
+ IAuthenticationManagerRegistry getAuthenticationManagerRegistry();
+
VirtualHostRegistry getVirtualHostRegistry();
SecurityManager getSecurityManager();
@@ -95,15 +97,35 @@ public interface IApplicationRegistry extends StatisticsGatherer
QMFService getQMFService();
- void setBroker(BrokerConfig broker);
+ void setBrokerConfig(BrokerConfig broker);
+
+ BrokerConfig getBrokerConfig();
- BrokerConfig getBroker();
+ Broker getBroker();
VirtualHost createVirtualHost(VirtualHostConfiguration vhostConfig) throws Exception;
ConfigStore getConfigStore();
void setConfigStore(ConfigStore store);
-
+
void initialiseStatisticsReporting();
+
+ Map<InetSocketAddress, QpidAcceptor> getAcceptors();
+
+ void addPortBindingListener(PortBindingListener listener);
+
+ boolean useHTTPManagement();
+
+ int getHTTPManagementPort();
+
+ void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener);
+
+ public interface PortBindingListener
+ {
+ public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress);
+ public void unbound(QpidAcceptor acceptor);
+
+ }
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
index 7088fae50c..cac60a5283 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
@@ -198,7 +198,7 @@ public abstract class AbstractPasswordFilePrincipalDatabase<U extends PasswordPr
try
{
_userUpdate.lock();
- _userMap.clear();
+ final Map<String, U> newUserMap = new HashMap<String, U>();
BufferedReader reader = null;
try
@@ -216,7 +216,7 @@ public abstract class AbstractPasswordFilePrincipalDatabase<U extends PasswordPr
U user = createUserFromFileData(result);
getLogger().info("Created user:" + user);
- _userMap.put(user.getName(), user);
+ newUserMap.put(user.getName(), user);
}
}
finally
@@ -226,6 +226,9 @@ public abstract class AbstractPasswordFilePrincipalDatabase<U extends PasswordPr
reader.close();
}
}
+
+ _userMap.clear();
+ _userMap.putAll(newUserMap);
}
finally
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
deleted file mode 100644
index 1314a5d6a6..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.security.auth.management;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-
-import javax.management.JMException;
-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.auth.login.AccountNotFoundException;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.List;
-
-/** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */
-@MBeanDescription("User Management Interface")
-public class AMQUserManagementMBean extends AMQManagedObject implements UserManagement
-{
- private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
-
- private PrincipalDatabase _principalDatabase;
-
- // Setup for the TabularType
- private static final TabularType _userlistDataType; // Datatype for representing User Lists
- private static final CompositeType _userDataType; // Composite type for representing User
-
- static
- {
- OpenType[] userItemTypes = new OpenType[4]; // User item types.
- userItemTypes[0] = SimpleType.STRING; // For Username
- userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read - No longer in use
- userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write - No longer in use
- userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin - No longer is use
-
- try
- {
- _userDataType =
- new CompositeType("User", "User Data", COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]),
- COMPOSITE_ITEM_DESCRIPTIONS.toArray(new String[COMPOSITE_ITEM_DESCRIPTIONS.size()]), userItemTypes);
-
- _userlistDataType = new TabularType("Users", "List of users", _userDataType, TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()]));
- }
- catch (OpenDataException e)
- {
- _logger.error("Tabular data setup for viewing users incorrect.", e);
- throw new ExceptionInInitializerError("Tabular data setup for viewing users incorrect");
- }
- }
-
- public AMQUserManagementMBean() throws JMException
- {
- super(UserManagement.class, UserManagement.TYPE);
- }
-
- public String getObjectInstanceName()
- {
- return UserManagement.TYPE;
- }
-
- public boolean setPassword(String username, String password)
- {
- try
- {
- //delegate password changes to the Principal Database
- return _principalDatabase.updatePassword(new UsernamePrincipal(username), password.toCharArray());
- }
- catch (AccountNotFoundException e)
- {
- _logger.warn("Attempt to set password of non-existent user'" + username + "'");
- return false;
- }
- }
-
- public boolean createUser(String username, String password)
- {
- if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password.toCharArray()))
- {
- return true;
- }
-
- return false;
- }
-
- public boolean deleteUser(String username)
- {
- try
- {
- _principalDatabase.deletePrincipal(new UsernamePrincipal(username));
- }
- catch (AccountNotFoundException e)
- {
- _logger.warn("Attempt to delete user (" + username + ") that doesn't exist");
- return false;
- }
-
- return true;
- }
-
- public boolean reloadData()
- {
- try
- {
- _principalDatabase.reload();
- }
- catch (IOException e)
- {
- _logger.warn("Reload failed due to:", e);
- return false;
- }
- // Reload successful
- return true;
- }
-
-
- @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.")
- public TabularData viewUsers()
- {
- List<Principal> users = _principalDatabase.getUsers();
-
- TabularDataSupport userList = new TabularDataSupport(_userlistDataType);
-
- try
- {
- // Create the tabular list of message header contents
- for (Principal user : users)
- {
- // Create header attributes list
- // Read,Write,Admin items are depcreated and we return always false.
- Object[] itemData = {user.getName(), false, false, false};
- CompositeData messageData = new CompositeDataSupport(_userDataType, COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
- userList.put(messageData);
- }
- }
- catch (OpenDataException e)
- {
- _logger.warn("Unable to create user list due to :", e);
- return null;
- }
-
- return userList;
- }
-
- /*** Broker Methods **/
-
- /**
- * setPrincipalDatabase
- *
- * @param database set The Database to use for user lookup
- */
- public void setPrincipalDatabase(PrincipalDatabase database)
- {
- _principalDatabase = database;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java
index 0eb3963865..5676c43754 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java
@@ -47,7 +47,7 @@ public class AnonymousAuthenticationManager implements AuthenticationManager
private static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal("ANONYMOUS");
- private static final Subject ANONYMOUS_SUBJECT = new Subject();
+ public static final Subject ANONYMOUS_SUBJECT = new Subject();
static
{
ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
index 3a1ca4f19d..89a4d8ae66 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
@@ -21,9 +21,12 @@ package org.apache.qpid.server.security.auth.manager;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import org.apache.commons.configuration.ConfigurationException;
@@ -49,6 +52,8 @@ public class AuthenticationManagerRegistry implements Closeable, IAuthentication
private final Map<String,AuthenticationManager> _classToAuthManagerMap = new HashMap<String,AuthenticationManager>();
private final AuthenticationManager _defaultAuthenticationManager;
private final Map<Integer,AuthenticationManager> _portToAuthenticationManagerMap;
+ private final List<RegistryChangeListener> _listeners =
+ Collections.synchronizedList(new ArrayList<RegistryChangeListener>());
public AuthenticationManagerRegistry(ServerConfiguration serverConfiguration, PluginManager _pluginManager)
throws ConfigurationException
@@ -114,9 +119,8 @@ public class AuthenticationManagerRegistry implements Closeable, IAuthentication
final SecurityConfiguration securityConfiguration)
throws ConfigurationException
{
- for (final Iterator<AuthenticationManagerPluginFactory<? extends Plugin>> iterator = factories.iterator(); iterator.hasNext();)
+ for(AuthenticationManagerPluginFactory<? extends Plugin> factory : factories)
{
- final AuthenticationManagerPluginFactory<? extends Plugin> factory = (AuthenticationManagerPluginFactory<? extends Plugin>) iterator.next();
final AuthenticationManager tmp = factory.newInstance(securityConfiguration);
if (tmp != null)
{
@@ -127,6 +131,11 @@ public class AuthenticationManagerRegistry implements Closeable, IAuthentication
+ " Remove configuration for one of the authentication managers.");
}
_classToAuthManagerMap.put(tmp.getClass().getSimpleName(),tmp);
+
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.authenticationManagerRegistered(tmp);
+ }
}
}
}
@@ -179,5 +188,16 @@ public class AuthenticationManagerRegistry implements Closeable, IAuthentication
return portToAuthenticationManagerMap;
}
+ @Override
+ public Map<String, AuthenticationManager> getAvailableAuthenticationManagers()
+ {
+ return Collections.unmodifiableMap(new HashMap<String, AuthenticationManager>(_classToAuthManagerMap));
+ }
+
+ @Override
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ _listeners.add(listener);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java
index bfb49b8ed6..485ca2e1e9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java
@@ -21,7 +21,9 @@ package org.apache.qpid.server.security.auth.manager;
import java.net.SocketAddress;
+import java.util.Map;
import org.apache.qpid.common.Closeable;
+import org.apache.qpid.server.virtualhost.VirtualHost;
/**
* Registry for {@link AuthenticationManager} instances.
@@ -43,4 +45,15 @@ public interface IAuthenticationManagerRegistry extends Closeable
* @return authentication manager.
*/
public AuthenticationManager getAuthenticationManager(SocketAddress address);
+
+ Map<String, AuthenticationManager> getAvailableAuthenticationManagers();
+
+ public static interface RegistryChangeListener
+ {
+ void authenticationManagerRegistered(AuthenticationManager authenticationManager);
+ void authenticationManagerUnregistered(AuthenticationManager authenticationManager);
+ }
+
+ public void addRegistryChangeListener(RegistryChangeListener listener);
+
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 24b365d34c..e6498919a1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -32,7 +32,6 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.JCAProvider;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
@@ -98,8 +97,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private PrincipalDatabase _principalDatabase = null;
- private AMQUserManagementMBean _mbean = null;
-
public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>()
{
public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
@@ -211,8 +208,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_logger.warn("No additional SASL providers registered.");
}
-
- registerManagement();
}
private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database)
@@ -332,8 +327,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_mechanisms = null;
Security.removeProvider(PROVIDER_NAME);
-
- unregisterManagement();
}
private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException
@@ -407,6 +400,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
}
}
+ public PrincipalDatabase getPrincipalDatabase()
+ {
+ return _principalDatabase;
+ }
+
private String generateSetterName(String argName) throws ConfigurationException
{
if ((argName == null) || (argName.length() == 0))
@@ -427,41 +425,4 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_principalDatabase = principalDatabase;
}
-
- protected void registerManagement()
- {
- try
- {
- _logger.info("Registering UserManagementMBean");
-
- _mbean = new AMQUserManagementMBean();
- _mbean.setPrincipalDatabase(_principalDatabase);
- _mbean.register();
- }
- catch (Exception e)
- {
- _logger.warn("User management disabled as unable to create MBean:", e);
- _mbean = null;
- }
- }
-
- protected void unregisterManagement()
- {
- try
- {
- if (_mbean != null)
- {
- _logger.info("Unregistering UserManagementMBean");
- _mbean.unregister();
- }
- }
- catch (Exception e)
- {
- _logger.warn("Failed to unregister User management MBean:", e);
- }
- finally
- {
- _mbean = null;
- }
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index e27fd99f90..2e21cfbb07 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,6 +20,9 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.net.SocketAddress;
+
+import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
@@ -37,11 +40,13 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String INVALID_CREDENTIALS = "Invalid user details supplied";
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
-
+
private AuthenticationManager _authenticationManager = null;
+ private SocketAddress _socketAddress;
- public RMIPasswordAuthenticator()
+ public RMIPasswordAuthenticator(SocketAddress socketAddress)
{
+ _socketAddress = socketAddress;
}
public void setAuthenticationManager(final AuthenticationManager authenticationManager)
@@ -79,11 +84,25 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
{
throw new SecurityException(SHOULD_BE_NON_NULL);
}
-
+
// Verify that an AuthenticationManager has been set.
if (_authenticationManager == null)
{
- throw new SecurityException(UNABLE_TO_LOOKUP);
+ try
+ {
+ if(ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress) != null)
+ {
+ _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress);
+ }
+ else
+ {
+ throw new SecurityException(UNABLE_TO_LOOKUP);
+ }
+ }
+ catch(IllegalStateException e)
+ {
+ throw new SecurityException(UNABLE_TO_LOOKUP);
+ }
}
final AuthenticationResult result = _authenticationManager.authenticate(username, password);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
index 2bd17cfa2f..f382f90010 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
@@ -33,8 +33,7 @@ public class StatisticsCounter
private static final Logger _log = LoggerFactory.getLogger(StatisticsCounter.class);
public static final long DEFAULT_SAMPLE_PERIOD = Long.getLong("qpid.statistics.samplePeriod", 2000L); // 2s
- public static final boolean DISABLE_STATISTICS = Boolean.getBoolean("qpid.statistics.disable");
-
+
private static final String COUNTER = "counter";
private static final AtomicLong _counterIds = new AtomicLong(0L);
@@ -78,11 +77,6 @@ public class StatisticsCounter
public void registerEvent(long value, long timestamp)
{
- if (DISABLE_STATISTICS)
- {
- return;
- }
-
long thisSample = (timestamp / _period);
synchronized (this)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
index 36fec4025a..37d87bb628 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
@@ -103,16 +103,4 @@ public interface StatisticsGatherer
* Reset the counters for this, and any child {@link StatisticsGatherer}s.
*/
void resetStatistics();
-
- /**
- * Check if this object has statistics generation enabled.
- *
- * @return true if statistics generation is enabled
- */
- boolean isStatisticsEnabled();
-
- /**
- * Enable or disable statistics generation for this object.
- */
- void setStatisticsEnabled(boolean enabled);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
index 1307b1dbd4..f1053f60ad 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
@@ -32,7 +32,7 @@ public interface ConfigurationRecoveryHandler
public static interface QueueRecoveryHandler
{
- void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments);
+ void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments, UUID alternateExchangeId);
ExchangeRecoveryHandler completeQueueRecovery();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java
index 1a67fdf540..7356e1ae83 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java
@@ -40,12 +40,7 @@ import org.apache.qpid.server.util.MapJsonSerializer;
public class ConfiguredObjectHelper
{
- /**
- * Name of queue attribute to store queue creation arguments.
- * <p>
- * This attribute is not defined yet on Queue configured object interface.
- */
- private static final String QUEUE_ARGUMENTS = "ARGUMENTS";
+
private MapJsonSerializer _serializer = new MapJsonSerializer();
@@ -57,14 +52,15 @@ public class ConfiguredObjectHelper
String queueName = (String) attributeMap.get(Queue.NAME);
String owner = (String) attributeMap.get(Queue.OWNER);
boolean exclusive = (Boolean) attributeMap.get(Queue.EXCLUSIVE);
+ UUID alternateExchangeId = attributeMap.get(Queue.ALTERNATE_EXCHANGE) == null ? null : UUID.fromString((String)attributeMap.get(Queue.ALTERNATE_EXCHANGE));
@SuppressWarnings("unchecked")
- Map<String, Object> queueArgumentsMap = (Map<String, Object>) attributeMap.get(QUEUE_ARGUMENTS);
+ Map<String, Object> queueArgumentsMap = (Map<String, Object>) attributeMap.get(Queue.ARGUMENTS);
FieldTable arguments = null;
if (queueArgumentsMap != null)
{
arguments = FieldTable.convertToFieldTable(queueArgumentsMap);
}
- qrh.queue(configuredObject.getId(), queueName, owner, exclusive, arguments);
+ qrh.queue(configuredObject.getId(), queueName, owner, exclusive, arguments, alternateExchangeId);
}
}
@@ -73,6 +69,24 @@ public class ConfiguredObjectHelper
Map<String, Object> attributesMap = _serializer.deserialize(queueRecord.getAttributes());
attributesMap.put(Queue.NAME, queue.getName());
attributesMap.put(Queue.EXCLUSIVE, queue.isExclusive());
+ if (queue.getAlternateExchange() != null)
+ {
+ attributesMap.put(Queue.ALTERNATE_EXCHANGE, queue.getAlternateExchange().getId());
+ }
+ else
+ {
+ attributesMap.remove(Queue.ALTERNATE_EXCHANGE);
+ }
+ if (attributesMap.containsKey(Queue.ARGUMENTS))
+ {
+ // We wouldn't need this if createQueueConfiguredObject took only AMQQueue
+ Map<String, Object> currentArgs = (Map<String, Object>) attributesMap.get(Queue.ARGUMENTS);
+ currentArgs.putAll(queue.getArguments());
+ }
+ else
+ {
+ attributesMap.put(Queue.ARGUMENTS, queue.getArguments());
+ }
String newJson = _serializer.serialize(attributesMap);
ConfiguredObjectRecord newQueueRecord = new ConfiguredObjectRecord(queue.getId(), queueRecord.getType(), newJson);
return newQueueRecord;
@@ -84,9 +98,15 @@ public class ConfiguredObjectHelper
attributesMap.put(Queue.NAME, queue.getName());
attributesMap.put(Queue.OWNER, AMQShortString.toString(queue.getOwner()));
attributesMap.put(Queue.EXCLUSIVE, queue.isExclusive());
+ if (queue.getAlternateExchange() != null)
+ {
+ attributesMap.put(Queue.ALTERNATE_EXCHANGE, queue.getAlternateExchange().getId());
+ }
+ // TODO KW i think the arguments could come from the queue itself removing the need for the parameter arguments.
+ // It would also do away with the need for the if/then/else within updateQueueConfiguredObject
if (arguments != null)
{
- attributesMap.put(QUEUE_ARGUMENTS, FieldTable.convertToMap(arguments));
+ attributesMap.put(Queue.ARGUMENTS, FieldTable.convertToMap(arguments));
}
String json = _serializer.serialize(attributesMap);
ConfiguredObjectRecord configuredObject = new ConfiguredObjectRecord(queue.getId(), Queue.class.getName(), json);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
index 7b98b30860..262d7d0213 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
@@ -134,4 +134,10 @@ public class MemoryMessageStore extends NullMessageStore
{
_eventManager.addEventListener(eventListener, events);
}
+
+ @Override
+ public String getStoreType()
+ {
+ return "Memory";
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
index cf08ee00ff..0acaf164d9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
@@ -67,4 +67,6 @@ public interface MessageStore extends DurableConfigurationStore
void addEventListener(EventListener eventListener, Event... events);
String getStoreLocation();
+
+ String getStoreType();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
index 34c7d2d933..be08e309e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
@@ -28,7 +28,7 @@ import org.apache.qpid.server.federation.Bridge;
import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.queue.AMQQueue;
-public class NullMessageStore implements MessageStore
+public abstract class NullMessageStore implements MessageStore
{
@Override
public void configureConfigStore(String name,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
index c065eb263b..ab374b4917 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
@@ -232,6 +232,8 @@ public class DerbyMessageStore implements MessageStore
private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006";
+ private static final String DERBY_STORE_TYPE = "DERBY";
+
private final StateManager _stateManager;
private final EventManager _eventManager = new EventManager();
@@ -2651,4 +2653,11 @@ public class DerbyMessageStore implements MessageStore
{
return _persistentSizeHighThreshold;
}
+
+ @Override
+ public String getStoreType()
+ {
+ return DERBY_STORE_TYPE;
+ }
+
} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
index 6b2dff7165..efedad1181 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
@@ -20,10 +20,10 @@
*/
package org.apache.qpid.server.subscription;
+import org.apache.qpid.server.queue.QueueEntryVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
import java.util.Iterator;
@@ -102,7 +102,7 @@ public class AssignedSubscriptionMessageGroupManager implements MessageGroupMana
return visitor.getEntry();
}
- private class EntryFinder implements AMQQueue.Visitor
+ private class EntryFinder implements QueueEntryVisitor
{
private QueueEntry _entry;
private Subscription _sub;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
index 62e94f6f2e..f38e23b342 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
@@ -20,12 +20,12 @@
*/
package org.apache.qpid.server.subscription;
+import org.apache.qpid.server.queue.QueueEntryVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
import java.util.HashMap;
@@ -176,7 +176,7 @@ public class DefinedGroupMessageGroupManager implements MessageGroupManager
return visitor.getEntry();
}
- private class EntryFinder implements AMQQueue.Visitor
+ private class EntryFinder implements QueueEntryVisitor
{
private QueueEntry _entry;
private Subscription _sub;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java
index cf2754862d..8f3822be6c 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java
@@ -45,7 +45,7 @@ class ExplicitAcceptDispositionChangeListener implements ServerSession.MessageDi
final Subscription_0_10 subscription = getSubscription();
if(subscription != null && _entry.isAcquiredBy(_sub))
{
- subscription.getSession().acknowledge(subscription, _entry);
+ subscription.getSessionModel().acknowledge(subscription, _entry);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java
index 1e37675c98..826082cc65 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java
@@ -72,6 +72,10 @@ class ImplicitAcceptDispositionChangeListener implements ServerSession.MessageDi
public boolean acquire()
{
boolean acquired = _entry.acquire(getSubscription());
+ if(acquired)
+ {
+ getSubscription().recordUnacknowledged(_entry);
+ }
return acquired;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java
index 66825caa24..8911754a66 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.subscription;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
@@ -32,6 +33,14 @@ public interface Subscription
boolean isTransient();
+ long getBytesOut();
+
+ long getMessagesOut();
+
+ long getUnacknowledgedBytes();
+
+ long getUnacknowledgedMessages();
+
public static enum State
{
ACTIVE,
@@ -45,6 +54,7 @@ public interface Subscription
}
AMQQueue getQueue();
+ AMQSessionModel getSessionModel();
QueueEntry.SubscriptionAcquiredState getOwningState();
QueueEntry.SubscriptionAssignedState getAssignedState();
@@ -108,4 +118,6 @@ public interface Subscription
boolean isSessionTransactional();
void queueEmpty() throws AMQException;
+
+ String getConsumerName();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
index 1f25c215cc..baf5d09c95 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
@@ -44,6 +44,7 @@ import org.apache.qpid.server.logging.subjects.SubscriptionLogSubject;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
@@ -92,8 +93,13 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
private LogActor _logActor;
private UUID _id;
private final AtomicLong _deliveredCount = new AtomicLong(0);
- private long _createTime = System.currentTimeMillis();
+ private final AtomicLong _deliveredBytes = new AtomicLong(0);
+
+ private final AtomicLong _unacknowledgedCount = new AtomicLong(0);
+ private final AtomicLong _unacknowledgedBytes = new AtomicLong(0);
+ private long _createTime = System.currentTimeMillis();
+
static final class BrowserSubscription extends SubscriptionImpl
{
@@ -276,22 +282,13 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
public void send(QueueEntry entry, boolean batch) throws AMQException
{
- // if we do not need to wait for client acknowledgements
- // we can decrement the reference count immediately.
-
- // By doing this _before_ the send we ensure that it
- // doesn't get sent if it can't be dequeued, preventing
- // duplicate delivery on recovery.
-
- // The send may of course still fail, in which case, as
- // the message is unacked, it will be lost.
-
+
synchronized (getChannel())
{
getChannel().getProtocolSession().setDeferFlush(batch);
long deliveryTag = getChannel().getNextDeliveryTag();
-
+ addUnacknowledgedMessage(entry);
recordMessageDelivery(entry, deliveryTag);
sendToClient(entry, deliveryTag);
@@ -371,6 +368,11 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
+ public AMQSessionModel getSessionModel()
+ {
+ return _channel;
+ }
+
public ConfigStore getConfigStore()
{
return getQueue().getConfigStore();
@@ -599,6 +601,11 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return _consumerTag;
}
+ public String getConsumerName()
+ {
+ return _consumerTag == null ? null : _consumerTag.asString();
+ }
+
public long getSubscriptionID()
{
return _subscriptionID;
@@ -687,6 +694,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
{
_deliveryMethod.deliverToClient(this,entry,deliveryTag);
_deliveredCount.incrementAndGet();
+ _deliveredBytes.addAndGet(entry.getSize());
}
@@ -832,4 +840,44 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
_channel.getProtocolSession().flushBatched();
}
+
+ public long getBytesOut()
+ {
+ return _deliveredBytes.longValue();
+ }
+
+ public long getMessagesOut()
+ {
+ return _deliveredCount.longValue();
+ }
+
+
+ protected void addUnacknowledgedMessage(QueueEntry entry)
+ {
+ final long size = entry.getSize();
+ _unacknowledgedBytes.addAndGet(size);
+ _unacknowledgedCount.incrementAndGet();
+ entry.addStateChangeListener(new QueueEntry.StateChangeListener()
+ {
+ public void stateChanged(QueueEntry entry, QueueEntry.State oldState, QueueEntry.State newState)
+ {
+ if(oldState.equals(QueueEntry.State.ACQUIRED) && !newState.equals(QueueEntry.State.ACQUIRED))
+ {
+ _unacknowledgedBytes.addAndGet(-size);
+ _unacknowledgedCount.decrementAndGet();
+ entry.removeStateChangeListener(this);
+ }
+ }
+ });
+ }
+
+ public long getUnacknowledgedBytes()
+ {
+ return _unacknowledgedBytes.longValue();
+ }
+
+ public long getUnacknowledgedMessages()
+ {
+ return _unacknowledgedCount.longValue();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 76d975a789..db378f2bf3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -130,6 +130,10 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private String _trace;
private final long _createTime = System.currentTimeMillis();
private final AtomicLong _deliveredCount = new AtomicLong(0);
+ private final AtomicLong _deliveredBytes = new AtomicLong(0);
+ private final AtomicLong _unacknowledgedCount = new AtomicLong(0);
+ private final AtomicLong _unacknowledgedBytes = new AtomicLong(0);
+
private final Map<String, Object> _arguments;
private int _deferredMessageCredit;
private long _deferredSizeCredit;
@@ -185,7 +189,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
_queue = queue;
- Map<String, Object> arguments = queue.getArguments() == null ? Collections.EMPTY_MAP : queue.getArguments();
+ Map<String, Object> arguments = queue.getArguments();
_traceExclude = (String) arguments.get("qpid.trace.exclude");
_trace = (String) arguments.get("qpid.trace.id");
_id = getConfigStore().createId();
@@ -199,9 +203,13 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
CurrentActor.get().message(this, SubscriptionMessages.CREATE(filterLogString, queue.isDurable() && exclusive,
filterLogString.length() > 0));
}
-
}
+ public String getConsumerName()
+ {
+ return _destination;
+ }
+
public boolean isSuspended()
{
return !isActive() || _deleted.get() || _session.isClosing(); // TODO check for Session suspension
@@ -620,10 +628,15 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
_session.sendMessage(xfr, _postIdSettingAction);
entry.incrementDeliveryCount();
_deliveredCount.incrementAndGet();
+ _deliveredBytes.addAndGet(entry.getSize());
if(_acceptMode == MessageAcceptMode.NONE && _acquireMode == MessageAcquireMode.PRE_ACQUIRED)
{
forceDequeue(entry, false);
}
+ else if(_acquireMode == MessageAcquireMode.PRE_ACQUIRED)
+ {
+ recordUnacknowledged(entry);
+ }
}
else
{
@@ -632,6 +645,12 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
}
+ void recordUnacknowledged(QueueEntry entry)
+ {
+ _unacknowledgedCount.incrementAndGet();
+ _unacknowledgedBytes.addAndGet(entry.getSize());
+ }
+
private void deferredAddCredit(final int deferredMessageCredit, final long deferredSizeCredit)
{
_deferredMessageCredit += deferredMessageCredit;
@@ -653,7 +672,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private void forceDequeue(final QueueEntry entry, final boolean restoreCredit)
{
- AutoCommitTransaction dequeueTxn = new AutoCommitTransaction(getQueue().getVirtualHost().getMessageStore());
+ AutoCommitTransaction dequeueTxn = new AutoCommitTransaction(getQueue().getVirtualHost().getMessageStore());
dequeueTxn.dequeue(entry.getQueue(), entry.getMessage(),
new ServerTransaction.Action()
{
@@ -690,7 +709,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
entry.setRedelivered();
}
- if (getSession().isClosing() || !setRedelivered)
+ if (getSessionModel().isClosing() || !setRedelivered)
{
entry.decrementDeliveryCount();
}
@@ -918,6 +937,8 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
// TODO Fix Store Context / cleanup
if(entry.isAcquiredBy(this))
{
+ _unacknowledgedBytes.addAndGet(-entry.getSize());
+ _unacknowledgedCount.decrementAndGet();
entry.discard();
}
}
@@ -944,7 +965,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return false;
}
- ServerSession getSession()
+ public ServerSession getSessionModel()
{
return _session;
}
@@ -952,7 +973,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
public SessionConfig getSessionConfig()
{
- return getSession();
+ return getSessionModel();
}
public boolean isBrowsing()
@@ -1073,4 +1094,24 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
{
_session.getConnection().flush();
}
+
+ public long getBytesOut()
+ {
+ return _deliveredBytes.longValue();
+ }
+
+ public long getMessagesOut()
+ {
+ return _deliveredCount.longValue();
+ }
+
+ public long getUnacknowledgedBytes()
+ {
+ return _unacknowledgedBytes.longValue();
+ }
+
+ public long getUnacknowledgedMessages()
+ {
+ return _unacknowledgedCount.longValue();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
index 637ea7dffc..7c4188bfcd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
@@ -20,25 +20,62 @@
*/
package org.apache.qpid.server.transport;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
import org.apache.qpid.transport.network.NetworkTransport;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
public class QpidAcceptor
{
- private NetworkTransport _transport;
- private String _protocol;
- public QpidAcceptor(NetworkTransport transport, String protocol)
+ public enum Transport
{
- _transport = transport;
- _protocol = protocol;
+ TCP("TCP"),
+ SSL("TCP/SSL");
+
+ private final String _asString;
+
+ Transport(String asString)
+ {
+ _asString = asString;
+ }
+
+ public String toString()
+ {
+ return _asString;
+ }
+ }
+
+ private NetworkTransport _networkTransport;
+ private Transport _transport;
+ private Set<AmqpProtocolVersion> _supported;
+
+
+ public QpidAcceptor(NetworkTransport transport, Transport protocol, Set<AmqpProtocolVersion> supported)
+ {
+ _networkTransport = transport;
+ _transport = protocol;
+ _supported = Collections.unmodifiableSet(new HashSet<AmqpProtocolVersion>(supported));
}
public NetworkTransport getNetworkTransport()
{
+ return _networkTransport;
+ }
+
+ public Transport getTransport()
+ {
return _transport;
}
+ public Set<AmqpProtocolVersion> getSupported()
+ {
+ return _supported;
+ }
+
public String toString()
{
- return _protocol;
+ return _transport.toString();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index c9482b9712..2d0e61ec2e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -37,8 +37,6 @@ import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
-import org.apache.qpid.server.management.Managable;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.security.AuthorizationHolder;
@@ -56,7 +54,7 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTIO
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORMAT;
-public class ServerConnection extends Connection implements Managable, AMQConnectionModel, LogSubject, AuthorizationHolder
+public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder
{
private ConnectionConfig _config;
private Runnable _onOpenTask;
@@ -65,11 +63,9 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
private Subject _authorizedSubject = null;
private Principal _authorizedPrincipal = null;
- private boolean _statisticsEnabled = false;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final long _connectionId;
private final Object _reference = new Object();
- private ServerConnectionMBean _mBean;
private VirtualHost _virtualHost;
private AtomicLong _lastIoTime = new AtomicLong();
private boolean _blocking;
@@ -118,7 +114,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
{
_virtualHost.getConnectionRegistry().deregisterConnection(this);
}
- unregisterConnectionMbean();
}
if (state == State.CLOSED)
@@ -156,8 +151,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
_virtualHost = virtualHost;
initialiseStatistics();
-
- registerConnectionMbean();
}
public void setConnectionConfig(final ConnectionConfig config)
@@ -273,7 +266,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
public void close(AMQConstant cause, String message) throws AMQException
{
closeSubscriptions();
- unregisterConnectionMbean();
ConnectionCloseCode replyCode = ConnectionCloseCode.NORMAL;
try
{
@@ -338,21 +330,15 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
public void registerMessageDelivered(long messageSize)
{
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
+ _messagesDelivered.registerEvent(1L);
+ _dataDelivered.registerEvent(messageSize);
_virtualHost.registerMessageDelivered(messageSize);
}
public void registerMessageReceived(long messageSize, long timestamp)
{
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
+ _messagesReceived.registerEvent(1L, timestamp);
+ _dataReceived.registerEvent(messageSize, timestamp);
_virtualHost.registerMessageReceived(messageSize, timestamp);
}
@@ -386,25 +372,12 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
public void initialiseStatistics()
{
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _virtualHost.getApplicationRegistry().getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
_messagesDelivered = new StatisticsCounter("messages-delivered-" + getConnectionId());
_dataDelivered = new StatisticsCounter("data-delivered-" + getConnectionId());
_messagesReceived = new StatisticsCounter("messages-received-" + getConnectionId());
_dataReceived = new StatisticsCounter("data-received-" + getConnectionId());
}
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
-
/**
* @return authorizedSubject
*/
@@ -448,6 +421,11 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
return !super.hasSessionWithName(name);
}
+ public String getRemoteAddressString()
+ {
+ return getConfig().getAddress();
+ }
+
public String getUserName()
{
return _authorizedPrincipal.getName();
@@ -476,12 +454,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
}
}
-
- public ManagedObject getManagedObject()
- {
- return _mBean;
- }
-
@Override
public void send(ProtocolEvent event)
{
@@ -489,54 +461,29 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
super.send(event);
}
- public AtomicLong getLastIoTime()
+ public long getLastIoTime()
{
- return _lastIoTime;
+ return _lastIoTime.longValue();
}
- void checkForNotification()
- {
- int channelsCount = getSessionModels().size();
- if (_mBean != null && channelsCount >= getConnectionDelegate().getChannelMax())
- {
- _mBean.notifyClients("Channel count (" + channelsCount + ") has reached the threshold value");
- }
- }
-
- private void registerConnectionMbean()
+ public String getClientId()
{
- try
- {
- _mBean = new ServerConnectionMBean(this);
- _mBean.register();
- }
- catch (JMException jme)
- {
- log.error("Unable to register mBean for ServerConnection", jme);
- }
+ return getConnectionDelegate().getClientId();
}
- private void unregisterConnectionMbean()
+ public String getClientVersion()
{
- if (_mBean != null)
- {
- if (log.isDebugEnabled())
- {
- log.debug("Unregistering mBean for ServerConnection" + _mBean);
- }
- _mBean.unregister();
- _mBean = null;
- }
+ return getConnectionDelegate().getClientVersion();
}
- public String getClientId()
+ public String getPrincipalAsString()
{
- return getConnectionDelegate().getClientId();
+ return getAuthorizedPrincipal().getName();
}
- public String getClientVersion()
+ public long getSessionCountLimit()
{
- return getConnectionDelegate().getClientVersion();
+ return getChannelMax();
}
public Principal getPeerPrincipal()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index ad59c56878..c13f63b44d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -61,7 +61,7 @@ public class ServerConnectionDelegate extends ServerDelegate
public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager)
{
- this(createConnectionProperties(appRegistry.getBroker()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager);
+ this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager);
}
private ServerConnectionDelegate(Map<String, Object> properties,
@@ -226,7 +226,7 @@ public class ServerConnectionDelegate extends ServerDelegate
}
@Override
- protected int getChannelMax()
+ public int getChannelMax()
{
return _maxNoOfChannels;
}
@@ -266,9 +266,6 @@ public class ServerConnectionDelegate extends ServerDelegate
if(isSessionNameUnique(atc.getName(), conn))
{
super.sessionAttach(conn, atc);
- final ServerConnection serverConnection = (ServerConnection) conn;
-
- serverConnection.checkForNotification();
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java
deleted file mode 100644
index bb545164fb..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.transport;
-
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AbstractAMQManagedConnectionObject;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.protocol.AMQSessionModel;
-
-import javax.management.JMException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-
-/**
- * This MBean class implements the management interface. In order to make more attributes, operations and notifications
- * available over JMX simply augment the ManagedConnection interface and add the appropriate implementation here.
- */
-@MBeanDescription("Management Bean for an AMQ Broker 0-10 Connection")
-public class ServerConnectionMBean extends AbstractAMQManagedConnectionObject
-{
- private final ServerConnection _serverConnection;
-
- @MBeanConstructor("Creates an MBean exposing an AMQ Broker 0-10 Connection")
- protected ServerConnectionMBean(final ServerConnection serverConnection) throws NotCompliantMBeanException
- {
- super(serverConnection.getConfig().getAddress());
- _serverConnection = serverConnection;
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return _serverConnection.getVirtualHost().getManagedObject();
- }
-
- @Override
- public String getClientId()
- {
- return _serverConnection.getClientId();
- }
-
- @Override
- public String getAuthorizedId()
- {
- return _serverConnection.getAuthorizedPrincipal().getName();
- }
-
- @Override
- public String getVersion()
- {
- return String.valueOf(_serverConnection.getClientVersion());
- }
-
- @Override
- public String getRemoteAddress()
- {
- return _serverConnection.getConfig().getAddress();
- }
-
- @Override
- public Date getLastIoTime()
- {
- return new Date(_serverConnection.getLastIoTime().longValue());
- }
-
- @Override
- public Long getMaximumNumberOfChannels()
- {
- return (long) _serverConnection.getConnectionDelegate().getChannelMax();
- }
-
- @Override
- public TabularData channels() throws IOException, JMException
- {
- final TabularDataSupport channelsList = new TabularDataSupport(_channelsType);
- final List<AMQSessionModel> list = _serverConnection.getSessionModels();
-
- for (final AMQSessionModel channel : list)
- {
- final ServerSession session = (ServerSession)channel;
- Object[] itemValues =
- {
- session.getChannel(),
- session.isTransactional(),
- null,
- session.getUnacknowledgedMessageCount(),
- session.getBlocking()
- };
-
- final CompositeData channelData = new CompositeDataSupport(_channelType,
- COMPOSITE_ITEM_NAMES_DESC.toArray(new String[COMPOSITE_ITEM_NAMES_DESC.size()]), itemValues);
- channelsList.put(channelData);
- }
- return channelsList;
- }
-
- @Override
- public void commitTransactions(int channelId) throws JMException
- {
- final ServerSession session = (ServerSession)_serverConnection.getSession(channelId);
- if (session == null)
- {
- throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
- }
- else if (session.isTransactional())
- {
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- session.commit();
- }
- finally
- {
- CurrentActor.remove();
- }
- }
- }
-
- @Override
- public void rollbackTransactions(int channelId) throws JMException
- {
- final ServerSession session = (ServerSession)_serverConnection.getSession(channelId);
- if (session == null)
- {
- throw new JMException("The channel (channel Id = " + channelId + ") does not exist");
- }
- else if (session.isTransactional())
- {
- CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger()));
- try
- {
- session.rollback();
- }
- finally
- {
- CurrentActor.remove();
- }
- }
- }
-
- @Override
- public void closeConnection() throws Exception
- {
- _serverConnection.mgmtClose();
- }
-
- @Override
- public void resetStatistics() throws Exception
- {
- _serverConnection.resetStatistics();
- }
-
- @Override
- public double getPeakMessageDeliveryRate()
- {
- return _serverConnection.getMessageDeliveryStatistics().getPeak();
- }
-
- @Override
- public double getPeakDataDeliveryRate()
- {
- return _serverConnection.getDataDeliveryStatistics().getPeak();
- }
-
- @Override
- public double getMessageDeliveryRate()
- {
- return _serverConnection.getMessageDeliveryStatistics().getRate();
- }
-
- @Override
- public double getDataDeliveryRate()
- {
- return _serverConnection.getDataDeliveryStatistics().getRate();
- }
-
- @Override
- public long getTotalMessagesDelivered()
- {
- return _serverConnection.getMessageDeliveryStatistics().getTotal();
- }
-
- @Override
- public long getTotalDataDelivered()
- {
- return _serverConnection.getDataDeliveryStatistics().getTotal();
- }
-
- @Override
- public double getPeakMessageReceiptRate()
- {
- return _serverConnection.getMessageReceiptStatistics().getPeak();
- }
-
- @Override
- public double getPeakDataReceiptRate()
- {
- return _serverConnection.getDataReceiptStatistics().getPeak();
- }
-
- @Override
- public double getMessageReceiptRate()
- {
- return _serverConnection.getMessageReceiptStatistics().getRate();
- }
-
- @Override
- public double getDataReceiptRate()
- {
- return _serverConnection.getDataReceiptStatistics().getRate();
- }
-
- @Override
- public long getTotalMessagesReceived()
- {
- return _serverConnection.getMessageReceiptStatistics().getTotal();
- }
-
- @Override
- public long getTotalDataReceived()
- {
- return _serverConnection.getDataReceiptStatistics().getTotal();
- }
-
- @Override
- public boolean isStatisticsEnabled()
- {
- return _serverConnection.isStatisticsEnabled();
- }
-
- @Override
- public void setStatisticsEnabled(boolean enabled)
- {
- _serverConnection.setStatisticsEnabled(enabled);
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index 0cb60fafd3..9914485638 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -630,11 +630,21 @@ public class ServerSession extends Session
return _txnRejects.get();
}
+ public int getChannelId()
+ {
+ return getChannel();
+ }
+
public Long getTxnCount()
{
return _txnCount.get();
}
+ public Long getTxnStart()
+ {
+ return _txnStarts.get();
+ }
+
public Principal getAuthorizedPrincipal()
{
return getConnection().getAuthorizedPrincipal();
@@ -1059,5 +1069,4 @@ public class ServerSession extends Session
{
return getId().compareTo(session.getId());
}
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index 85ea97c107..3dbc835c45 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -1226,11 +1226,7 @@ public class ServerSessionDelegate extends SessionDelegate
try
{
queue = createQueue(queueName, method, virtualHost, (ServerSession)session);
- if(method.getExclusive())
- {
- queue.setExclusive(true);
- }
- else if(method.getAutoDelete())
+ if(!method.getExclusive() && method.getAutoDelete())
{
queue.setDeleteOnNoConsumers(true);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index c59016173a..dcc5acb820 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -32,7 +32,6 @@ import org.apache.qpid.server.connection.IConnectionRegistry;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.federation.BrokerLink;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
@@ -62,8 +61,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
void close();
- ManagedObject getManagedObject();
-
UUID getBrokerId();
void scheduleHouseKeepingTask(long period, HouseKeepingTask task);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
index e956806823..acd6101ff8 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
@@ -100,7 +100,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
return this;
}
- public void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments)
+ public void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments, UUID alternateExchangeId)
{
try
{
@@ -111,6 +111,17 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
q = AMQQueueFactory.createAMQQueueImpl(id, queueName, true, owner, false, exclusive, _virtualHost,
FieldTable.convertToMap(arguments));
_virtualHost.getQueueRegistry().registerQueue(q);
+
+ if (alternateExchangeId != null)
+ {
+ Exchange altExchange = _virtualHost.getExchangeRegistry().getExchange(alternateExchangeId);
+ if (altExchange == null)
+ {
+ _logger.error("Unknown exchange id " + alternateExchangeId + ", cannot set alternate exchange on queue with id " + id);
+ return;
+ }
+ q.setAlternateExchange(altExchange);
+ }
}
CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERY_START(queueName, true));
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 5a56fe1765..8945431e99 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -20,12 +20,20 @@
*/
package org.apache.qpid.server.virtualhost;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.AMQBrokerManagerMBean;
import org.apache.qpid.server.binding.BindingFactory;
import org.apache.qpid.server.configuration.BrokerConfig;
import org.apache.qpid.server.configuration.ConfigStore;
@@ -45,11 +53,9 @@ import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
+import org.apache.qpid.server.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.DefaultQueueRegistry;
@@ -66,20 +72,6 @@ import org.apache.qpid.server.txn.DtxRegistry;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
-import javax.management.JMException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-
public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.RegistryChangeListener, EventListener
{
private static final Logger _logger = Logger.getLogger(VirtualHostImpl.class);
@@ -104,10 +96,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
private final VirtualHostConfiguration _vhostConfig;
- private final VirtualHostMBean _virtualHostMBean;
-
- private final AMQBrokerManagerMBean _brokerMBean;
-
private final QueueRegistry _queueRegistry;
private final ExchangeRegistry _exchangeRegistry;
@@ -124,8 +112,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
private volatile State _state = State.INITIALISING;
- private boolean _statisticsEnabled = false;
-
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>();
@@ -144,7 +130,7 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
}
_appRegistry = appRegistry;
- _brokerConfig = _appRegistry.getBroker();
+ _brokerConfig = _appRegistry.getBrokerConfig();
_vhostConfig = hostConfig;
_name = _vhostConfig.getName();
_dtxRegistry = new DtxRegistry();
@@ -153,7 +139,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
CurrentActor.get().message(VirtualHostMessages.CREATED(_name));
- _virtualHostMBean = new VirtualHostMBean();
_securityManager = new SecurityManager(_appRegistry.getSecurityManager());
_securityManager.configureHostPlugins(_vhostConfig);
@@ -171,8 +156,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
_bindingFactory = new BindingFactory(this);
- _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
-
_messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass());
configureMessageStore(hostConfig);
@@ -541,16 +524,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
CurrentActor.get().message(VirtualHostMessages.CLOSED());
}
- public ManagedObject getBrokerMBean()
- {
- return _brokerMBean;
- }
-
- public ManagedObject getManagedObject()
- {
- return _virtualHostMBean;
- }
-
public UUID getBrokerId()
{
return _appRegistry.getBrokerId();
@@ -568,21 +541,15 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
public void registerMessageDelivered(long messageSize)
{
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
+ _messagesDelivered.registerEvent(1L);
+ _dataDelivered.registerEvent(messageSize);
_appRegistry.registerMessageDelivered(messageSize);
}
public void registerMessageReceived(long messageSize, long timestamp)
{
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
+ _messagesReceived.registerEvent(1L, timestamp);
+ _dataReceived.registerEvent(messageSize, timestamp);
_appRegistry.registerMessageReceived(messageSize, timestamp);
}
@@ -621,25 +588,12 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
public void initialiseStatistics()
{
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _appRegistry.getConfiguration().isStatisticsGenerationVirtualhostsEnabled());
-
_messagesDelivered = new StatisticsCounter("messages-delivered-" + getName());
_dataDelivered = new StatisticsCounter("bytes-delivered-" + getName());
_messagesReceived = new StatisticsCounter("messages-received-" + getName());
_dataReceived = new StatisticsCounter("bytes-received-" + getName());
}
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
-
public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments)
{
BrokerLink blink = new BrokerLink(this, id, createTime, arguments);
@@ -772,36 +726,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
}
}
-
- /**
- * Virtual host JMX MBean class.
- *
- * This has some of the methods implemented from management interface for exchanges. Any
- * Implementation of an Exchange MBean should extend this class.
- */
- public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost
- {
- public VirtualHostMBean() throws NotCompliantMBeanException
- {
- super(ManagedVirtualHost.class, ManagedVirtualHost.TYPE);
- }
-
- public String getObjectInstanceName()
- {
- return ObjectName.quote(_name);
- }
-
- public String getName()
- {
- return _name;
- }
-
- public VirtualHostImpl getVirtualHost()
- {
- return VirtualHostImpl.this;
- }
- }
-
private final class BeforeActivationListener implements EventListener
{
@Override
@@ -825,17 +749,19 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
public void event(Event event)
{
State finalState = State.ERRORED;
+
try
{
initialiseHouseKeeping(_vhostConfig.getHousekeepingCheckPeriod());
- try
- {
- _brokerMBean.register();
- }
- catch (JMException e)
- {
- throw new RuntimeException("Failed to register virtual host mbean for virtual host " + getName(), e);
- }
+//TODO: implement state changing for the VirtualHost MBean instead of registering and unregistering
+// try
+// {
+// _brokerMBean.register();
+// }
+// catch (JMException e)
+// {
+// throw new RuntimeException("Failed to register virtual host mbean for virtual host " + getName(), e);
+// }
finalState = State.ACTIVE;
}
finally
@@ -861,7 +787,8 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
*/
_connectionRegistry.close(IConnectionRegistry.VHOST_PASSIVATE_REPLY_TEXT);
- _brokerMBean.unregister();
+//TODO: implement state changing for the VirtualHost MBean instead of registering and unregistering
+// _brokerMBean.unregister();
removeHouseKeepingTasks();
_queueRegistry.stopAllAndUnregisterMBeans();
@@ -884,7 +811,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
@Override
public void event(Event event)
{
- _brokerMBean.unregister();
shutdownHouseKeeping();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
index ef621a166a..1be472844a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
@@ -22,10 +22,12 @@ package org.apache.qpid.server.virtualhost;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +39,8 @@ public class VirtualHostRegistry implements Closeable
private String _defaultVirtualHostName;
private ApplicationRegistry _applicationRegistry;
+ private final Collection<RegistryChangeListener> _listeners =
+ Collections.synchronizedCollection(new ArrayList<RegistryChangeListener>());
public VirtualHostRegistry(ApplicationRegistry applicationRegistry)
{
@@ -50,11 +54,25 @@ public class VirtualHostRegistry implements Closeable
throw new Exception("Virtual Host with name " + host.getName() + " already registered.");
}
_registry.put(host.getName(),host);
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.virtualHostRegistered(host);
+ }
+ }
}
public synchronized void unregisterVirtualHost(VirtualHost host)
{
_registry.remove(host.getName());
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.virtualHostUnregistered(host);
+ }
+ }
}
public VirtualHost getVirtualHost(String name)
@@ -106,4 +124,17 @@ public class VirtualHostRegistry implements Closeable
}
}
+
+ public static interface RegistryChangeListener
+ {
+ void virtualHostRegistered(VirtualHost virtualHost);
+ void virtualHostUnregistered(VirtualHost virtualHost);
+
+ }
+
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ _listeners.add(listener);
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java b/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java
deleted file mode 100644
index c06ce5e31a..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.log4j.xml;
-
-
-import junit.framework.TestCase;
-import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-public class QpidLog4JConfiguratorTest extends TestCase
-{
- private static final String NEWLINE = System.getProperty("line.separator");
-
- private File _testConfigFile;
-
- private File createTempTestLog4JConfig(String loggerLevel,String rootLoggerLevel, boolean missingTagClose, boolean incorrectAttribute)
- {
- File tmpFile = null;
- try
- {
- tmpFile = File.createTempFile("QpidLog4JConfiguratorTestLog4jConfig", ".tmp");
- tmpFile.deleteOnExit();
-
- FileWriter fstream = new FileWriter(tmpFile);
- BufferedWriter writer = new BufferedWriter(fstream);
-
- writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE);
- writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE);
-
- writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " +
- "threshold=\"null\">"+NEWLINE);
-
- writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE);
- writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE);
- writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE);
- writer.write(" </layout>"+NEWLINE);
- writer.write(" </appender>"+NEWLINE);
-
- String closeTag="/";
- if(missingTagClose)
- {
- closeTag="";
- }
-
- //Example of a 'category' with a 'priority'
- writer.write(" <category additivity=\"true\" name=\"logger1\">"+NEWLINE);
- writer.write(" <priority value=\"" + loggerLevel+ "\"" + closeTag + ">"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- String attributeName="value";
- if(incorrectAttribute)
- {
- attributeName="values";
- }
-
- //Example of a 'category' with a 'level'
- writer.write(" <category additivity=\"true\" name=\"logger2\">"+NEWLINE);
- writer.write(" <level " + attributeName + "=\"" + loggerLevel+ "\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- //Example of a 'logger' with a 'level'
- writer.write(" <logger additivity=\"true\" name=\"logger3\">"+NEWLINE);
- writer.write(" <level value=\"" + loggerLevel+ "\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </logger>"+NEWLINE);
-
- //'root' logger
- writer.write(" <root>"+NEWLINE);
- writer.write(" <priority value=\"" + rootLoggerLevel+ "\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </root>"+NEWLINE);
-
- writer.write("</log4j:configuration>"+NEWLINE);
-
- writer.flush();
- writer.close();
- }
- catch (IOException e)
- {
- fail("Unable to create temporary test log4j configuration");
- }
-
- return tmpFile;
- }
-
-
-
- //******* Test Methods ******* //
-
- public void testCheckLevelsAndStrictParser()
- {
- //try the valid logger levels
- _testConfigFile = createTempTestLog4JConfig("all", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("trace", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("debug", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("warn", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("error", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("fatal", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("off", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("null", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("inherited", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- //now try an invalid logger level
- _testConfigFile = createTempTestLog4JConfig("madeup", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- fail("IllegalLoggerLevelException expected, invalid levels used");
- }
- catch (IllegalLoggerLevelException e)
- {
- //expected, ignore
- }
- catch (IOException e)
- {
- fail("Incorrect Exception, expected an IllegalLoggerLevelException");
- }
-
-
-
- //now try the valid rootLogger levels
- _testConfigFile = createTempTestLog4JConfig("info", "all", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "trace", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "debug", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "info", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "warn", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "error", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "fatal", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "off", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "null", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "inherited", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "debug", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- }
- catch (Exception e)
- {
- fail("No exception expected, valid levels and xml were used");
- }
-
- //now try an invalid logger level
- _testConfigFile = createTempTestLog4JConfig("info", "madeup", false, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- fail("IllegalLoggerLevelException expected, invalid levels used");
- }
- catch (IllegalLoggerLevelException e)
- {
- //expected, ignore
- }
- catch (IOException e)
- {
- fail("Incorrect Exception, expected an IllegalLoggerLevelException");
- }
-
-
-
- //now try invalid xml
- _testConfigFile = createTempTestLog4JConfig("info", "info", true, false);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- fail("IOException expected, malformed XML used");
- }
- catch (IllegalLoggerLevelException e)
- {
- fail("Incorrect Exception, expected an IOException");
- }
- catch (IOException e)
- {
- //expected, ignore
- }
-
- _testConfigFile = createTempTestLog4JConfig("info", "info", false, true);
- try
- {
- QpidLog4JConfigurator.checkLoggerLevels(_testConfigFile.getAbsolutePath());
- fail("IOException expected, malformed XML used");
- }
- catch (IllegalLoggerLevelException e)
- {
- //expected, ignore
- }
- catch (IOException e)
- {
- fail("Incorrect Exception, expected an IllegalLoggerLevelException");
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
deleted file mode 100644
index d34d1bbef3..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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;
-
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.logging.SystemOutMessageLogger;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.TestLogActor;
-import org.apache.qpid.server.queue.AMQPriorityQueue;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class AMQBrokerManagerMBeanTest extends QpidTestCase
-{
- private QueueRegistry _queueRegistry;
- private ExchangeRegistry _exchangeRegistry;
- private VirtualHost _vHost;
-
- public void testExchangeOperations() throws Exception
- {
- String exchange1 = "testExchange1_" + System.currentTimeMillis();
- String exchange2 = "testExchange2_" + System.currentTimeMillis();
- String exchange3 = "testExchange3_" + System.currentTimeMillis();
-
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) == null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) == null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange3)) == null);
-
-
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHostImpl.VirtualHostMBean) _vHost.getManagedObject());
- mbean.createNewExchange(exchange1, "direct", false);
- mbean.createNewExchange(exchange2, "topic", false);
- mbean.createNewExchange(exchange3, "headers", false);
-
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) != null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) != null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange3)) != null);
-
- mbean.unregisterExchange(exchange1);
- mbean.unregisterExchange(exchange2);
- mbean.unregisterExchange(exchange3);
-
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) == null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) == null);
- assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange3)) == null);
- }
-
- public void testQueueOperations() throws Exception
- {
- String queueName = "testQueue_" + System.currentTimeMillis();
-
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHostImpl.VirtualHostMBean) _vHost.getManagedObject());
-
- assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) == null);
-
- mbean.createNewQueue(queueName, "test", false);
- assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) != null);
-
- mbean.deleteQueue(queueName);
- assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) == null);
- }
-
- public void testCreateNewQueueBindsToDefaultExchange() throws Exception
- {
- String queueName = "testQueue_" + System.currentTimeMillis();
-
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHostImpl.VirtualHostMBean) _vHost.getManagedObject());
- ExchangeRegistry exReg = _vHost.getExchangeRegistry();
- Exchange defaultExchange = exReg.getDefaultExchange();
-
- mbean.createNewQueue(queueName, "test", false);
- assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) != null);
-
- assertTrue("New queue should be bound to default exchange", defaultExchange.isBound(new AMQShortString(queueName)));
- }
-
- /**
- * Tests that setting the {@link AMQQueueFactory#X_QPID_MAXIMUM_DELIVERY_COUNT} argument does cause the
- * maximum delivery count to be set on the Queue.
- */
- public void testCreateNewQueueWithMaximumDeliveryCount() throws Exception
- {
- final Map<String,Object> args = new HashMap<String, Object>();
- args.put(AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT, 5);
-
- final AMQShortString queueName = new AMQShortString("testCreateNewQueueWithMaximumDeliveryCount");
-
- final QueueRegistry qReg = _vHost.getQueueRegistry();
-
- assertNull("The queue should not yet exist", qReg.getQueue(queueName));
-
- final ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHostImpl.VirtualHostMBean) _vHost.getManagedObject());
- mbean.createNewQueue(queueName.asString(), "test", false, args);
-
- final AMQQueue createdQueue = qReg.getQueue(queueName);
- assertNotNull("The queue was not registered as expected", createdQueue);
- assertEquals("Unexpected maximum delivery count", 5, createdQueue.getMaximumDeliveryCount());
- }
-
- /**
- * Tests that setting the {@link AMQQueueFactory#X_QPID_PRIORITIES} argument prompts creation of
- * a Priority Queue.
- */
- public void testCreatePriorityQueue() throws Exception
- {
- int numPriorities = 7;
- Map<String,Object> args = new HashMap<String, Object>();
- args.put(AMQQueueFactory.X_QPID_PRIORITIES, numPriorities);
-
- AMQShortString queueName = new AMQShortString("testCreatePriorityQueue");
-
- QueueRegistry qReg = _vHost.getQueueRegistry();
-
- assertNull("The queue should not yet exist", qReg.getQueue(queueName));
-
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHostImpl.VirtualHostMBean) _vHost.getManagedObject());
- mbean.createNewQueue(queueName.asString(), "test", false, args);
-
- AMQQueue queue = qReg.getQueue(queueName);
- assertEquals("Queue is not a priorty queue", AMQPriorityQueue.class, queue.getClass());
- assertEquals("Number of priorities supported was not as expected", numPriorities, ((AMQPriorityQueue)queue).getPriorities());
- }
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
-
- XMLConfiguration configXml = new XMLConfiguration();
- configXml.addProperty("virtualhosts.virtualhost(-1).name", "test");
- configXml.addProperty("virtualhosts.virtualhost(-1).test.store.class", TestableMemoryMessageStore.class.getName());
-
- ServerConfiguration configuration = new ServerConfiguration(configXml);
-
- ApplicationRegistry registry = new TestApplicationRegistry(configuration);
- ApplicationRegistry.initialise(registry);
- registry.getVirtualHostRegistry().setDefaultVirtualHostName("test");
-
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- _vHost = appRegistry.getVirtualHostRegistry().getVirtualHost("test");
- _queueRegistry = _vHost.getQueueRegistry();
- _exchangeRegistry = _vHost.getExchangeRegistry();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- super.tearDown();
- }
- finally
- {
- ApplicationRegistry.remove();
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
index 36f131a30f..9225f7810a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
@@ -204,6 +204,18 @@ public class QueueConfigurationTest extends TestCase
assertEquals("test-sort-key", qConf.getQueueSortKey());
}
+ public void testQueueDescription() throws ConfigurationException
+ {
+ //Check default value
+ QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
+ assertNull(qConf.getDescription());
+
+ // Check explicit value
+ final VirtualHostConfiguration vhostConfig = overrideConfiguration("description", "mydescription");
+ qConf = new QueueConfiguration("test", vhostConfig);
+ assertEquals("mydescription", qConf.getDescription());
+ }
+
private VirtualHostConfiguration overrideConfiguration(String property, Object value)
throws ConfigurationException
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index c2d2eb37c1..2ee02430c8 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -252,13 +252,13 @@ public class ServerConfigurationTest extends QpidTestCase
{
// Check default
_serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementSSLEnabled());
+ assertEquals(false, _serverConfig.getManagementSSLEnabled());
// Check value we set
- _config.setProperty("management.ssl.enabled", false);
+ _config.setProperty("management.ssl.enabled", true);
_serverConfig = new ServerConfiguration(_config);
_serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementSSLEnabled());
+ assertEquals(true, _serverConfig.getManagementSSLEnabled());
}
public void testGetManagementKeystorePassword() throws ConfigurationException
@@ -287,25 +287,17 @@ public class ServerConfigurationTest extends QpidTestCase
assertEquals(false, _serverConfig.getQueueAutoRegister());
}
- public void testGetManagementEnabled() throws ConfigurationException
+ public void testGetJMXManagementEnabled() throws ConfigurationException
{
// Check default
_serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementEnabled());
+ assertEquals(true, _serverConfig.getJMXManagementEnabled());
// Check value we set
_config.setProperty("management.enabled", false);
_serverConfig = new ServerConfiguration(_config);
_serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementEnabled());
- }
-
- public void testSetManagementEnabled() throws ConfigurationException
- {
- // Check value we set
- _serverConfig.initialise();
- _serverConfig.setManagementEnabled(false);
- assertEquals(false, _serverConfig.getManagementEnabled());
+ assertEquals(false, _serverConfig.getJMXManagementEnabled());
}
public void testGetManagementRightsInferAllAccess() throws Exception
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
deleted file mode 100644
index 9034bf9c3a..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.exchange;
-
-import org.apache.commons.lang.ArrayUtils;
-
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedExchange;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.model.UUIDGenerator;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * Unit test class for testing different Exchange MBean operations
- */
-public class ExchangeMBeanTest extends InternalBrokerBaseCase
-{
- private AMQQueue _queue;
- private QueueRegistry _queueRegistry;
- private VirtualHost _virtualHost;
-
- public void testGeneralProperties() throws Exception
- {
- DirectExchange exchange = new DirectExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost, ExchangeDefaults.DIRECT_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- // test general exchange properties
- assertEquals("Unexpected exchange name", "amq.direct", mbean.getName());
- assertEquals("Unexpected exchange type", "direct", mbean.getExchangeType());
- assertEquals("Unexpected ticket number", Integer.valueOf(0), mbean.getTicketNo());
- assertFalse("Unexpected durable flag", mbean.isDurable());
- assertTrue("Unexpected auto delete flag", mbean.isAutoDelete());
- }
-
- public void testDirectExchangeMBean() throws Exception
- {
- DirectExchange exchange = new DirectExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost, ExchangeDefaults.DIRECT_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- mbean.createNewBinding(_queue.getNameShortString().toString(), "binding1");
- mbean.createNewBinding(_queue.getNameShortString().toString(), "binding2");
-
- TabularData data = mbean.bindings();
- ArrayList<Object> list = new ArrayList<Object>(data.values());
- assertTrue(list.size() == 2);
- }
-
- public void testTopicExchangeMBean() throws Exception
- {
- TopicExchange exchange = new TopicExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost,ExchangeDefaults.TOPIC_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- mbean.createNewBinding(_queue.getNameShortString().toString(), "binding1");
- mbean.createNewBinding(_queue.getNameShortString().toString(), "binding2");
-
- TabularData data = mbean.bindings();
- ArrayList<Object> list = new ArrayList<Object>(data.values());
- assertTrue(list.size() == 2);
- }
-
- public void testHeadersExchangeMBean() throws Exception
- {
- HeadersExchange exchange = new HeadersExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost,ExchangeDefaults.HEADERS_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- mbean.createNewBinding(_queue.getNameShortString().toString(), "x-match=any,key1=binding1,key2=binding2");
-
- TabularData data = mbean.bindings();
- ArrayList<Object> list = new ArrayList<Object>(data.values());
- assertEquals("Unexpected number of bindings", 1, list.size());
-
- final Iterator<CompositeDataSupport> rowItr = (Iterator<CompositeDataSupport>) data.values().iterator();
- CompositeDataSupport row = rowItr.next();
- assertBinding(1, _queue.getName(), new String[]{"x-match=any","key1=binding1","key2=binding2"}, row);
- }
-
- /**
- * Included to ensure 0-10 Specification compliance:
- * 2.3.1.4 "the field in the bind arguments has no value and a field of the same name is present in the message headers
- */
- public void testHeadersExchangeMBeanMatchPropertyNoValue() throws Exception
- {
- HeadersExchange exchange = new HeadersExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost,ExchangeDefaults.HEADERS_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- mbean.createNewBinding(_queue.getNameShortString().toString(), "x-match=any,key4,key5=");
-
- TabularData data = mbean.bindings();
- ArrayList<Object> list = new ArrayList<Object>(data.values());
- assertEquals("Unexpected number of bindings", 1, list.size());
-
- final Iterator<CompositeDataSupport> rowItr = (Iterator<CompositeDataSupport>) data.values().iterator();
- CompositeDataSupport row = rowItr.next();
- assertBinding(1, _queue.getName(), new String[]{"x-match=any","key4=","key5="}, row);
- }
-
- public void testInvalidHeaderBindingMalformed() throws Exception
- {
- HeadersExchange exchange = new HeadersExchange();
- exchange.initialise(UUIDGenerator.generateUUID(), _virtualHost,ExchangeDefaults.HEADERS_EXCHANGE_NAME, false, 0, true);
- ManagedObject managedObj = exchange.getManagedObject();
- ManagedExchange mbean = (ManagedExchange)managedObj;
-
- try
- {
- mbean.createNewBinding(_queue.getNameShortString().toString(), "x-match=any,=value4");
- fail("Exception not thrown");
- }
- catch (JMException jme)
- {
- //pass
- }
- }
-
- private void assertBinding(final int expectedBindingNo, final String expectedQueueName, final String[] expectedBindingArray,
- final CompositeDataSupport row)
- {
- final Number bindingNumber = (Number) row.get(ManagedExchange.HDR_BINDING_NUMBER);
- final String queueName = (String) row.get(ManagedExchange.HDR_QUEUE_NAME);
- final String[] bindings = (String[]) row.get(ManagedExchange.HDR_QUEUE_BINDINGS);
- assertEquals("Unexpected binding number", expectedBindingNo, bindingNumber);
- assertEquals("Unexpected queue name", expectedQueueName, queueName);
- assertEquals("Unexpected no of bindings", expectedBindingArray.length, bindings.length);
- for(String binding : bindings)
- {
- assertTrue("Expected binding not found: " + binding, ArrayUtils.contains(expectedBindingArray, binding));
- }
- }
-
- /**
- * Test adding bindings and removing them from the default exchange via JMX.
- * <p>
- * QPID-2700
- */
- public void testDefaultBindings() throws Exception
- {
- int bindings = _queue.getBindingCount();
-
- Exchange exchange = _queue.getVirtualHost().getExchangeRegistry().getDefaultExchange();
- ManagedExchange mbean = (ManagedExchange) ((AbstractExchange) exchange).getManagedObject();
-
- mbean.createNewBinding(_queue.getName(), "robot");
- mbean.createNewBinding(_queue.getName(), "kitten");
-
- assertEquals("Should have added two bindings", bindings + 2, _queue.getBindingCount());
-
- mbean.removeBinding(_queue.getName(), "robot");
-
- assertEquals("Should have one extra binding", bindings + 1, _queue.getBindingCount());
-
- mbean.removeBinding(_queue.getName(), "kitten");
-
- assertEquals("Should have original number of binding", bindings, _queue.getBindingCount());
- }
-
- /**
- * Test adding bindings and removing them from the topic exchange via JMX.
- * <p>
- * QPID-2700
- */
- public void testTopicBindings() throws Exception
- {
- int bindings = _queue.getBindingCount();
-
- Exchange exchange = _queue.getVirtualHost().getExchangeRegistry().getExchange(new AMQShortString("amq.topic"));
- ManagedExchange mbean = (ManagedExchange) ((AbstractExchange) exchange).getManagedObject();
-
- mbean.createNewBinding(_queue.getName(), "robot.#");
- mbean.createNewBinding(_queue.getName(), "#.kitten");
-
- assertEquals("Should have added two bindings", bindings + 2, _queue.getBindingCount());
-
- mbean.removeBinding(_queue.getName(), "robot.#");
-
- assertEquals("Should have one extra binding", bindings + 1, _queue.getBindingCount());
-
- mbean.removeBinding(_queue.getName(), "#.kitten");
-
- assertEquals("Should have original number of binding", bindings, _queue.getBindingCount());
- }
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- IApplicationRegistry applicationRegistry = ApplicationRegistry.getInstance();
- _virtualHost = applicationRegistry.getVirtualHostRegistry().getVirtualHost("test");
- _queueRegistry = _virtualHost.getQueueRegistry();
- _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue"), false, new AMQShortString("ExchangeMBeanTest"), false, false,
- _virtualHost, null);
- _queueRegistry.registerQueue(_queue);
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
index 4305cdadc6..833df34fd8 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
@@ -7,9 +7,9 @@
* to you 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
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.exchange;
+import java.util.Collection;
import junit.framework.TestCase;
import org.apache.qpid.server.binding.Binding;
@@ -50,6 +51,16 @@ public class HeadersBindingTest extends TestCase
return 0;
}
+ public String getUserId()
+ {
+ return null;
+ }
+
+ public String getAppId()
+ {
+ return null;
+ }
+
public String getMessageId()
{
return null;
@@ -57,7 +68,7 @@ public class HeadersBindingTest extends TestCase
public String getMimeType()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return null;
}
public String getEncoding()
@@ -105,6 +116,12 @@ public class HeadersBindingTest extends TestCase
return _headers.keySet().containsAll(names);
}
+ @Override
+ public Collection<String> getHeaderNames()
+ {
+ return _headers.keySet();
+ }
+
public boolean containsHeader(String name)
{
return _headers.containsKey(name);
@@ -125,13 +142,13 @@ public class HeadersBindingTest extends TestCase
private MockHeader matchHeaders = new MockHeader();
private int _count = 0;
private MockAMQQueue _queue;
-
+
protected void setUp()
{
_count++;
_queue = new MockAMQQueue(getQueueName());
}
-
+
protected String getQueueName()
{
return "Queue" + _count;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java
deleted file mode 100644
index f9ad81ae74..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.logging.management;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import static org.apache.qpid.management.common.mbeans.LoggingManagement.LOGGER_LEVEL;
-import static org.apache.qpid.management.common.mbeans.LoggingManagement.LOGGER_NAME;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularDataSupport;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class LoggingManagementMBeanTest extends InternalBrokerBaseCase
-{
- private static final String TEST_LOGGER = "LoggingManagementMBeanTestLogger";
- private static final String TEST_LOGGER_CHILD1 = "LoggingManagementMBeanTestLogger.child1";
- private static final String TEST_LOGGER_CHILD2 = "LoggingManagementMBeanTestLogger.child2";
-
- private static final String TEST_CATEGORY_PRIORITY = "LogManMBeanTest.category.priority";
- private static final String TEST_CATEGORY_LEVEL = "LogManMBeanTest.category.level";
- private static final String TEST_LOGGER_LEVEL = "LogManMBeanTest.logger.level";
-
- private static final String NEWLINE = System.getProperty("line.separator");
-
- private File _testConfigFile;
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
- _testConfigFile = createTempTestLog4JConfig();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- File oldTestConfigFile = new File(_testConfigFile.getAbsolutePath() + ".old");
- if(oldTestConfigFile.exists())
- {
- oldTestConfigFile.delete();
- }
-
- _testConfigFile.delete();
-
- super.tearDown();
- }
-
- private File createTempTestLog4JConfig()
- {
- File tmpFile = null;
- try
- {
- tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp");
- tmpFile.deleteOnExit();
-
- FileWriter fstream = new FileWriter(tmpFile);
- BufferedWriter writer = new BufferedWriter(fstream);
-
- writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE);
- writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE);
-
- writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " +
- "threshold=\"null\">"+NEWLINE);
-
- writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE);
- writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE);
- writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE);
- writer.write(" </layout>"+NEWLINE);
- writer.write(" </appender>"+NEWLINE);
-
- //Example of a 'category' with a 'priority'
- writer.write(" <category additivity=\"true\" name=\"" + TEST_CATEGORY_PRIORITY +"\">"+NEWLINE);
- writer.write(" <priority value=\"info\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- //Example of a 'category' with a 'level'
- writer.write(" <category additivity=\"true\" name=\"" + TEST_CATEGORY_LEVEL +"\">"+NEWLINE);
- writer.write(" <level value=\"warn\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- //Example of a 'logger' with a 'level'
- writer.write(" <logger additivity=\"true\" name=\"" + TEST_LOGGER_LEVEL + "\">"+NEWLINE);
- writer.write(" <level value=\"error\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </logger>"+NEWLINE);
-
- //'root' logger
- writer.write(" <root>"+NEWLINE);
- writer.write(" <priority value=\"info\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </root>"+NEWLINE);
-
- writer.write("</log4j:configuration>"+NEWLINE);
-
- writer.flush();
- writer.close();
- }
- catch (IOException e)
- {
- fail("Unable to create temporary test log4j configuration");
- }
-
- return tmpFile;
- }
-
-
-
- //******* Test Methods ******* //
-
- public void testSetRuntimeLoggerLevel()
- {
- LoggingManagementMBean lm = null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- //create a parent test logger, set its level explicitly
- Logger log = Logger.getLogger(TEST_LOGGER);
- log.setLevel(Level.toLevel("info"));
-
- //create child1 test logger, check its *effective* level is the same as the parent, "info"
- Logger log1 = Logger.getLogger(TEST_LOGGER_CHILD1);
- assertTrue("Test logger's level was not the expected value",
- log1.getEffectiveLevel().toString().equalsIgnoreCase("info"));
-
- //now change its level to "warn"
- assertTrue("Failed to set logger level", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "warn"));
-
- //check the change, see its actual level is "warn
- assertTrue("Test logger's level was not the expected value",
- log1.getLevel().toString().equalsIgnoreCase("warn"));
-
- //try an invalid level
- assertFalse("Trying to set an invalid level succeded", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "made.up.level"));
- }
-
- public void testSetRuntimeRootLoggerLevel()
- {
- LoggingManagementMBean lm = null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- Logger log = Logger.getRootLogger();
-
- //get current root logger level
- Level origLevel = log.getLevel();
-
- //change level twice to ensure a new level is actually selected
-
- //set root loggers level to info
- assertTrue("Failed to set root logger level", lm.setRuntimeRootLoggerLevel("debug"));
- //check it is now actually info
- Level currentLevel = log.getLevel();
- assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("debug")));
-
- //try an invalid level
- assertFalse("Trying to set an invalid level succeded", lm.setRuntimeRootLoggerLevel("made.up.level"));
-
- //set root loggers level to warn
- assertTrue("Failed to set logger level", lm.setRuntimeRootLoggerLevel("info"));
- //check it is now actually warn
- currentLevel = log.getLevel();
- assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("info")));
-
- //restore original level
- log.setLevel(origLevel);
- }
-
- public void testGetRuntimeRootLoggerLevel()
- {
- LoggingManagementMBean lm = null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- Logger log = Logger.getRootLogger();
-
- //get current root logger level
- Level origLevel = log.getLevel();
-
- //change level twice to ensure a new level is actually selected
-
- //set root loggers level to debug
- log.setLevel(Level.toLevel("debug"));
- //check it is now actually debug
- assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("debug"));
-
-
- //set root loggers level to warn
- log.setLevel(Level.toLevel("info"));
- //check it is now actually warn
- assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("info"));
-
- //restore original level
- log.setLevel(origLevel);
- }
-
- public void testViewEffectiveRuntimeLoggerLevels()
- {
- LoggingManagementMBean lm = null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- //(re)create a parent test logger, set its level explicitly
- Logger log = Logger.getLogger(TEST_LOGGER);
- log.setLevel(Level.toLevel("info"));
-
- //retrieve the current effective runtime logger level values
- TabularDataSupport levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
- Collection<Object> records = levels.values();
- Map<String,String> list = new HashMap<String,String>();
- for (Object o : records)
- {
- CompositeData data = (CompositeData) o;
- list.put(data.get(LOGGER_NAME).toString(), data.get(LOGGER_LEVEL).toString());
- }
-
- //check child2 does not exist already
- assertFalse("Did not expect this logger to exist already", list.containsKey(TEST_LOGGER_CHILD2));
-
- //create child2 test logger
- Logger log2 = Logger.getLogger(TEST_LOGGER_CHILD2);
-
- //retrieve the current effective runtime logger level values
- levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
- records = levels.values();
- list = new HashMap<String,String>();
- for (Object o : records)
- {
- CompositeData data = (CompositeData) o;
- list.put(data.get(LOGGER_NAME).toString(), data.get(LOGGER_LEVEL).toString());
- }
-
- //verify the parent and child2 loggers are present in returned values
- assertTrue(TEST_LOGGER + " logger was not in the returned list", list.containsKey(TEST_LOGGER));
- assertTrue(TEST_LOGGER_CHILD2 + " logger was not in the returned list", list.containsKey(TEST_LOGGER_CHILD2));
-
- //check child2's effective level is the same as the parent, "info"
- assertTrue("Test logger's level was not the expected value",
- list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("info"));
-
- //now change its level explicitly to "warn"
- log2.setLevel(Level.toLevel("warn"));
-
- //retrieve the current effective runtime logger level values
- levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
- records = levels.values();
- list = new HashMap<String,String>();
- for (Object o : records)
- {
- CompositeData data = (CompositeData) o;
- list.put(data.get(LOGGER_NAME).toString(), data.get(LOGGER_LEVEL).toString());
- }
-
- //check child2's effective level is now "warn"
- assertTrue("Test logger's level was not the expected value",
- list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("warn"));
- }
-
- public void testViewAndSetConfigFileLoggerLevel() throws Exception
- {
- LoggingManagementMBean lm =null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- //retrieve the current values
- TabularDataSupport levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels();
- Collection<Object> records = levels.values();
- Map<String,String> list = new HashMap<String,String>();
- for (Object o : records)
- {
- CompositeData data = (CompositeData) o;
- list.put(data.get(LOGGER_NAME).toString(), data.get(LOGGER_LEVEL).toString());
- }
-
- //check the 3 different types of logger definition are successfully retrieved before update
- assertTrue("Wrong number of items in returned list", list.size() == 3);
- assertTrue(TEST_CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(TEST_CATEGORY_PRIORITY));
- assertTrue(TEST_CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(TEST_CATEGORY_LEVEL));
- assertTrue(TEST_LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(TEST_LOGGER_LEVEL));
-
- //check that their level is as expected
- assertTrue(TEST_CATEGORY_PRIORITY + " logger's level was incorrect", list.get(TEST_CATEGORY_PRIORITY).equalsIgnoreCase("info"));
- assertTrue(TEST_CATEGORY_LEVEL + " logger's level was incorrect", list.get(TEST_CATEGORY_LEVEL).equalsIgnoreCase("warn"));
- assertTrue(TEST_LOGGER_LEVEL + " logger's level was incorrect", list.get(TEST_LOGGER_LEVEL).equalsIgnoreCase("error"));
-
- //increase their levels a notch to test the 3 different types of logger definition are successfully updated
- //change the category+priority to warn
- assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(TEST_CATEGORY_PRIORITY, "warn"));
- //change the category+level to error
- assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(TEST_CATEGORY_LEVEL, "error"));
- //change the logger+level to trace
- assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(TEST_LOGGER_LEVEL, "trace"));
-
- //try an invalid level
- assertFalse("Use of an invalid logger level was successfull", lm.setConfigFileLoggerLevel(TEST_LOGGER_LEVEL, "made.up.level"));
-
- //try an invalid logger name
- assertFalse("Use of an invalid logger name was successfull", lm.setConfigFileLoggerLevel("made.up.logger.name", "info"));
-
- //retrieve the new values from the file and check them
- levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels();
- records = levels.values();
- list = new HashMap<String,String>();
- for (Object o : records)
- {
- CompositeData data = (CompositeData) o;
- list.put(data.get(LOGGER_NAME).toString(), data.get(LOGGER_LEVEL).toString());
- }
-
- //check the 3 different types of logger definition are successfully retrieved after update
- assertTrue("Wrong number of items in returned list", list.size() == 3);
- assertTrue(TEST_CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(TEST_CATEGORY_PRIORITY));
- assertTrue(TEST_CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(TEST_CATEGORY_LEVEL));
- assertTrue(TEST_LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(TEST_LOGGER_LEVEL));
-
- //check that their level is as expected after the changes
- assertTrue(TEST_CATEGORY_PRIORITY + " logger's level was incorrect", list.get(TEST_CATEGORY_PRIORITY).equalsIgnoreCase("warn"));
- assertTrue(TEST_CATEGORY_LEVEL + " logger's level was incorrect", list.get(TEST_CATEGORY_LEVEL).equalsIgnoreCase("error"));
- assertTrue(TEST_LOGGER_LEVEL + " logger's level was incorrect", list.get(TEST_LOGGER_LEVEL).equalsIgnoreCase("trace"));
- }
-
- public void testGetAndSetConfigFileRootLoggerLevel() throws Exception
- {
- LoggingManagementMBean lm =null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- //retrieve the current value
- String level = lm.getConfigFileRootLoggerLevel();
-
- //check the value was successfully retrieved before update
- assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("info"));
-
- //try an invalid level
- assertFalse("Use of an invalid RootLogger level was successfull", lm.setConfigFileRootLoggerLevel("made.up.level"));
-
- //change the level to warn
- assertTrue("Failed to set new RootLogger level", lm.setConfigFileRootLoggerLevel("warn"));
-
- //retrieve the current value
- level = lm.getConfigFileRootLoggerLevel();
-
- //check the value was successfully retrieved after update
- assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("warn"));
- }
-
- public void testGetLog4jLogWatchInterval()
- {
- LoggingManagementMBean lm =null;
- try
- {
- lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 5000);
- }
- catch (JMException e)
- {
- fail("Could not create test LoggingManagementMBean");
- }
-
- assertTrue("Wrong value returned for logWatch period", lm.getLog4jLogWatchInterval() == 5000);
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
deleted file mode 100644
index f7d85c11a8..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-/**
- *
- * Tests the AMQUserManagementMBean and its interaction with the PrincipalDatabase.
- *
- */
-public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
-{
- private PlainPasswordFilePrincipalDatabase _database;
- private AMQUserManagementMBean _amqumMBean;
-
- private File _passwordFile;
-
- private static final String TEST_USERNAME = "testuser";
- private static final String TEST_PASSWORD = "password";
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- _database = new PlainPasswordFilePrincipalDatabase();
- _amqumMBean = new AMQUserManagementMBean();
- loadFreshTestPasswordFile();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- //clean up test password/access files
- File _oldPasswordFile = new File(_passwordFile.getAbsolutePath() + ".old");
- _oldPasswordFile.delete();
- _passwordFile.delete();
-
- super.tearDown();
- }
-
- public void testDeleteUser()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Delete should return true to flag successful delete", _amqumMBean.deleteUser(TEST_USERNAME));
- assertEquals("Unexpected number of users after test", 0,_amqumMBean.viewUsers().size());
- }
-
- public void testDeleteUserWhereUserDoesNotExist()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Delete should return false to flag unsuccessful delete", _amqumMBean.deleteUser("made.up.username"));
- assertEquals("Unexpected number of users after test", 1,_amqumMBean.viewUsers().size());
-
- }
-
- public void testCreateUser()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Create should return true to flag successful create", _amqumMBean.createUser("newuser", "mypass"));
- assertEquals("Unexpected number of users before test", 2,_amqumMBean.viewUsers().size());
- }
-
- public void testCreateUserWhereUserAlreadyExists()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Create should return false to flag unsuccessful create", _amqumMBean.createUser(TEST_USERNAME, "mypass"));
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- }
-
- public void testSetPassword()
- {
- assertTrue("Set password should return true to flag successful change", _amqumMBean.setPassword(TEST_USERNAME, "newpassword"));
- }
-
- public void testSetPasswordWhereUserDoesNotExist()
- {
- assertFalse("Set password should return false to flag successful change", _amqumMBean.setPassword("made.up.username", "newpassword"));
- }
-
- public void testViewUsers()
- {
- TabularData userList = _amqumMBean.viewUsers();
-
- assertNotNull(userList);
- assertEquals("Unexpected number of users in user list", 1, userList.size());
- assertTrue(userList.containsKey(new Object[]{TEST_USERNAME}));
-
- // Check the deprecated read, write and admin items continue to exist but return false.
- CompositeData userRec = userList.get(new Object[]{TEST_USERNAME});
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_ADMIN));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_ADMIN));
- }
-
- // ============================ Utility methods =========================
-
- private void loadFreshTestPasswordFile()
- {
- try
- {
- if(_passwordFile == null)
- {
- _passwordFile = File.createTempFile(this.getClass().getName(),".password");
- }
-
- BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(_passwordFile, false));
- passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD);
- passwordWriter.newLine();
- passwordWriter.flush();
- passwordWriter.close();
- _database.setPasswordFile(_passwordFile.toString());
- _amqumMBean.setPrincipalDatabase(_database);
- }
- catch (IOException e)
- {
- fail("Unable to create test password file: " + e.getMessage());
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
deleted file mode 100644
index fe9bcc57a6..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.protocol;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-
-/** Test class to test MBean operations for AMQMinaProtocolSession. */
-public class AMQProtocolSessionMBeanTest extends InternalBrokerBaseCase
-{
- /** Used for debugging. */
- private static final Logger log = Logger.getLogger(AMQProtocolSessionMBeanTest.class);
-
- private MessageStore _messageStore = new TestableMemoryMessageStore();
- private AMQProtocolEngine _protocolSession;
- private AMQChannel _channel;
- private AMQProtocolSessionMBean _mbean;
-
- public void testChannels() throws Exception
- {
- // check the channel count is correct
- int channelCount = _mbean.channels().size();
- assertTrue(channelCount == 1);
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue_" + System.currentTimeMillis()),
- false,
- new AMQShortString("test"),
- true,
- false, _protocolSession.getVirtualHost(), null);
- AMQChannel channel = new AMQChannel(_protocolSession, 2, _messageStore);
- channel.setDefaultQueue(queue);
- _protocolSession.addChannel(channel);
- channelCount = _mbean.channels().size();
- assertTrue(channelCount == 2);
-
- // general properties test
- _protocolSession.setMaximumNumberOfChannels(1000L);
- assertTrue(_mbean.getMaximumNumberOfChannels() == 1000L);
-
- // check APIs
- AMQChannel channel3 = new AMQChannel(_protocolSession, 3, _messageStore);
- channel3.setLocalTransactional();
- _protocolSession.addChannel(channel3);
- _mbean.rollbackTransactions(2);
- _mbean.rollbackTransactions(3);
- _mbean.commitTransactions(2);
- _mbean.commitTransactions(3);
-
- // This should throw exception, because the channel does't exist
- try
- {
- _mbean.commitTransactions(4);
- fail();
- }
- catch (JMException ex)
- {
- log.debug("expected exception is thrown :" + ex.getMessage());
- }
-
- // check channels() return type conveys flow control blocking status correctly
- AMQChannel channel4 = new AMQChannel(_protocolSession, 4, _messageStore);
- _protocolSession.addChannel(channel4);
- channel4.setDefaultQueue(queue);
-
- final String blocking = ManagedConnection.FLOW_BLOCKED;
- TabularData channels = _mbean.channels();
- CompositeData chan4result = channels.get(new Integer[]{4});
- assertNotNull(chan4result);
- assertEquals("Flow should not have been blocked", false, chan4result.get(blocking));
-
- channel4.block(queue);
- channels = _mbean.channels();
- chan4result = channels.get(new Integer[]{4});
- assertNotNull(chan4result);
- assertEquals("Flow should have been blocked", true, chan4result.get(blocking));
-
- channel4.unblock(queue);
- channels = _mbean.channels();
- chan4result = channels.get(new Integer[]{4});
- assertNotNull(chan4result);
- assertEquals("Flow should have been unblocked", false, chan4result.get(blocking));
-
- // check if closing of session works
- _protocolSession.addChannel(new AMQChannel(_protocolSession, 5, _messageStore));
- _mbean.closeConnection();
- try
- {
- channelCount = _mbean.channels().size();
- assertTrue(channelCount == 0);
- // session is now closed so adding another channel should throw an exception
- _protocolSession.addChannel(new AMQChannel(_protocolSession, 6, _messageStore));
- fail();
- }
- catch (AMQException ex)
- {
- log.debug("expected exception is thrown :" + ex.getMessage());
- }
- }
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- _protocolSession = new InternalTestProtocolSession(vhost);
-
- _channel = new AMQChannel(_protocolSession, 1, _messageStore);
- _protocolSession.addChannel(_channel);
- _mbean = (AMQProtocolSessionMBean) _protocolSession.getManagedObject();
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
deleted file mode 100644
index 25d35aab16..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.queue;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.abstraction.ContentChunk;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import javax.management.Notification;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/** This class tests all the alerts an AMQQueue can throw based on threshold values of different parameters */
-public class AMQQueueAlertTest extends InternalBrokerBaseCase
-{
- private final static long MAX_MESSAGE_COUNT = 50;
- private final static long MAX_MESSAGE_AGE = 250; // 0.25 sec
- private final static long MAX_MESSAGE_SIZE = 2000; // 2 KB
- private final static long MAX_QUEUE_DEPTH = 10000; // 10 KB
- private AMQQueueMBean _queueMBean;
- private static final SubscriptionFactoryImpl SUBSCRIPTION_FACTORY = SubscriptionFactoryImpl.INSTANCE;
-
- /**
- * Tests if the alert gets thrown when message count increases the threshold limit
- *
- * @throws Exception
- */
- public void testMessageCountAlert() throws Exception
- {
- setSession(new InternalTestProtocolSession(getVirtualHost()));
- AMQChannel channel = new AMQChannel(getSession(), 2, getMessageStore());
- getSession().addChannel(channel);
-
- setQueue(AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue1"), false, new AMQShortString("AMQueueAlertTest"),
- false, false,
- getVirtualHost(), null));
- _queueMBean = (AMQQueueMBean) getQueue().getManagedObject();
-
- _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT);
-
- sendMessages(channel, MAX_MESSAGE_COUNT, 256l);
- assertTrue(_queueMBean.getMessageCount() == MAX_MESSAGE_COUNT);
-
- Notification lastNotification = _queueMBean.getLastNotification();
- assertNotNull(lastNotification);
-
- String notificationMsg = lastNotification.getMessage();
- assertTrue(notificationMsg.startsWith(NotificationCheck.MESSAGE_COUNT_ALERT.name()));
- }
-
- /**
- * Tests if the Message Size alert gets thrown when message of higher than threshold limit is sent
- *
- * @throws Exception
- */
- public void testMessageSizeAlert() throws Exception
- {
- setSession(new InternalTestProtocolSession(getVirtualHost()));
- AMQChannel channel = new AMQChannel(getSession(), 2, getMessageStore());
- getSession().addChannel(channel);
-
- setQueue(AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue2"), false, new AMQShortString("AMQueueAlertTest"),
- false, false,
- getVirtualHost(), null));
- _queueMBean = (AMQQueueMBean) getQueue().getManagedObject();
- _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT);
- _queueMBean.setMaximumMessageSize(MAX_MESSAGE_SIZE);
-
- sendMessages(channel, 1, MAX_MESSAGE_SIZE * 2);
- assertTrue(_queueMBean.getMessageCount() == 1);
-
- Notification lastNotification = _queueMBean.getLastNotification();
- assertNotNull(lastNotification);
-
- String notificationMsg = lastNotification.getMessage();
- assertTrue(notificationMsg.startsWith(NotificationCheck.MESSAGE_SIZE_ALERT.name()));
- }
-
- /**
- * Tests if Queue Depth alert is thrown when queue depth reaches the threshold value
- *
- * Based on FT-402 subbmitted by client
- *
- * @throws Exception
- */
- public void testQueueDepthAlertNoSubscriber() throws Exception
- {
- setSession(new InternalTestProtocolSession(getVirtualHost()));
- AMQChannel channel = new AMQChannel(getSession(), 2, getMessageStore());
- getSession().addChannel(channel);
-
- setQueue(AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue3"), false, new AMQShortString("AMQueueAlertTest"),
- false, false,
- getVirtualHost(), null));
- _queueMBean = (AMQQueueMBean) getQueue().getManagedObject();
- _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT);
- _queueMBean.setMaximumQueueDepth(MAX_QUEUE_DEPTH);
-
- while (getQueue().getQueueDepth() < MAX_QUEUE_DEPTH)
- {
- sendMessages(channel, 1, MAX_MESSAGE_SIZE);
- }
-
- Notification lastNotification = _queueMBean.getLastNotification();
- assertNotNull(lastNotification);
-
- String notificationMsg = lastNotification.getMessage();
- assertTrue(notificationMsg.startsWith(NotificationCheck.QUEUE_DEPTH_ALERT.name()));
- }
-
- /**
- * Tests if MESSAGE AGE alert is thrown, when a message is in the queue for time higher than threshold value of
- * message age
- *
- * Alternative test to FT-401 provided by client
- *
- * @throws Exception
- */
- public void testMessageAgeAlert() throws Exception
- {
- setSession(new InternalTestProtocolSession(getVirtualHost()));
- AMQChannel channel = new AMQChannel(getSession(), 2, getMessageStore());
- getSession().addChannel(channel);
-
- setQueue(AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue4"), false, new AMQShortString("AMQueueAlertTest"),
- false, false,
- getVirtualHost(), null));
- _queueMBean = (AMQQueueMBean) getQueue().getManagedObject();
- _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT);
- _queueMBean.setMaximumMessageAge(MAX_MESSAGE_AGE);
-
- sendMessages(channel, 1, MAX_MESSAGE_SIZE);
-
- // Ensure message sits on queue long enough to age.
- Thread.sleep(MAX_MESSAGE_AGE * 2);
-
- Notification lastNotification = _queueMBean.getLastNotification();
- assertNotNull("Last notification was null", lastNotification);
-
- String notificationMsg = lastNotification.getMessage();
- assertTrue(notificationMsg.startsWith(NotificationCheck.MESSAGE_AGE_ALERT.name()));
- }
-
- /*
- This test sends some messages to the queue with subscribers needing message to be acknowledged.
- The messages will not be acknowledged and will be required twice. Why we are checking this is because
- the bug reported said that the queueDepth keeps increasing when messages are requeued.
- // TODO - queue depth now includes unacknowledged messages so does not go down when messages are delivered
-
- The QueueDepth should decrease when messages are delivered from the queue (QPID-408)
- */
- public void testQueueDepthAlertWithSubscribers() throws Exception
- {
- AMQChannel channel = new AMQChannel(getSession(), 2, getMessageStore());
- getSession().addChannel(channel);
-
- // Create queue
- setQueue(getNewQueue());
- Subscription subscription =
- SUBSCRIPTION_FACTORY.createSubscription(channel.getChannelId(), getSession(), new AMQShortString("consumer_tag"), true, null, false, channel.getCreditManager());
-
- getQueue().registerSubscription(
- subscription, false);
-
- _queueMBean = (AMQQueueMBean) getQueue().getManagedObject();
- _queueMBean.setMaximumMessageCount(9999l); // Set a high value, because this is not being tested
- _queueMBean.setMaximumQueueDepth(MAX_QUEUE_DEPTH);
-
- // Send messages(no of message to be little more than what can cause a Queue_Depth alert)
- int messageCount = Math.round(MAX_QUEUE_DEPTH / MAX_MESSAGE_SIZE) + 10;
- long totalSize = (messageCount * MAX_MESSAGE_SIZE);
- sendMessages(channel, messageCount, MAX_MESSAGE_SIZE);
-
- // Check queueDepth. There should be no messages on the queue and as the subscriber is listening
- // so there should be no Queue_Deoth alert raised
- assertEquals(new Long(totalSize), new Long(_queueMBean.getQueueDepth()));
- Notification lastNotification = _queueMBean.getLastNotification();
-// assertNull(lastNotification);
-
- // Kill the subscriber and check for the queue depth values.
- // Messages are unacknowledged, so those should get requeued. All messages should be on the Queue
- getQueue().unregisterSubscription(subscription);
- channel.requeue();
-
- assertEquals(new Long(totalSize), new Long(_queueMBean.getQueueDepth()));
-
- lastNotification = _queueMBean.getLastNotification();
- assertNotNull(lastNotification);
- String notificationMsg = lastNotification.getMessage();
- assertTrue(notificationMsg.startsWith(NotificationCheck.QUEUE_DEPTH_ALERT.name()));
-
- // Connect a consumer again and check QueueDepth values. The queue should get emptied.
- // Messages will get delivered but still are unacknowledged.
- Subscription subscription2 =
- SUBSCRIPTION_FACTORY.createSubscription(channel.getChannelId(), getSession(), new AMQShortString("consumer_tag"), true, null, false, channel.getCreditManager());
-
- getQueue().registerSubscription(
- subscription2, false);
-
- while (getQueue().getUndeliveredMessageCount()!= 0)
- {
- Thread.sleep(100);
- }
-// assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth()));
-
- // Kill the subscriber again. Now those messages should get requeued again. Check if the queue depth
- // value is correct.
- getQueue().unregisterSubscription(subscription2);
- channel.requeue();
-
- assertEquals(new Long(totalSize), new Long(_queueMBean.getQueueDepth()));
- getSession().closeSession();
-
- // Check the clear queue
- _queueMBean.clearQueue();
- assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth()));
- }
-
- protected IncomingMessage message(final boolean immediate, long size) throws AMQException
- {
- MessagePublishInfo publish = new MessagePublishInfo()
- {
-
- public AMQShortString getExchange()
- {
- return null;
- }
-
- public void setExchange(AMQShortString exchange)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isImmediate()
- {
- return immediate;
- }
-
- public boolean isMandatory()
- {
- return false;
- }
-
- public AMQShortString getRoutingKey()
- {
- return null;
- }
- };
-
- ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
- BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- contentHeaderBody.setProperties(props);
- contentHeaderBody.setBodySize(size); // in bytes
- IncomingMessage message = new IncomingMessage(publish);
- message.setContentHeaderBody(contentHeaderBody);
-
- return message;
- }
-
- @Override
- protected void configure()
- {
- // Increase Alert Check period
- getConfiguration().setHousekeepingCheckPeriod(200);
- }
-
- private void sendMessages(AMQChannel channel, long messageCount, final long size) throws AMQException
- {
- IncomingMessage[] messages = new IncomingMessage[(int) messageCount];
- MessageMetaData[] metaData = new MessageMetaData[(int) messageCount];
- for (int i = 0; i < messages.length; i++)
- {
- messages[i] = message(false, size);
- ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
- qs.add(getQueue());
- metaData[i] = messages[i].headersReceived(System.currentTimeMillis());
- messages[i].setStoredMessage(getMessageStore().addMessage(metaData[i]));
-
- messages[i].enqueue(qs);
-
- }
-
- for (int i = 0; i < messageCount; i++)
- {
- ContentChunk contentChunk = new ContentChunk()
- {
- private byte[] _data = new byte[(int)size];
-
- public int getSize()
- {
- return (int) size;
- }
-
- public byte[] getData()
- {
- return _data;
- }
-
- public void reduceToFit()
- {
- }
- };
-
- messages[i].addContentBodyFrame(contentChunk);
- messages[i].getStoredMessage().addContent(0, ByteBuffer.wrap(contentChunk.getData()));
-
- getQueue().enqueue(new AMQMessage(messages[i].getStoredMessage()));
- }
- }
-
- private AMQQueue getNewQueue() throws AMQException
- {
- return AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue" + Math.random()),
- false,
- new AMQShortString("AMQueueAlertTest"),
- false,
- false, getVirtualHost(), null);
- }
-}
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
deleted file mode 100644
index 89c14c40a0..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.queue;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentBody;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.abstraction.ContentChunk;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.subscription.SubscriptionFactory;
-import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-/**
- * Test class to test AMQQueueMBean attributes and operations
- */
-public class AMQQueueMBeanTest extends InternalBrokerBaseCase
-{
- private static long MESSAGE_SIZE = 1000;
- private AMQQueueMBean _queueMBean;
- private static final SubscriptionFactoryImpl SUBSCRIPTION_FACTORY = SubscriptionFactoryImpl.INSTANCE;
-
- public void testMessageCountTransient() throws Exception
- {
- int messageCount = 10;
- sendMessages(messageCount, false);
- assertTrue(_queueMBean.getMessageCount() == messageCount);
- assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
- long queueDepth = (messageCount * MESSAGE_SIZE);
- assertTrue(_queueMBean.getQueueDepth() == queueDepth);
-
- _queueMBean.deleteMessageFromTop();
- assertTrue(_queueMBean.getMessageCount() == (messageCount - 1));
- assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
-
- _queueMBean.clearQueue();
- assertEquals(0,(int)_queueMBean.getMessageCount());
- assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
-
- //Ensure that the data has been removed from the Store
- verifyBrokerState();
- }
-
- public void testMessageCountPersistent() 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);
-
- _queueMBean.deleteMessageFromTop();
- assertTrue(_queueMBean.getMessageCount() == (messageCount - 1));
- assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
-
- _queueMBean.clearQueue();
- assertTrue(_queueMBean.getMessageCount() == 0);
- assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
-
- //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()
- {
-
- TestableMemoryMessageStore store = (TestableMemoryMessageStore) getVirtualHost().getMessageStore();
-
- // Unlike MessageReturnTest there is no need for a delay as there this thread does the clean up.
-
- assertEquals("Store should have no messages:" + store.getMessageCount(), 0, store.getMessageCount());
- }
-
- public void testConsumerCount() throws AMQException
- {
-
- assertTrue(getQueue().getActiveConsumerCount() == 0);
- assertTrue(_queueMBean.getActiveConsumerCount() == 0);
-
-
- InternalTestProtocolSession protocolSession = new InternalTestProtocolSession(getVirtualHost());
-
- AMQChannel channel = new AMQChannel(protocolSession, 1, getMessageStore());
- protocolSession.addChannel(channel);
-
- Subscription subscription =
- SUBSCRIPTION_FACTORY.createSubscription(channel.getChannelId(), protocolSession, new AMQShortString("test"), false, null, false, channel.getCreditManager());
-
- getQueue().registerSubscription(subscription, false);
- assertEquals(1,(int)_queueMBean.getActiveConsumerCount());
-
-
- SubscriptionFactory subscriptionFactory = SUBSCRIPTION_FACTORY;
- Subscription s1 = subscriptionFactory.createSubscription(channel.getChannelId(),
- protocolSession,
- new AMQShortString("S1"),
- false,
- null,
- true,
- channel.getCreditManager());
-
- Subscription s2 = subscriptionFactory.createSubscription(channel.getChannelId(),
- protocolSession,
- new AMQShortString("S2"),
- false,
- null,
- true,
- channel.getCreditManager());
- getQueue().registerSubscription(s1,false);
- getQueue().registerSubscription(s2,false);
- assertTrue(_queueMBean.getActiveConsumerCount() == 3);
- assertTrue(_queueMBean.getConsumerCount() == 3);
-
- s1.close();
- assertEquals(2, (int) _queueMBean.getActiveConsumerCount());
- assertTrue(_queueMBean.getConsumerCount() == 3);
- }
-
- public void testGeneralProperties() throws Exception
- {
- long maxQueueDepth = 1000; // in bytes
- _queueMBean.setMaximumMessageCount(50000l);
- _queueMBean.setMaximumMessageSize(2000l);
- _queueMBean.setMaximumQueueDepth(maxQueueDepth);
-
- assertEquals("Max MessageCount not set",50000,_queueMBean.getMaximumMessageCount().longValue());
- assertEquals("Max MessageSize not set",2000, _queueMBean.getMaximumMessageSize().longValue());
- assertEquals("Max QueueDepth not set",maxQueueDepth, _queueMBean.getMaximumQueueDepth().longValue());
-
- assertEquals("Queue Name does not match", new AMQShortString(getName()), _queueMBean.getName());
- assertFalse("AutoDelete should not be set.",_queueMBean.isAutoDelete());
- assertFalse("Queue should not be durable.",_queueMBean.isDurable());
-
- //set+get exclusivity using the mbean, and also verify it is actually updated in the queue
- _queueMBean.setExclusive(true);
- assertTrue("Exclusive property should be true.",_queueMBean.isExclusive());
- assertTrue("Exclusive property should be true.", getQueue().isExclusive());
- _queueMBean.setExclusive(false);
- assertFalse("Exclusive property should be false.",_queueMBean.isExclusive());
- assertFalse("Exclusive property should be false.", getQueue().isExclusive());
- }
-
- /**
- * Tests view messages with two test messages. The first message is non-persistent, the second persistent
- * and has timestamp/expiration.
- *
- */
- public void testViewMessages() throws Exception
- {
- sendMessages(1, false);
- final Date msg2Timestamp = new Date();
- final Date msg2Expiration = new Date(msg2Timestamp.getTime() + 1000);
- sendMessages(1, true, msg2Timestamp.getTime(), msg2Expiration.getTime());
-
- final TabularData tab = _queueMBean.viewMessages(1l, 2l);
- assertEquals("Unexpected number of rows in table", 2, tab.size());
- final Iterator<CompositeDataSupport> rowItr = (Iterator<CompositeDataSupport>) tab.values().iterator();
-
- // Check row1
- final CompositeDataSupport row1 = rowItr.next();
- assertEquals("Message should have AMQ message id", 1l, row1.get(ManagedQueue.MSG_AMQ_ID));
- assertNotNull("Expected message header array", row1.get(ManagedQueue.MSG_HEADER));
- final Map<String, String> row1Headers = headerArrayToMap((String[])row1.get(ManagedQueue.MSG_HEADER));
- assertEquals("Unexpected JMSPriority within header", "Non_Persistent", row1Headers.get("JMSDeliveryMode"));
- assertEquals("Unexpected JMSTimestamp within header", "null", row1Headers.get("JMSTimestamp"));
- assertEquals("Unexpected JMSExpiration within header", "null", row1Headers.get("JMSExpiration"));
-
- final CompositeDataSupport row2 = rowItr.next();
- assertEquals("Message should have AMQ message id", 2l, row2.get(ManagedQueue.MSG_AMQ_ID));
- assertNotNull("Expected message header array", row2.get(ManagedQueue.MSG_HEADER));
- final Map<String, String> row2Headers = headerArrayToMap((String[])row2.get(ManagedQueue.MSG_HEADER));
- assertEquals("Unexpected JMSPriority within header", "Persistent", row2Headers.get("JMSDeliveryMode"));
- final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(AMQQueueMBean.JMSTIMESTAMP_DATETIME_FORMAT);
- assertEquals("Unexpected JMSTimestamp within header", msg2Timestamp,
- simpleDateFormat.parse(row2Headers.get("JMSTimestamp")));
- assertEquals("Unexpected JMSExpiration within header", msg2Expiration,
- simpleDateFormat.parse(row2Headers.get("JMSExpiration")));
- }
-
- public void testViewMessageWithIllegalStartEndRanges() throws Exception
- {
- try
- {
- _queueMBean.viewMessages(0L, 3L);
- fail();
- }
- catch (JMException ex)
- {
- // PASS
- }
-
- try
- {
- _queueMBean.viewMessages(2L, 1L);
- fail();
- }
- catch (JMException ex)
- {
- // PASS
- }
-
- try
- {
- _queueMBean.viewMessages(-1L, 1L);
- fail();
- }
- catch (JMException ex)
- {
- // PASS
- }
-
- 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)
- {
- // PASS
- }
- }
-
- public void testViewMessageContent() throws Exception
- {
- final List<AMQMessage> sentMessages = sendMessages(1, true);
- final Long id = sentMessages.get(0).getMessageId();
-
- final CompositeData messageData = _queueMBean.viewMessageContent(id);
- assertNotNull(messageData);
- }
-
- public void testViewMessageContentWithUnknownMessageId() throws Exception
- {
- final List<AMQMessage> sentMessages = sendMessages(1, true);
- final Long id = sentMessages.get(0).getMessageId();
-
- try
- {
- _queueMBean.viewMessageContent(id + 1);
- fail();
- }
- catch (JMException ex)
- {
- // PASS
- }
- }
-
- public void testFlowControlProperties() throws Exception
- {
- assertTrue(_queueMBean.getCapacity() == 0);
- assertTrue(_queueMBean.getFlowResumeCapacity() == 0);
- assertFalse(_queueMBean.isFlowOverfull());
-
- //capacity currently 0, try setting FlowResumeCapacity above this
- try
- {
- _queueMBean.setFlowResumeCapacity(1L);
- fail("Should have failed to allow setting FlowResumeCapacity above Capacity");
- }
- catch (IllegalArgumentException ex)
- {
- //expected exception
- assertTrue(_queueMBean.getFlowResumeCapacity() == 0);
- }
-
- //add a message to the queue
- sendMessages(1, true);
-
- //(FlowResume)Capacity currently 0, set both to 2
- _queueMBean.setCapacity(2L);
- assertTrue(_queueMBean.getCapacity() == 2L);
- _queueMBean.setFlowResumeCapacity(2L);
- assertTrue(_queueMBean.getFlowResumeCapacity() == 2L);
-
- //Try setting Capacity below FlowResumeCapacity
- try
- {
- _queueMBean.setCapacity(1L);
- fail("Should have failed to allow setting Capacity below FlowResumeCapacity");
- }
- catch (IllegalArgumentException ex)
- {
- //expected exception
- assertTrue(_queueMBean.getCapacity() == 2);
- }
-
- //create a channel and use it to exercise the capacity check mechanism
- AMQChannel channel = new AMQChannel(getSession(), 1, getMessageStore());
- getQueue().checkCapacity(channel);
-
- assertTrue(_queueMBean.isFlowOverfull());
- assertTrue(channel.getBlocking());
-
- //set FlowResumeCapacity to MESSAGE_SIZE and check queue is now underfull and channel unblocked
- _queueMBean.setCapacity(MESSAGE_SIZE);//must increase capacity too
- _queueMBean.setFlowResumeCapacity(MESSAGE_SIZE);
-
- assertFalse(_queueMBean.isFlowOverfull());
- assertFalse(channel.getBlocking());
- }
-
- public void testMaximumDeliveryCount() throws IOException
- {
- assertEquals("Unexpected default maximum delivery count", Integer.valueOf(0), _queueMBean.getMaximumDeliveryCount());
- }
-
- public void testViewAllMessages() throws Exception
- {
- final int messageCount = 5;
- sendPersistentMessages(messageCount);
-
-
- final TabularData messageTable = _queueMBean.viewMessages(1L, 5L);
- assertNotNull("Message table should not be null", messageTable);
- assertEquals("Unexpected number of rows", messageCount, messageTable.size());
-
-
- final Iterator rowIterator = messageTable.values().iterator();
- // Get its message ID
- final CompositeDataSupport row1 = (CompositeDataSupport) rowIterator.next();
- final Long msgId = (Long) row1.get("AMQ MessageId");
- final Long queuePosition = (Long) row1.get("Queue Position");
- final Integer deliveryCount = (Integer) row1.get("Delivery Count");
-
- assertNotNull("Row should have value for queue position", queuePosition);
- assertNotNull("Row should have value for msgid", msgId);
- assertNotNull("Row should have value for deliveryCount", deliveryCount);
- }
-
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- _queueMBean = new AMQQueueMBean(getQueue());
- }
-
- public void tearDown()
- {
- ApplicationRegistry.remove();
- }
-
- private void sendPersistentMessages(int messageCount) throws AMQException
- {
- sendMessages(messageCount, true);
- assertEquals("Expected " + messageCount + " messages in the queue", messageCount, _queueMBean
- .getMessageCount().intValue());
- }
-
- private List<AMQMessage> sendMessages(int messageCount, boolean persistent) throws AMQException
- {
- return sendMessages(messageCount, persistent, 0l, 0l);
- }
-
- private List<AMQMessage> sendMessages(int messageCount, boolean persistent, long timestamp, long expiration) throws AMQException
- {
- final List<AMQMessage> sentMessages = new ArrayList<AMQMessage>();
-
- for (int i = 0; i < messageCount; i++)
- {
- IncomingMessage currentMessage = createIncomingMessage(false, persistent, timestamp, expiration);
- ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
- qs.add(getQueue());
- currentMessage.enqueue(qs);
-
- // route header
- MessageMetaData mmd = currentMessage.headersReceived(System.currentTimeMillis());
-
- // Add the message to the store so we have something to test later
- currentMessage.setStoredMessage(getMessageStore().addMessage(mmd));
- ContentChunk chunk = getSession().getMethodRegistry()
- .getProtocolVersionMethodConverter()
- .convertToContentChunk(
- new ContentBody(new byte[(int) MESSAGE_SIZE]));
- currentMessage.addContentBodyFrame(chunk);
- currentMessage.getStoredMessage().addContent(0, ByteBuffer.wrap(chunk.getData()));
-
- AMQMessage m = new AMQMessage(currentMessage.getStoredMessage());
- for(BaseQueue q : currentMessage.getDestinationQueues())
- {
- q.enqueue(m);
- }
-
- sentMessages.add(m);
- }
-
- return sentMessages;
- }
-
- private IncomingMessage createIncomingMessage(final boolean immediate, boolean persistent, long timestamp, long expiration) throws AMQException
- {
- MessagePublishInfo publish = new MessagePublishInfo()
- {
-
- public AMQShortString getExchange()
- {
- return null;
- }
-
- public void setExchange(AMQShortString exchange)
- {
- }
-
- public boolean isImmediate()
- {
- return immediate;
- }
-
- public boolean isMandatory()
- {
- return false;
- }
-
- public AMQShortString getRoutingKey()
- {
- return null;
- }
- };
-
- ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
- contentHeaderBody.setBodySize(MESSAGE_SIZE); // in bytes
- final BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- contentHeaderBody.setProperties(props);
- props.setDeliveryMode((byte) (persistent ? 2 : 1));
- if (timestamp > 0)
- {
- props.setTimestamp(timestamp);
- }
- if (expiration > 0)
- {
- props.setExpiration(expiration);
- }
- IncomingMessage msg = new IncomingMessage(publish);
- msg.setContentHeaderBody(contentHeaderBody);
- return msg;
- }
-
- /**
- *
- * Utility method to convert array of Strings in the form x = y into a
- * map with key/value x =&gt; y.
- *
- */
- private Map<String,String> headerArrayToMap(final String[] headerArray)
- {
- final Map<String, String> headerMap = new HashMap<String, String>();
- final List<String> headerList = Arrays.asList(headerArray);
- for (Iterator<String> iterator = headerList.iterator(); iterator.hasNext();)
- {
- final String nameValuePair = iterator.next();
- final String[] nameValue = nameValuePair.split(" *= *", 2);
- headerMap.put(nameValue[0], nameValue[1]);
- }
- return headerMap;
- }
-
-
-}
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 afaa417415..d3eb61a544 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
@@ -29,13 +29,14 @@ import org.apache.qpid.server.configuration.QueueConfigType;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.security.AuthorizationHolder;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -51,7 +52,6 @@ public class MockAMQQueue implements AMQQueue
private AuthorizationHolder _authorizationHolder;
private AMQSessionModel _exclusiveOwner;
- private AMQShortString _owner;
private List<Binding> _bindings = new CopyOnWriteArrayList<Binding>();
private boolean _autoDelete;
@@ -98,7 +98,12 @@ public class MockAMQQueue implements AMQQueue
return "[MockAMQQueue]";
}
- };
+ };
+ }
+
+ public long getUnackedMessageBytes()
+ {
+ return 0;
}
public ConfigStore getConfigStore()
@@ -121,6 +126,16 @@ public class MockAMQQueue implements AMQQueue
return 0;
}
+ public long getTotalDequeueCount()
+ {
+ return 0;
+ }
+
+ public long getTotalEnqueueCount()
+ {
+ return 0;
+ }
+
public int getBindingCountHigh()
{
return 0;
@@ -219,12 +234,27 @@ public class MockAMQQueue implements AMQQueue
public void registerSubscription(Subscription subscription, boolean exclusive) throws AMQException
{
-
+
}
public void unregisterSubscription(Subscription subscription) throws AMQException
{
-
+
+ }
+
+ public Collection<Subscription> getConsumers()
+ {
+ return Collections.emptyList();
+ }
+
+ public void addSubscriptionRegistrationListener(final SubscriptionRegistrationListener listener)
+ {
+
+ }
+
+ public void removeSubscriptionRegistrationListener(final SubscriptionRegistrationListener listener)
+ {
+
}
public int getConsumerCount()
@@ -283,7 +313,7 @@ public class MockAMQQueue implements AMQQueue
}
public int delete() throws AMQException
- {
+ {
_deleted = true;
return getMessageCount();
}
@@ -356,21 +386,6 @@ public class MockAMQQueue implements AMQQueue
return null;
}
- public void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName)
- {
-
- }
-
- public void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName)
- {
-
- }
-
- public void removeMessagesFromQueue(long fromMessageId, long toMessageId)
- {
-
- }
-
public long getMaximumMessageSize()
{
return 0;
@@ -378,7 +393,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageSize(long value)
{
-
+
}
public long getMaximumMessageCount()
@@ -388,7 +403,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageCount(long value)
{
-
+
}
public long getMaximumQueueDepth()
@@ -398,7 +413,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumQueueDepth(long value)
{
-
+
}
public long getMaximumMessageAge()
@@ -408,7 +423,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageAge(long maximumMessageAge)
{
-
+
}
public long getMinimumAlertRepeatGap()
@@ -418,7 +433,7 @@ public class MockAMQQueue implements AMQQueue
public void deleteMessageFromTop()
{
-
+
}
public long clearQueue()
@@ -429,7 +444,7 @@ public class MockAMQQueue implements AMQQueue
public void checkMessageStatus() throws AMQException
{
-
+
}
public Set<NotificationCheck> getNotificationChecks()
@@ -439,22 +454,22 @@ public class MockAMQQueue implements AMQQueue
public void flushSubscription(Subscription sub) throws AMQException
{
-
+
}
public void deliverAsync(Subscription sub)
{
-
+
}
public void deliverAsync()
{
-
+
}
public void stop()
{
-
+
}
public boolean isExclusive()
@@ -469,7 +484,7 @@ public class MockAMQQueue implements AMQQueue
public void setAlternateExchange(Exchange exchange)
{
-
+
}
public Map<String, Object> getArguments()
@@ -481,11 +496,6 @@ public class MockAMQQueue implements AMQQueue
{
}
- public ManagedObject getManagedObject()
- {
- return null;
- }
-
public int compareTo(AMQQueue o)
{
return 0;
@@ -503,7 +513,7 @@ public class MockAMQQueue implements AMQQueue
public void setCapacity(long capacity)
{
-
+
}
public long getFlowResumeCapacity()
@@ -513,7 +523,7 @@ public class MockAMQQueue implements AMQQueue
public void setFlowResumeCapacity(long flowResumeCapacity)
{
-
+
}
public void configure(ConfigurationPlugin config)
@@ -546,12 +556,6 @@ public class MockAMQQueue implements AMQQueue
_exclusiveOwner = exclusiveOwner;
}
-
- public String getResourceName()
- {
- return _name.toString();
- }
-
public boolean isOverfull()
{
return false;
@@ -582,7 +586,7 @@ public class MockAMQQueue implements AMQQueue
return 0;
}
- public void decrementUnackedMsgCount()
+ public void decrementUnackedMsgCount(QueueEntry queueEntry)
{
}
@@ -599,7 +603,6 @@ public class MockAMQQueue implements AMQQueue
public void setExclusive(boolean exclusive)
{
-
}
public int getMaximumDeliveryCount()
@@ -611,11 +614,23 @@ public class MockAMQQueue implements AMQQueue
{
}
- public void setAlternateExchange(String exchangeName)
+ public void visit(final QueueEntryVisitor visitor)
+ {
+ }
+
+ @Override
+ public void setNotificationListener(NotificationListener listener)
{
}
- public void visit(final Visitor visitor)
+ @Override
+ public void setDescription(String description)
{
}
+
+ @Override
+ public String getDescription()
+ {
+ return null;
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java
new file mode 100644
index 0000000000..df2de7f0e0
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.queue;
+
+import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import static org.apache.qpid.server.queue.NotificationCheck.MESSAGE_AGE_ALERT;
+import static org.apache.qpid.server.queue.NotificationCheck.MESSAGE_COUNT_ALERT;
+import static org.apache.qpid.server.queue.NotificationCheck.MESSAGE_SIZE_ALERT;
+import static org.apache.qpid.server.queue.NotificationCheck.QUEUE_DEPTH_ALERT;
+
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.queue.AMQQueue.NotificationListener;
+
+public class NotificationCheckTest extends TestCase
+{
+
+ private ServerMessage<?> _message = mock(ServerMessage.class);
+ private AMQQueue _queue = mock(AMQQueue.class);
+ private NotificationListener _listener = mock(NotificationListener.class);
+
+ public void testMessageCountAlertFires() throws Exception
+ {
+ when(_queue.getMaximumMessageCount()).thenReturn(1000l);
+ when(_queue.getMessageCount()).thenReturn(999, 1000, 1001);
+
+ MESSAGE_COUNT_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verifyZeroInteractions(_listener);
+
+ MESSAGE_COUNT_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(MESSAGE_COUNT_ALERT), eq(_queue), eq("1000: Maximum count on queue threshold (1000) breached."));
+
+ MESSAGE_COUNT_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(MESSAGE_COUNT_ALERT), eq(_queue), eq("1001: Maximum count on queue threshold (1000) breached."));
+ }
+
+ public void testMessageSizeAlertFires() throws Exception
+ {
+ when(_queue.getMaximumMessageSize()).thenReturn(1024l);
+ when(_message.getSize()).thenReturn(1023l, 1024l, 1025l);
+
+ MESSAGE_SIZE_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verifyZeroInteractions(_listener);
+
+ MESSAGE_SIZE_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(MESSAGE_SIZE_ALERT), eq(_queue), contains("1024b : Maximum message size threshold (1024) breached."));
+
+ MESSAGE_SIZE_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(MESSAGE_SIZE_ALERT), eq(_queue), contains("1025b : Maximum message size threshold (1024) breached."));
+ }
+
+ public void testMessageAgeAlertFires() throws Exception
+ {
+ long now = System.currentTimeMillis();
+ when(_queue.getMaximumMessageAge()).thenReturn(1000l);
+ when(_queue.getOldestMessageArrivalTime()).thenReturn(now, now - 15000);
+
+ MESSAGE_AGE_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verifyZeroInteractions(_listener);
+
+ MESSAGE_AGE_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ // Uses contains as first part of message is nondeterministic
+ verify(_listener).notifyClients(eq(MESSAGE_AGE_ALERT), eq(_queue), contains("s : Maximum age on queue threshold (1s) breached."));
+ }
+
+ public void testQueueDepthAlertFires() throws Exception
+ {
+ when(_queue.getMaximumQueueDepth()).thenReturn(1024l);
+ when(_queue.getQueueDepth()).thenReturn(1023l, 1024l, 2048l);
+
+ QUEUE_DEPTH_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verifyZeroInteractions(_listener);
+
+ QUEUE_DEPTH_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(QUEUE_DEPTH_ALERT), eq(_queue), eq("1Kb : Maximum queue depth threshold (1Kb) breached."));
+
+ QUEUE_DEPTH_ALERT.notifyIfNecessary(_message, _queue, _listener);
+ verify(_listener).notifyClients(eq(QUEUE_DEPTH_ALERT), eq(_queue), eq("2Kb : Maximum queue depth threshold (1Kb) breached."));
+ }
+}
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 a8fad96063..d2fe529856 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
@@ -21,6 +21,13 @@
package org.apache.qpid.server.queue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
+
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.AMQException;
@@ -79,7 +86,6 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void setExchange(AMQShortString exchange)
{
- //To change body of implemented methods use File | Settings | File Templates.
}
public boolean isImmediate()
@@ -839,120 +845,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
}
- /**
- * Tests that dequeued message is not copied as part of invocation of
- * {@link SimpleAMQQueue#copyMessagesToAnotherQueue(long, long, String)}
- */
- public void testCopyMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
- // put test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // copy messages into another queue
- _queue.copyMessagesToAnotherQueue(0, messageNumber, anotherQueueName);
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not moved as part of invocation of
- * {@link SimpleAMQQueue#moveMessagesToAnotherQueue(long, long, String)}
- */
- public void testMovedMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // move messages into another queue
- _queue.moveMessagesToAnotherQueue(0, messageNumber, anotherQueueName);
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that messages in given range including dequeued one are deleted
- * from the queue on invocation of
- * {@link SimpleAMQQueue#removeMessagesFromQueue(long, long)}
- */
- public void testRemoveMessagesFromQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // remove messages
- _queue.removeMessagesFromQueue(0, messageNumber);
-
- // get queue entries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
- assertEquals("Queue should be empty", 0, entries.size());
- }
/**
* Tests that dequeued message on the top is not accounted and next message
@@ -1096,7 +989,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
/**
* Tests that entry in dequeued state are not enqueued and not delivered to subscription
*/
- public void testEqueueDequeuedEntry()
+ public void testEnqueueDequeuedEntry()
{
// create a queue where each even entry is considered a dequeued
SimpleAMQQueue queue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), new AMQShortString("test"), false,
@@ -1231,6 +1124,39 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
assertEquals("Unexpected active consumer count", 1, queue.getActiveConsumerCount());
}
+ public void testNotificationFiredOnEnqueue() throws Exception
+ {
+ AMQQueue.NotificationListener listener = mock(AMQQueue.NotificationListener.class);
+
+ _queue.setNotificationListener(listener);
+ _queue.setMaximumMessageCount(2);
+
+ _queue.enqueue(createMessage(new Long(24)));
+ verifyZeroInteractions(listener);
+
+ _queue.enqueue(createMessage(new Long(25)));
+
+ verify(listener, atLeastOnce()).notifyClients(eq(NotificationCheck.MESSAGE_COUNT_ALERT), eq(_queue), contains("Maximum count on queue threshold"));
+ }
+
+ public void testNotificationFiredAsync() throws Exception
+ {
+ AMQQueue.NotificationListener listener = mock(AMQQueue.NotificationListener.class);
+
+ _queue.enqueue(createMessage(new Long(24)));
+ _queue.enqueue(createMessage(new Long(25)));
+ _queue.enqueue(createMessage(new Long(26)));
+
+ _queue.setNotificationListener(listener);
+ _queue.setMaximumMessageCount(2);
+
+ verifyZeroInteractions(listener);
+
+ _queue.checkMessageStatus();
+
+ verify(listener, atLeastOnce()).notifyClients(eq(NotificationCheck.MESSAGE_COUNT_ALERT), eq(_queue), contains("Maximum count on queue threshold"));
+ }
+
/**
* A helper method to create a queue with given name
*
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
index f6675e917e..c0c55de92a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
@@ -32,6 +32,7 @@ import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import java.net.InetSocketAddress;
import java.util.Collections;
/**
@@ -47,7 +48,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
protected void setUp() throws Exception
{
- _rmipa = new RMIPasswordAuthenticator();
+ _rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(5672));
_credentials = new String[] {USERNAME, PASSWORD};
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java
index 48e631a0f4..8ab32d9710 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java
@@ -1,3 +1,23 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.store;
import static org.mockito.Matchers.any;
@@ -78,7 +98,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_exchangeId = UUIDGenerator.generateUUID();
_storeName = getName();
- _storePath = TMP_FOLDER + "/" + _storeName;
+ _storePath = TMP_FOLDER + File.separator + _storeName;
FileUtils.delete(new File(_storePath), true);
setTestSystemProperty("QPID_WORK", TMP_FOLDER);
_configuration = mock(Configuration.class);
@@ -172,7 +192,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_store.createQueue(queue);
reopenStore();
- verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", true, null);
+ verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", true, null, null);
}
public void testCreateQueueAMQQueueFieldTable() throws Exception
@@ -186,10 +206,29 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_store.createQueue(queue, arguments);
reopenStore();
- verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", true, arguments);
+ verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", true, arguments, null);
}
- public void testUpdateQueue() throws Exception
+ public void testCreateQueueAMQQueueWithAlternateExchange() throws Exception
+ {
+ Exchange alternateExchange = createTestAlternateExchange();
+
+ AMQQueue queue = createTestQueue(getName(), getName() + "Owner", true, alternateExchange);
+ _store.createQueue(queue);
+
+ reopenStore();
+ verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", true, null, alternateExchange.getId());
+ }
+
+ private Exchange createTestAlternateExchange()
+ {
+ UUID exchUuid = UUID.randomUUID();
+ Exchange alternateExchange = mock(Exchange.class);
+ when(alternateExchange.getId()).thenReturn(exchUuid);
+ return alternateExchange;
+ }
+
+ public void testUpdateQueueExclusivity() throws Exception
{
// create queue
AMQQueue queue = createTestQueue(getName(), getName() + "Owner", true);
@@ -204,7 +243,26 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_store.updateQueue(queue);
reopenStore();
- verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", false, arguments);
+ verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", false, arguments, null);
+ }
+
+ public void testUpdateQueueAlternateExchange() throws Exception
+ {
+ // create queue
+ AMQQueue queue = createTestQueue(getName(), getName() + "Owner", true);
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put("x-qpid-dlq-enabled", Boolean.TRUE);
+ attributes.put("x-qpid-maximum-delivery-count", new Integer(10));
+ FieldTable arguments = FieldTable.convertToFieldTable(attributes);
+ _store.createQueue(queue, arguments);
+
+ // update the queue to have exclusive=false
+ Exchange alternateExchange = createTestAlternateExchange();
+ queue = createTestQueue(getName(), getName() + "Owner", false, alternateExchange);
+ _store.updateQueue(queue);
+
+ reopenStore();
+ verify(_queueRecoveryHandler).queue(_queueId, getName(), getName() + "Owner", false, arguments, alternateExchange.getId());
}
public void testRemoveQueue() throws Exception
@@ -221,17 +279,23 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_store.removeQueue(queue);
reopenStore();
verify(_queueRecoveryHandler, never()).queue(any(UUID.class), anyString(), anyString(), anyBoolean(),
- any(FieldTable.class));
+ any(FieldTable.class), any(UUID.class));
}
private AMQQueue createTestQueue(String queueName, String queueOwner, boolean exclusive) throws AMQStoreException
{
+ return createTestQueue(queueName, queueOwner, exclusive, null);
+ }
+
+ private AMQQueue createTestQueue(String queueName, String queueOwner, boolean exclusive, Exchange alternateExchange) throws AMQStoreException
+ {
AMQQueue queue = mock(AMQQueue.class);
when(queue.getName()).thenReturn(queueName);
when(queue.getNameShortString()).thenReturn(AMQShortString.valueOf(queueName));
when(queue.getOwner()).thenReturn(AMQShortString.valueOf(queueOwner));
when(queue.isExclusive()).thenReturn(exclusive);
when(queue.getId()).thenReturn(_queueId);
+ when(queue.getAlternateExchange()).thenReturn(alternateExchange);
return queue;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
index 64048d294b..93f3701c85 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
@@ -99,7 +99,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
{
super.setUp();
- String storePath = System.getProperty("QPID_WORK") + "/" + getName();
+ String storePath = System.getProperty("QPID_WORK") + File.separator + getName();
_config = new PropertiesConfiguration();
_config.addProperty("store.class", getTestProfileMessageStoreClassName());
@@ -267,15 +267,9 @@ public class MessageStoreTest extends InternalBrokerBaseCase
//Validate normally expected properties of Queues/Topics
validateDurableQueueProperties();
- //Update the durable exclusive queue's exclusivity and verify it is persisted and recovered correctly
+ //Update the durable exclusive queue's exclusivity
setQueueExclusivity(false);
validateQueueExclusivityProperty(false);
-
- //Reload the Virtualhost to recover the queues again
- reloadVirtualHost();
-
- //verify the change was persisted and recovered correctly
- validateQueueExclusivityProperty(false);
}
/**
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
index c6ef35d255..24e8b591e0 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
@@ -147,6 +147,12 @@ public class OperationalLoggingListenerTest extends TestCase
{
_eventManager.addEventListener(eventListener, events);
}
+
+ @Override
+ public String getStoreType()
+ {
+ return "TEST";
+ }
}
private static class TestActor implements LogActor
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
index 5ba9c0c015..0aa0569b07 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
@@ -1,5 +1,3 @@
-package org.apache.qpid.server.subscription;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -21,16 +19,24 @@ package org.apache.qpid.server.subscription;
*
*/
+package org.apache.qpid.server.subscription;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.queue.QueueEntry.SubscriptionAcquiredState;
+import org.apache.qpid.server.stats.StatisticsCounter;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -76,19 +82,9 @@ public class MockSubscription implements Subscription
_state = State.CLOSED;
}
- public boolean filtersMessages()
- {
- return false;
- }
-
- public AMQChannel getChannel()
- {
- return null;
- }
-
- public AMQShortString getConsumerTag()
+ public String getConsumerName()
{
- return tag;
+ return tag == null ? null : tag.asString();
}
public long getSubscriptionID()
@@ -121,11 +117,36 @@ public class MockSubscription implements Subscription
return false;
}
+ public long getBytesOut()
+ {
+ return 0; // TODO - Implement
+ }
+
+ public long getMessagesOut()
+ {
+ return 0; // TODO - Implement
+ }
+
+ public long getUnacknowledgedBytes()
+ {
+ return 0; // TODO - Implement
+ }
+
+ public long getUnacknowledgedMessages()
+ {
+ return 0; // TODO - Implement
+ }
+
public AMQQueue getQueue()
{
return queue;
}
+ public AMQSessionModel getSessionModel()
+ {
+ return new MockSessionModel();
+ }
+
public boolean trySendLock()
{
return _stateChangeLock.tryLock();
@@ -154,11 +175,6 @@ public class MockSubscription implements Subscription
return _isActive ;
}
- public void confirmAutoClose()
- {
-
- }
-
public void set(String key, Object value)
{
}
@@ -173,11 +189,6 @@ public class MockSubscription implements Subscription
return false;
}
- public boolean isBrowser()
- {
- return false;
- }
-
public boolean isClosed()
{
return _closed;
@@ -207,10 +218,6 @@ public class MockSubscription implements Subscription
_stateChangeLock.unlock();
}
- public void resend(QueueEntry entry) throws AMQException
- {
- }
-
public void onDequeue(QueueEntry queueEntry)
{
}
@@ -232,7 +239,6 @@ public class MockSubscription implements Subscription
messages.add(entry);
}
- @Override
public void flushBatched()
{
@@ -249,7 +255,7 @@ public class MockSubscription implements Subscription
}
public void setNoLocal(boolean noLocal)
- {
+ {
}
public void setStateListener(StateListener listener)
@@ -285,4 +291,259 @@ public class MockSubscription implements Subscription
{
_isActive = isActive;
}
+
+ private static class MockSessionModel implements AMQSessionModel
+ {
+
+ @Override
+ public int compareTo(AMQSessionModel o)
+ {
+ return 0;
+ }
+
+ @Override
+ public UUID getId()
+ {
+ return null;
+ }
+
+ @Override
+ public AMQConnectionModel getConnectionModel()
+ {
+ return new MockConnectionModel();
+ }
+
+ @Override
+ public String getClientID()
+ {
+ return null;
+ }
+
+ @Override
+ public void close() throws AMQException
+ {
+ }
+
+ @Override
+ public LogSubject getLogSubject()
+ {
+ return null;
+ }
+
+ @Override
+ public void checkTransactionStatus(long openWarn, long openClose,
+ long idleWarn, long idleClose) throws AMQException
+ {
+ }
+
+ @Override
+ public void block(AMQQueue queue)
+ {
+ }
+
+ @Override
+ public void unblock(AMQQueue queue)
+ {
+ }
+
+ @Override
+ public void block()
+ {
+ }
+
+ @Override
+ public void unblock()
+ {
+ }
+
+ @Override
+ public boolean getBlocking()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean onSameConnection(InboundMessage inbound)
+ {
+ return false;
+ }
+
+ @Override
+ public int getUnacknowledgedMessageCount()
+ {
+ return 0;
+ }
+
+ @Override
+ public Long getTxnCount()
+ {
+ return null;
+ }
+
+ @Override
+ public Long getTxnStart()
+ {
+ return null;
+ }
+
+ @Override
+ public Long getTxnCommits()
+ {
+ return null;
+ }
+
+ @Override
+ public Long getTxnRejects()
+ {
+ return null;
+ }
+
+ @Override
+ public int getChannelId()
+ {
+ return 0;
+ }
+ }
+
+ private static class MockConnectionModel implements AMQConnectionModel
+ {
+ @Override
+ public void initialiseStatistics()
+ {
+ }
+
+ @Override
+ public void registerMessageReceived(long messageSize, long timestamp)
+ {
+ }
+
+ @Override
+ public void registerMessageDelivered(long messageSize)
+ {
+ }
+
+ @Override
+ public StatisticsCounter getMessageDeliveryStatistics()
+ {
+ return null;
+ }
+
+ @Override
+ public StatisticsCounter getMessageReceiptStatistics()
+ {
+ return null;
+ }
+
+ @Override
+ public StatisticsCounter getDataDeliveryStatistics()
+ {
+ return null;
+ }
+
+ @Override
+ public StatisticsCounter getDataReceiptStatistics()
+ {
+ return null;
+ }
+
+ @Override
+ public void resetStatistics()
+ {
+
+ }
+
+ @Override
+ public UUID getId()
+ {
+ return null;
+ }
+
+ @Override
+ public void close(AMQConstant cause, String message)
+ throws AMQException
+ {
+ }
+
+ @Override
+ public void closeSession(AMQSessionModel session, AMQConstant cause,
+ String message) throws AMQException
+ {
+ }
+
+ @Override
+ public long getConnectionId()
+ {
+ return 0;
+ }
+
+ @Override
+ public List<AMQSessionModel> getSessionModels()
+ {
+ return null;
+ }
+
+ @Override
+ public void block()
+ {
+ }
+
+ @Override
+ public void unblock()
+ {
+ }
+
+ @Override
+ public LogSubject getLogSubject()
+ {
+ return null;
+ }
+
+ @Override
+ public String getUserName()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isSessionNameUnique(byte[] name)
+ {
+ return false;
+ }
+
+ @Override
+ public String getRemoteAddressString()
+ {
+ return "remoteAddress:1234";
+ }
+
+ @Override
+ public String getClientId()
+ {
+ return null;
+ }
+
+ @Override
+ public String getClientVersion()
+ {
+ return null;
+ }
+
+ @Override
+ public String getPrincipalAsString()
+ {
+ return null;
+ }
+
+ @Override
+ public long getSessionCountLimit()
+ {
+ return 0;
+ }
+
+ @Override
+ public long getLastIoTime()
+ {
+ return 0;
+ }
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java
deleted file mode 100644
index b0b81355ac..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.transport;
-
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.server.configuration.MockConnectionConfig;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.Binary;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.Session;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-
-public class ServerConnectionMBeanTest extends InternalBrokerBaseCase
-{
- private ServerConnection _serverConnection;
- private ServerSessionMock _serverSession;
- private ServerConnectionMBean _mbean;
- private List<Session> _sessions = new ArrayList<Session>();
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- final VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- _serverConnection = new ServerConnection(1)
- {
- protected Collection<Session> getChannels()
- {
- return _sessions;
- }
- public Session getSession(int channelId)
- {
- for(Session session : _sessions)
- {
- if (session.getChannel() == channelId)
- {
- return session;
- }
- }
- return null;
- }
- @Override
- public AtomicLong getLastIoTime()
- {
- return new AtomicLong(1);
- }
- };
- final MockConnectionConfig config = new MockConnectionConfig(UUID.randomUUID(), null, null,
- false, 1, vhost, "address", Boolean.TRUE, Boolean.TRUE, Boolean.TRUE,
- "authid", "remoteProcessName", new Integer(1967), new Integer(1970), vhost.getConfigStore(), Boolean.FALSE);
- _serverConnection.setConnectionConfig(config);
- _serverConnection.setVirtualHost(vhost);
- _serverConnection.setConnectionDelegate(new ServerConnectionDelegate(getRegistry(), "", getRegistry().getAuthenticationManager(new InetSocketAddress(5672))));
- _serverSession = new ServerSessionMock(_serverConnection, 1);
- _mbean = (ServerConnectionMBean) _serverConnection.getManagedObject();
- }
-
- public void testChannels() throws Exception
- {
- // check the channel count is correct
- TabularData tabularData = _mbean.channels();
-
- int channelCount = tabularData.size();
- assertEquals("Unexpected number of channels",1,channelCount);
- _sessions.add(new ServerSession(_serverConnection, new ServerSessionDelegate(),
- new Binary(getName().getBytes()), 2 , _serverConnection.getConfig()));
-
- channelCount = _mbean.channels().size();
- assertEquals("Unexpected number of channels",2,channelCount);
-
- final CompositeData chanresult = tabularData.get(new Integer[]{1});
- assertNotNull(chanresult);
- assertEquals("Unexpected channel id", new Integer(1),(Integer)chanresult.get(ManagedConnection.CHAN_ID));
- assertNull("Unexpected default queue", chanresult.get(ManagedConnection.DEFAULT_QUEUE));
- assertFalse("Unexpected transactional flag", (Boolean)chanresult.get(ManagedConnection.TRANSACTIONAL));
- assertFalse("Flow should have been blocked", (Boolean)chanresult.get(ManagedConnection.FLOW_BLOCKED));
- assertEquals("Unexpected unack'd count", new Integer(1967), (Integer)chanresult.get(ManagedConnection.UNACKED_COUNT));
- }
-
- public void testMaxChannels() throws Exception
- {
- _serverConnection.getConnectionDelegate().setChannelMax(10001);
- assertEquals("Max channels not got correctly", new Long(10001), _mbean.getMaximumNumberOfChannels());
- }
-
- public void testRollback() throws Exception
- {
- _mbean.rollbackTransactions(1);
- assertFalse("Rollback performed despite not being transacted", _serverSession.isRolledback());
-
- _serverSession.setTransactional(true);
- _mbean.rollbackTransactions(1);
- assertTrue("Rollback not performed", _serverSession.isRolledback());
-
- try
- {
- _mbean.rollbackTransactions(2);
- fail("Exception expected");
- }
- catch (JMException jme)
- {
- //pass
- }
- }
-
- public void testCommit() throws Exception
- {
- _mbean.commitTransactions(1);
- assertFalse("Commit performed despite not being transacted", _serverSession.isCommitted());
-
- _serverSession.setTransactional(true);
- _mbean.commitTransactions(1);
- assertTrue("Commit not performed", _serverSession.isCommitted());
-
- try
- {
- _mbean.commitTransactions(2);
- fail("Exception expected");
- }
- catch (JMException jme)
- {
- //pass
- }
- }
-
- public void testGetName()
- {
- assertEquals("Unexpected Object Instance Name", "\"address\"", _mbean.getObjectInstanceName());
- }
-
- public void testEnableStatistics()
- {
- assertFalse("Unexpected statistics enable flag", _mbean.isStatisticsEnabled());
- _mbean.setStatisticsEnabled(true);
- assertTrue("Unexpected statistics enable flag", _mbean.isStatisticsEnabled());
- }
-
- public void testLastIOTime()
- {
- assertEquals("Unexpected last IO time", new Date(1), _mbean.getLastIoTime());
- }
-
- private class ServerSessionMock extends ServerSession
- {
- private int _channelId = 0;
- private boolean _committed = false;
- private boolean _rolledback = false;
- private boolean _transacted = false;
-
- ServerSessionMock(Connection connection, int channelId)
- {
- super(connection, new ServerSessionDelegate(), new Binary(String.valueOf(channelId).getBytes()), 1 , _serverConnection.getConfig());
- _channelId = channelId;
- _sessions.add(this);
- }
-
- public int getChannel()
- {
- return _channelId;
- }
-
- @Override
- public void commit()
- {
- _committed = true;
- }
-
- @Override
- public void rollback()
- {
- _rolledback = true;
- }
-
- public boolean isCommitted()
- {
- return _committed;
- }
-
- public boolean isRolledback()
- {
- return _rolledback;
- }
-
- @Override
- public int getUnacknowledgedMessageCount()
- {
- return 1967;
- }
-
- public boolean isTransactional()
- {
- return _transacted;
- }
-
- public void setTransactional(boolean transacted)
- {
- _transacted = transacted;
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
index af49238998..0221f3d509 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
@@ -124,6 +124,12 @@ class MockStoreTransaction implements Transaction
storeTransaction.setState(TransactionState.STARTED);
return storeTransaction;
}
+
+ @Override
+ public String getStoreType()
+ {
+ return "TEST";
+ }
};
}
} \ No newline at end of file
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index 9bd69e3889..a64ab620ab 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -21,6 +21,8 @@
package org.apache.qpid.server.util;
import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.Map;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.configuration.ServerConfiguration;
@@ -101,6 +103,17 @@ public class TestApplicationRegistry extends ApplicationRegistry
{
return pdam;
}
+
+ @Override
+ public Map<String, AuthenticationManager> getAvailableAuthenticationManagers()
+ {
+ return Collections.singletonMap(pdam.getClass().getName(), pdam);
+ }
+
+ @Override
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ }
};
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
index 58c7625ad6..df31845798 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
@@ -32,7 +32,6 @@ import org.apache.qpid.server.connection.IConnectionRegistry;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.federation.BrokerLink;
-import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
@@ -141,11 +140,6 @@ public class MockVirtualHost implements VirtualHost
return 0;
}
- public ManagedObject getManagedObject()
- {
- return null;
- }
-
public MessageStore getMessageStore()
{
return null;
@@ -257,11 +251,6 @@ public class MockVirtualHost implements VirtualHost
}
- public boolean isStatisticsEnabled()
- {
- return false;
- }
-
public void registerMessageDelivered(long messageSize)
{
@@ -277,11 +266,6 @@ public class MockVirtualHost implements VirtualHost
}
- public void setStatisticsEnabled(boolean enabled)
- {
-
- }
-
public State getState()
{
return State.ACTIVE;