summaryrefslogtreecommitdiff
path: root/java/broker/src
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2012-08-03 12:13:32 +0000
committerKim van der Riet <kpvdr@apache.org>2012-08-03 12:13:32 +0000
commitd43d1912b376322e27fdcda551a73f9ff5487972 (patch)
treece493e10baa95f44be8beb5778ce51783463196d /java/broker/src
parent04877fec0c6346edec67072d7f2d247740cf2af5 (diff)
downloadqpid-python-d43d1912b376322e27fdcda551a73f9ff5487972.tar.gz
QPID-3858: Updated branch - merged from trunk r.1368650
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1368910 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker/src')
-rwxr-xr-xjava/broker/src/main/java/broker.bnd2
-rw-r--r--java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java320
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java410
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java177
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Broker.java144
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Main.java58
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java215
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java215
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java62
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java85
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java21
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java158
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java40
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherResult.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java40
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java7
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager_0_10.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java145
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java210
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java579
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacadeException.java (renamed from java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java)27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java822
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java105
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java90
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java192
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java491
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java399
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java367
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/Managable.java34
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java59
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java49
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java58
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java17
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java199
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java (renamed from java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStoreFactory.java)22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java55
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Broker.java80
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Connection.java107
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Event.java (renamed from java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java)10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/EventType.java60
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Model.java97
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java46
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Port.java91
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Queue.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/QueueNotificationListener.java (renamed from java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java)5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/QueueType.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Session.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Transport.java27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java58
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/User.java59
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java152
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java37
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java283
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java488
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java232
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java494
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java313
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java225
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java437
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java273
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java46
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java320
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java726
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java240
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java892
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java143
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java91
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java31
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java246
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java344
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java30
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java2
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java11
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java21
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java196
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java165
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java45
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java99
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java664
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java147
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java50
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java39
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java496
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java322
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java48
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java186
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java192
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java203
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java177
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java59
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java213
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java389
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java12
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/Event.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/HAMessageStore.java (renamed from java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java)20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/State.java27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java326
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java4
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java2
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java95
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java64
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java49
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java183
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java60
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java263
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java152
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java36
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java11
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java157
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java4
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java11
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java37
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java295
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java31
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java1
-rw-r--r--java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java395
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java195
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java27
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/MainTest.java19
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java101
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java10
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java43
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java186
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java3
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java235
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java55
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java45
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java245
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.log4j.xml41
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java428
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/BrokerMessagesTest.java5
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java153
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java213
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java4
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java146
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java348
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java59
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java553
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java3
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/ConflationQueueListTest.java211
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java119
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java106
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java198
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java7
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java109
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java304
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java120
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java42
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java109
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java178
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java19
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java44
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java62
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java62
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java325
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java230
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java140
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java22
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java43
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java46
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java27
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java4
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java12
267 files changed, 15524 insertions, 10804 deletions
diff --git a/java/broker/src/main/java/broker.bnd b/java/broker/src/main/java/broker.bnd
index fa433848a6..4e799a1609 100755
--- a/java/broker/src/main/java/broker.bnd
+++ b/java/broker/src/main/java/broker.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.17.0
+ver: 0.19.0
Bundle-SymbolicName: qpid-broker
Bundle-Version: ${ver}
diff --git a/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java b/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java
deleted file mode 100644
index dca62f34b4..0000000000
--- a/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java
+++ /dev/null
@@ -1,320 +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 org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-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;
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Substitute for the Log4J XMLWatchdog (as used by DOMConfigurator.configureAndWatch)
- *
- * Extends the default behaviour with a strict parser check on the XML file before allowing the reconfiguration to proceed,
- * ensuring that any parser error or warning prevents initiation of a configuration update by Log4J, which aborts mid-update
- * upon fatal errors from the parser and proceeds in the event of 'regular' parser errors and warnings, in all cases allowing
- * startup to proceed with whatever half-baked configuration then exists.
- */
-public class QpidLog4JConfigurator
-{
- //lock to protect access to the configuration file
- //shared with LoggingManagementMBean
- public static final ReentrantLock LOCK = new ReentrantLock();
- private static Logger _logger;
- private static DOMConfigurator domConfig = new DOMConfigurator();
-
- private QpidLog4JConfigurator()
- {
- //no instances
- }
-
- public static void configure(String filename) throws IOException, ParserConfigurationException,
- SAXException, IllegalLoggerLevelException
- {
- try
- {
- LOCK.lock();
-
- parseXMLConfigFile(filename);
- checkLoggerLevels(filename);
-
- DOMConfigurator.configure(filename);
-
- if(_logger == null)
- {
- _logger = Logger.getLogger(QpidLog4JConfigurator.class);
- }
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public static void configureAndWatch(String filename, long delay) throws IOException, ParserConfigurationException,
- SAXException, IllegalLoggerLevelException
- {
- parseXMLConfigFile(filename);
- checkLoggerLevels(filename);
-
- QpidLog4JXMLWatchdog watchdog = new QpidLog4JXMLWatchdog(filename);
- watchdog.setDelay(delay);
- watchdog.start();
- }
-
- private static void parseXMLConfigFile(String fileName) throws IOException, SAXException,
- ParserConfigurationException
- {
- try
- {
- LOCK.lock();
-
- //check file was specified, exists, and is readable
- if(fileName == null)
- {
- throw new IOException("Provided log4j XML configuration filename was null");
- }
-
- File configFile = new File(fileName);
-
- if (!configFile.exists())
- {
- throw new IOException("The log4j XML configuration file does not exist: " + fileName);
- }
- else if (!configFile.canRead())
- {
- throw new IOException("The log4j XML configuration file is not readable: " + fileName);
- }
-
- //parse it
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder;
-
- ErrorHandler errHandler = new QpidLog4JSaxErrorHandler();
-
- docFactory.setValidating(true);
- docBuilder = docFactory.newDocumentBuilder();
- docBuilder.setErrorHandler(errHandler);
- docBuilder.setEntityResolver(new Log4jEntityResolver());
- docBuilder.parse(fileName);
- }
- finally
- {
- LOCK.unlock();
- }
- }
-
- public static class QpidLog4JSaxErrorHandler implements ErrorHandler
- {
- public void error(SAXParseException e) throws SAXException
- {
- if(_logger != null)
- {
- _logger.warn(constructMessage("Error parsing XML file", e));
- }
- else
- {
- System.err.println(constructMessage("Error parsing XML file", e));
- }
- }
-
- public void fatalError(SAXParseException e) throws SAXException
- {
- throw new SAXException(constructMessage("Fatal error parsing XML file", e));
- }
-
- public void warning(SAXParseException e) throws SAXException
- {
- if(_logger != null)
- {
- _logger.warn(constructMessage("Warning parsing XML file", e));
- }
- else
- {
- System.err.println(constructMessage("Warning parsing XML file", e));
- }
- }
-
- private static String constructMessage(final String msg, final SAXParseException ex)
- {
- return msg + ": Line " + ex.getLineNumber()+" column " +ex.getColumnNumber() + ": " + ex.getMessage();
- }
- }
-
- private static class QpidLog4JXMLWatchdog extends XMLWatchdog
- {
- public QpidLog4JXMLWatchdog(String filename)
- {
- super(filename);
- }
-
- public void doOnChange()
- {
- try
- {
- LOCK.lock();
-
- try
- {
- parseXMLConfigFile(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("Parsing the log4j XML configuration file generated errors/warnings. " +
- "The new configuration was not applied. Correct the issues to prompt " +
- "another update attempt: " + e.getMessage());
- }
- 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();
-
- //a configuration has now been applied, enable logging for future attempts
- if(_logger == null)
- {
- _logger = Logger.getLogger(QpidLog4JConfigurator.class);
- }
-
- _logger.info("Applied log4j configuration from: " + filename);
- }
- finally
- {
- LOCK.unlock();
- }
-
- }
- }
-
- 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))
- {
- //the string "null" signals to inherit from a parent logger
- return;
- }
-
- Level level = Level.toLevel(levelString);
-
- //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result.
- if (level.equals(Level.DEBUG) && !(levelString.equalsIgnoreCase("debug")))
- {
- //received DEBUG but we did not ask for it, the Level request failed.
- throw new IllegalLoggerLevelException("Level '" + levelString + "' specified for Logger '" + loggerName + "' is invalid");
- }
- }
-
- public static class IllegalLoggerLevelException extends Exception
- {
- private static final long serialVersionUID = 1L;
-
- public IllegalLoggerLevelException(String msg)
- {
- super(msg);
- }
- }
-}
-
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
index 034a4ae53c..27ab580642 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
@@ -70,6 +70,7 @@ public class ManagementExchange implements Exchange, QMFService.Listener
private final Set<Binding> _bindingSet = new CopyOnWriteArraySet<Binding>();
private UUID _id;
+ private UUID _qmfId;
private static final String AGENT_BANK = "0";
private int _bindingCountHigh;
@@ -84,7 +85,7 @@ public class ManagementExchange implements Exchange, QMFService.Listener
private class ManagementQueue implements BaseQueue
{
- private final UUID QUEUE_ID = UUIDGenerator.generateUUID();
+ private final UUID QUEUE_ID = UUIDGenerator.generateRandomUUID();
private final String NAME_AS_STRING = "##__mgmt_pseudo_queue__##" + QUEUE_ID.toString();
private final AMQShortString NAME_AS_SHORT_STRING = new AMQShortString(NAME_AS_STRING);
@@ -196,6 +197,7 @@ public class ManagementExchange implements Exchange, QMFService.Listener
_virtualHost = host;
_id = id;
_virtualHost.scheduleHouseKeepingTask(_virtualHost.getBroker().getManagementPublishInterval(), new UpdateTask(_virtualHost));
+ _qmfId = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
getQMFService().addListener(this);
}
@@ -205,6 +207,12 @@ public class ManagementExchange implements Exchange, QMFService.Listener
return _id;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return _qmfId;
+ }
+
public ExchangeConfigType getConfigType()
{
return ExchangeConfigType.getInstance();
@@ -540,6 +548,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener
return getMsgReceives();
}
+ public long getMsgDrops()
+ {
+ return 0l;
+ }
+
public long getByteReceives()
{
return _bytesReceived.get();
@@ -550,6 +563,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener
return getByteReceives();
}
+ public long getByteDrops()
+ {
+ return 0l;
+ }
+
public long getCreateTime()
{
return _createTime;
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
index 787cede2b7..1b173c7e11 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
index 631bd3c7cc..c3604dca44 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java
@@ -28,7 +28,7 @@ public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate
public interface Delegate
{
- UUID getId();
+ UUID getQMFId();
long getCreateTime();
}
@@ -49,7 +49,7 @@ public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate
public final UUID getId()
{
- return _delegate.getId();
+ return _delegate.getQMFId();
}
public final long getCreateTime()
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index 900b722886..d713976919 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -436,7 +436,7 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
QMFObject qmfObject = classObjects.remove(object);
if(qmfObject != null)
{
- _managedObjectsById.get(qmfClass).remove(object.getId());
+ _managedObjectsById.get(qmfClass).remove(object.getQMFId());
objectRemoved(qmfObject);
}
}
@@ -468,7 +468,7 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
}
}
- classObjectsById.put(object.getId(),qmfObject);
+ classObjectsById.put(object.getQMFId(),qmfObject);
if(classObjects.putIfAbsent(object, qmfObject) == null)
{
@@ -570,7 +570,7 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
public UUID getSystemId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public String getOsName()
@@ -598,9 +598,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getOSArchitecture();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -964,9 +964,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1004,9 +1004,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getFederationTag();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1135,9 +1135,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getByteRoutes();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1470,9 +1470,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getArguments();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1526,9 +1526,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getMatches();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1647,9 +1647,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return factory.createResponseCommand();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1741,6 +1741,12 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return 0l;
}
+ public Long getUnackedMessages()
+ {
+ // TODO
+ return 0l;
+ }
+
public Long getTxnStarts()
{
return _obj.getTxnStarts();
@@ -1799,9 +1805,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return factory.createResponseCommand();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1870,9 +1876,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getDelivered();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -1955,14 +1961,20 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getAckBatching();
}
+ /* support TBD */
+ public String getName()
+ {
+ return null;
+ }
+
public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory)
{
return null;
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
@@ -2020,6 +2032,18 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return _obj.getLastError();
}
+ /* support TBD */
+ public String getName()
+ {
+ return null;
+ }
+
+ /* support TBD */
+ public BrokerSchema.ConnectionObject getConnectionRef()
+ {
+ return (BrokerSchema.ConnectionObject) null;
+ }
+
public BrokerSchema.LinkClass.CloseMethodResponseCommand close(final BrokerSchema.LinkClass.CloseMethodResponseCommandFactory factory)
{
_obj.close();
@@ -2042,9 +2066,9 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return factory.createResponseCommand();
}
- public UUID getId()
+ public UUID getQMFId()
{
- return _obj.getId();
+ return _obj.getQMFId();
}
public long getCreateTime()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
deleted file mode 100644
index 0f32b98aa8..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 8198cec821..e197dddfde 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -23,7 +23,9 @@ package org.apache.qpid.server;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -32,9 +34,9 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
-import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
@@ -89,7 +91,6 @@ import org.apache.qpid.server.subscription.ClientDeliveryMethod;
import org.apache.qpid.server.subscription.RecordDeliveryMethod;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
-import org.apache.qpid.server.subscription.SubscriptionImpl;
import org.apache.qpid.server.txn.AsyncAutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
@@ -137,11 +138,9 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
private final LinkedList<AsyncCommand> _unfinishedCommandsQueue = new LinkedList<AsyncCommand>();
- private static final int UNFINISHED_COMMAND_QUEUE_THRESHOLD = 500;
-
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);
@@ -157,7 +156,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
private final AMQProtocolSession _session;
private AtomicBoolean _closing = new AtomicBoolean(false);
- private final Set<AMQQueue> _blockingQueues = new ConcurrentSkipListSet<AMQQueue>();
+ private final Set<Object> _blockingEntities = Collections.synchronizedSet(new HashSet<Object>());
private final AtomicBoolean _blocking = new AtomicBoolean(false);
@@ -170,11 +169,13 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
private List<QueueEntry> _resendList = new ArrayList<QueueEntry>();
private static final
AMQShortString IMMEDIATE_DELIVERY_REPLY_TEXT = new AMQShortString("Immediate delivery is not possible.");
- private final UUID _id;
+ private final UUID _qmfId;
private long _createTime = System.currentTimeMillis();
private final ClientDeliveryMethod _clientDeliveryMethod;
+ private final TransactionTimeoutHelper _transactionTimeoutHelper;
+
public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore)
throws AMQException
{
@@ -183,7 +184,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_actor = new AMQPChannelActor(this, session.getLogActor().getRootMessageLogger());
_logSubject = new ChannelLogSubject(this);
- _id = getConfigStore().createId();
+ _qmfId = getConfigStore().createId();
_actor.message(ChannelMessages.CREATE());
getConfigStore().addConfiguredObject(this);
@@ -194,6 +195,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_transaction = new AsyncAutoCommitTransaction(_messageStore, this);
_clientDeliveryMethod = session.createDeliveryMethod(_channelId);
+
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
}
public ConfigStore getConfigStore()
@@ -264,6 +267,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return _txnCount.get();
}
+ public Long getTxnStart()
+ {
+ return _txnStarts.get();
+ }
+
public int getChannelId()
{
return _channelId;
@@ -441,7 +449,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
*
@@ -948,9 +956,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
public void commit() throws AMQException
{
- commit(null);
+ commit(null, false);
}
- public void commit(Runnable immediateAction) throws AMQException
+
+
+ public void commit(final Runnable immediateAction, boolean async) throws AMQException
{
if (!isTransactional())
@@ -958,11 +968,29 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
throw new AMQException("Fatal error: commit called on non-transactional channel");
}
- _transaction.commit(immediateAction);
+ if(async && _transaction instanceof LocalTransaction)
+ {
+
+ ((LocalTransaction)_transaction).commitAsync(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ immediateAction.run();
+ _txnCommits.incrementAndGet();
+ _txnStarts.incrementAndGet();
+ decrementOutstandingTxnsIfNecessary();
+ }
+ });
+ }
+ else
+ {
+ _transaction.commit(immediateAction);
- _txnCommits.incrementAndGet();
- _txnStarts.incrementAndGet();
- decrementOutstandingTxnsIfNecessary();
+ _txnCommits.incrementAndGet();
+ _txnStarts.incrementAndGet();
+ decrementOutstandingTxnsIfNecessary();
+ }
}
public void rollback() throws AMQException
@@ -1357,9 +1385,34 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return _actor;
}
- public void block(AMQQueue queue)
+ public synchronized void block()
{
- if(_blockingQueues.add(queue))
+ if(_blockingEntities.add(this))
+ {
+ if(_blocking.compareAndSet(false,true))
+ {
+ _actor.message(_logSubject, ChannelMessages.FLOW_ENFORCED("** All Queues **"));
+ flow(false);
+ }
+ }
+ }
+
+ public synchronized void unblock()
+ {
+ if(_blockingEntities.remove(this))
+ {
+ if(_blockingEntities.isEmpty() && _blocking.compareAndSet(true,false))
+ {
+ _actor.message(_logSubject, ChannelMessages.FLOW_REMOVED());
+
+ flow(true);
+ }
+ }
+ }
+
+ public synchronized void block(AMQQueue queue)
+ {
+ if(_blockingEntities.add(queue))
{
if(_blocking.compareAndSet(false,true))
@@ -1370,11 +1423,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
}
}
- public void unblock(AMQQueue queue)
+ public synchronized void unblock(AMQQueue queue)
{
- if(_blockingQueues.remove(queue))
+ if(_blockingEntities.remove(queue))
{
- if(_blocking.compareAndSet(true,false) && !isClosing())
+ if(_blockingEntities.isEmpty() && _blocking.compareAndSet(true,false) && !isClosing())
{
_actor.message(_logSubject, ChannelMessages.FLOW_REMOVED());
@@ -1393,6 +1446,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();
@@ -1400,6 +1458,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_session.writeFrame(responseBody.generateFrame(_channelId));
}
+ @Override
public boolean getBlocking()
{
return _blocking.get();
@@ -1456,9 +1515,10 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return false;
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public String getSessionName()
@@ -1484,30 +1544,42 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
long openTime = currentTime - _transaction.getTransactionStartTime();
long idleTime = currentTime - _txnUpdateTime.get();
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(_logSubject, ChannelMessages.IDLE_TXN(idleTime));
- _logger.warn("IDLE TRANSACTION ALERT " + _logSubject.toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
+ _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime),
+ TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT);
+ if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose))
{
- CurrentActor.get().message(_logSubject, ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + _logSubject.toString() + " " + openTime + " ms");
+ closeConnection("Idle transaction timed out");
+ return;
}
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
+ _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime),
+ TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT);
+ if (_transactionTimeoutHelper.isTimedOut(openTime, openClose))
{
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
- }
- else if (openClose > 0L && openTime > openClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
+ closeConnection("Open transaction timed out");
+ return;
}
}
}
+ /**
+ * Typically called from the HouseKeepingThread instead of the main receiver thread,
+ * therefore uses a lock to close the connection in a thread-safe manner.
+ */
+ private void closeConnection(String reason) throws AMQException
+ {
+ Lock receivedLock = _session.getReceivedLock();
+ receivedLock.lock();
+ try
+ {
+ _session.close(AMQConstant.RESOURCE_ERROR, reason);
+ }
+ finally
+ {
+ receivedLock.unlock();
+ }
+ }
+
public void deadLetter(long deliveryTag) throws AMQException
{
final UnacknowledgedMessageMap unackedMap = getUnacknowledgedMessageMap();
@@ -1563,23 +1635,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_unfinishedCommandsQueue.add(new AsyncCommand(future, action));
}
- public void completeAsyncCommands()
- {
- AsyncCommand cmd;
- while((cmd = _unfinishedCommandsQueue.peek()) != null && cmd.isReadyForCompletion())
- {
- cmd.complete();
- _unfinishedCommandsQueue.poll();
- }
- while(_unfinishedCommandsQueue.size() > UNFINISHED_COMMAND_QUEUE_THRESHOLD)
- {
- cmd = _unfinishedCommandsQueue.poll();
- cmd.awaitReadyForCompletion();
- cmd.complete();
- }
- }
-
-
public void sync()
{
AsyncCommand cmd;
@@ -1588,6 +1643,10 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
cmd.awaitReadyForCompletion();
cmd.complete();
}
+ if(_transaction instanceof LocalTransaction)
+ {
+ ((LocalTransaction)_transaction).sync();
+ }
}
private static class AsyncCommand
@@ -1624,6 +1683,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
public int compareTo(AMQSessionModel session)
{
- return getId().compareTo(session.getId());
+ return getQMFId().compareTo(session.getQMFId());
+ }
+
+ @Override
+ public int getConsumerCount()
+ {
+ return _tag2SubscriptionMap.size();
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/Broker.java
index 5004d320c2..d58a0d5bb4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/Broker.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/Broker.java
@@ -20,19 +20,22 @@
*/
package org.apache.qpid.server;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+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.log4j.LoggingFacade;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
@@ -46,30 +49,10 @@ import org.apache.qpid.transport.network.Transport;
import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-import javax.net.ssl.SSLContext;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.EnumSet;
-import java.util.Formatter;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.FileHandler;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
public class Broker
{
private static final Logger LOGGER = Logger.getLogger(Broker.class);
- private static final int IPV4_ADDRESS_LENGTH = 4;
- private static final char IPV4_LITERAL_SEPARATOR = '.';
private volatile Thread _shutdownHookThread;
protected static class InitException extends RuntimeException
@@ -128,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);
@@ -145,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())
{
@@ -165,36 +148,71 @@ public class Broker
parsePortList(sslPorts, serverConfig.getSSLPorts());
}
+ //1-0 excludes and includes
Set<Integer> exclude_1_0 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v1_0));
if(exclude_1_0.isEmpty())
{
parsePortList(exclude_1_0, serverConfig.getPortExclude10());
}
+ Set<Integer> include_1_0 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v1_0));
+ if(include_1_0.isEmpty())
+ {
+ parsePortList(include_1_0, serverConfig.getPortInclude10());
+ }
+
+ //0-10 excludes and includes
Set<Integer> exclude_0_10 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_10));
if(exclude_0_10.isEmpty())
{
parsePortList(exclude_0_10, serverConfig.getPortExclude010());
}
+ Set<Integer> include_0_10 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_10));
+ if(include_0_10.isEmpty())
+ {
+ parsePortList(include_0_10, serverConfig.getPortInclude010());
+ }
+
+ //0-9-1 excludes and includes
Set<Integer> exclude_0_9_1 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9_1));
if(exclude_0_9_1.isEmpty())
{
parsePortList(exclude_0_9_1, serverConfig.getPortExclude091());
}
+ Set<Integer> include_0_9_1 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9_1));
+ if(include_0_9_1.isEmpty())
+ {
+ parsePortList(include_0_9_1, serverConfig.getPortInclude091());
+ }
+
+ //0-9 excludes and includes
Set<Integer> exclude_0_9 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9));
if(exclude_0_9.isEmpty())
{
parsePortList(exclude_0_9, serverConfig.getPortExclude09());
}
+ Set<Integer> include_0_9 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9));
+ if(include_0_9.isEmpty())
+ {
+ parsePortList(include_0_9, serverConfig.getPortInclude09());
+ }
+
+ //0-8 excludes and includes
Set<Integer> exclude_0_8 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_8));
if(exclude_0_8.isEmpty())
{
parsePortList(exclude_0_8, serverConfig.getPortExclude08());
}
+ Set<Integer> include_0_8 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_8));
+ if(include_0_8.isEmpty())
+ {
+ parsePortList(include_0_8, serverConfig.getPortInclude08());
+ }
+
String bindAddr = options.getBind();
if (bindAddr == null)
{
@@ -220,8 +238,8 @@ public class Broker
final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, port);
final Set<AmqpProtocolVersion> supported =
- getSupportedVersions(port, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9,
- exclude_0_8, serverConfig);
+ getSupportedVersions(port, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8,
+ include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8,serverConfig);
final NetworkTransportConfiguration settings =
new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP);
@@ -233,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));
}
}
@@ -242,16 +260,31 @@ public class Broker
{
final String keystorePath = serverConfig.getConnectorKeyStorePath();
final String keystorePassword = serverConfig.getConnectorKeyStorePassword();
+ final String keystoreType = serverConfig.getConnectorKeyStoreType();
final String keyManagerFactoryAlgorithm = serverConfig.getConnectorKeyManagerFactoryAlgorithm();
- final SSLContext sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keyManagerFactoryAlgorithm);
+ final SSLContext sslContext;
+ if(serverConfig.getConnectorTrustStorePath()!=null)
+ {
+ sslContext = SSLContextFactory.buildClientContext(serverConfig.getConnectorTrustStorePath(),
+ serverConfig.getConnectorTrustStorePassword(),
+ serverConfig.getConnectorTrustStoreType(),
+ serverConfig.getConnectorTrustManagerFactoryAlgorithm(),
+ keystorePath,
+ keystorePassword, keystoreType, keyManagerFactoryAlgorithm,
+ serverConfig.getCertAlias());
+ }
+ else
+ {
+ sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm);
+ }
for(int sslPort : sslPorts)
{
final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, sslPort);
final Set<AmqpProtocolVersion> supported =
- getSupportedVersions(sslPort, exclude_1_0, exclude_0_10, exclude_0_9_1,
- exclude_0_9, exclude_0_8, serverConfig);
+ getSupportedVersions(sslPort, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8,
+ include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8, serverConfig);
final NetworkTransportConfiguration settings =
new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP);
@@ -262,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));
}
}
@@ -282,27 +315,36 @@ public class Broker
final Set<Integer> exclude_0_9_1,
final Set<Integer> exclude_0_9,
final Set<Integer> exclude_0_8,
+ final Set<Integer> include_1_0,
+ final Set<Integer> include_0_10,
+ final Set<Integer> include_0_9_1,
+ final Set<Integer> include_0_9,
+ final Set<Integer> include_0_8,
final ServerConfiguration serverConfig)
{
final EnumSet<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class);
- if(exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled())
+ if((exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled()) && !include_1_0.contains(port))
{
supported.remove(AmqpProtocolVersion.v1_0_0);
}
- if(exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled())
+
+ if((exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) && !include_0_10.contains(port))
{
supported.remove(AmqpProtocolVersion.v0_10);
}
- if(exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled())
+
+ if((exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled()) && !include_0_9_1.contains(port))
{
supported.remove(AmqpProtocolVersion.v0_9_1);
}
- if(exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled())
+
+ if((exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled()) && !include_0_9.contains(port))
{
supported.remove(AmqpProtocolVersion.v0_9);
}
- if(exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled())
+
+ if((exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled()) && !include_0_8.contains(port))
{
supported.remove(AmqpProtocolVersion.v0_8);
}
@@ -388,7 +430,7 @@ public class Broker
}
}
- private void configureLogging(File logConfigFile, long logWatchTime) throws InitException, IOException
+ private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException
{
if (logConfigFile.exists() && logConfigFile.canRead())
{
@@ -401,7 +443,7 @@ public class Broker
// log4j expects the watch interval in milliseconds
try
{
- QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
+ LoggingFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
}
catch (Exception e)
{
@@ -412,7 +454,7 @@ public class Broker
{
try
{
- QpidLog4JConfigurator.configure(logConfigFile.getPath());
+ LoggingFacade.configure(logConfigFile.getPath());
}
catch (Exception e)
{
@@ -446,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/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
index d871c724fd..434d40d557 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
@@ -33,10 +33,12 @@ 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>();
private final Map<ProtocolExclusion,Set<Integer>> _exclusionMap = new HashMap<ProtocolExclusion, Set<Integer>>();
+ private final Map<ProtocolInclusion,Set<Integer>> _inclusionMap = new HashMap<ProtocolInclusion, Set<Integer>>();
private String _configFile;
private String _logConfigFile;
@@ -46,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)
{
@@ -108,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)
@@ -161,4 +165,36 @@ public class BrokerOptions
{
_bundleContext = bundleContext;
}
+
+ public Set<Integer> getIncludedPorts(final ProtocolInclusion includeProtocol)
+ {
+ final Set<Integer> includedPorts = _inclusionMap.get(includeProtocol);
+ return includedPorts == null ? Collections.<Integer>emptySet() : includedPorts;
+ }
+
+ public void addIncludedPort(final ProtocolInclusion includeProtocol, final int port)
+ {
+ if (!_inclusionMap.containsKey(includeProtocol))
+ {
+ _inclusionMap.put(includeProtocol, new HashSet<Integer>());
+ }
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 70fa414e3c..9fe7a6619f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -85,6 +85,32 @@ public class Main
.withDescription("when listening on the specified port do not accept AMQP0-8 connections. The specified port must be one specified on the command line")
.withLongOpt("exclude-0-8").create();
+ private static final Option OPTION_INCLUDE_1_0 =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("accept AMQP1-0 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line")
+ .withLongOpt("include-1-0").create();
+
+private static final Option OPTION_INCLUDE_0_10 =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("accept AMQP0-10 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line")
+ .withLongOpt("include-0-10").create();
+
+private static final Option OPTION_INCLUDE_0_9_1 =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("accept AMQP0-9-1 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line")
+ .withLongOpt("include-0-9-1").create();
+
+private static final Option OPTION_INCLUDE_0_9 =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("accept AMQP0-9 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line")
+ .withLongOpt("include-0-9").create();
+
+private static final Option OPTION_INCLUDE_0_8 =
+ OptionBuilder.withArgName("port").hasArg()
+ .withDescription("accept AMQP0-8 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line")
+ .withLongOpt("include-0-8").create();
+
+
private static final Option OPTION_JMX_PORT_REGISTRY_SERVER =
OptionBuilder.withArgName("port").hasArg()
.withDescription("listen on the specified management (registry server) port. Overrides any value in the config file")
@@ -127,6 +153,11 @@ public class Main
OPTIONS.addOption(OPTION_EXCLUDE_0_9_1);
OPTIONS.addOption(OPTION_EXCLUDE_0_9);
OPTIONS.addOption(OPTION_EXCLUDE_0_8);
+ OPTIONS.addOption(OPTION_INCLUDE_1_0);
+ OPTIONS.addOption(OPTION_INCLUDE_0_10);
+ OPTIONS.addOption(OPTION_INCLUDE_0_9_1);
+ OPTIONS.addOption(OPTION_INCLUDE_0_9);
+ OPTIONS.addOption(OPTION_INCLUDE_0_8);
OPTIONS.addOption(OPTION_BIND);
OPTIONS.addOption(OPTION_JMX_PORT_REGISTRY_SERVER);
@@ -256,6 +287,10 @@ public class Main
{
parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe);
}
+ for(ProtocolInclusion pe : ProtocolInclusion.values())
+ {
+ parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe);
+ }
}
String[] sslPortStr = _commandLine.getOptionValues(OPTION_SSLPORT.getOpt());
@@ -266,6 +301,10 @@ public class Main
{
parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe);
}
+ for(ProtocolInclusion pe : ProtocolInclusion.values())
+ {
+ parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe);
+ }
}
setExceptionHandler();
@@ -399,4 +438,23 @@ public class Main
}
}
}
+
+ private static void parseProtocolInclusions(final BrokerOptions options, final Object[] ports,
+ final ProtocolInclusion includedProtocol) throws InitException
+ {
+ if(ports != null)
+ {
+ for(int i = 0; i < ports.length; i++)
+ {
+ try
+ {
+ options.addIncludedPort(includedProtocol, Integer.parseInt(String.valueOf(ports[i])));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InitException("Invalid port for inclusion: " + ports[i], e);
+ }
+ }
+ }
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java
new file mode 100644
index 0000000000..85fbe2e02e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+public enum ProtocolInclusion
+{
+ v0_8("include-0-8","--include-0-8"),
+ v0_9("include-0-9", "--include-0-9"),
+ v0_9_1("include-0-9-1", "--include-0-9-1"),
+ v0_10("include-0-10", "--include-0-10"),
+ v1_0("include-1-0", "--include-1-0");
+
+ private static final Map<String, ProtocolInclusion> MAP = new HashMap<String,ProtocolInclusion>();
+
+ static
+ {
+ for(ProtocolInclusion pe : ProtocolInclusion.values())
+ {
+ MAP.put(pe.getArg(), pe);
+ }
+ }
+
+ private String _arg;
+ private String _includeName;
+
+ private ProtocolInclusion(final String includeName, final String arg)
+ {
+ _includeName = includeName;
+ _arg = arg;
+ }
+
+ public String getArg()
+ {
+ return _arg;
+ }
+
+ public String getIncludeName()
+ {
+ return _includeName;
+ }
+
+ public static ProtocolInclusion lookup(final String arg)
+ {
+ ProtocolInclusion ex = MAP.get(arg);
+
+ if(ex == null)
+ {
+ throw new IllegalArgumentException(arg + " is not a valid protocol inclusion");
+ }
+
+ return ex;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java
new file mode 100644
index 0000000000..0c474cca13
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java
@@ -0,0 +1,63 @@
+/*
+ * 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.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ChannelMessages;
+
+public class TransactionTimeoutHelper
+{
+ private static final Logger LOGGER = Logger.getLogger(TransactionTimeoutHelper.class);
+
+ public static final String IDLE_TRANSACTION_ALERT = "IDLE TRANSACTION ALERT";
+ public static final String OPEN_TRANSACTION_ALERT = "OPEN TRANSACTION ALERT";
+
+ private final LogSubject _logSubject;
+
+ public TransactionTimeoutHelper(final LogSubject logSubject)
+ {
+ _logSubject = logSubject;
+ }
+
+ public void logIfNecessary(final long timeSoFar, final long warnTimeout,
+ final LogMessage message, final String alternateLogPrefix)
+ {
+ if (isTimedOut(timeSoFar, warnTimeout))
+ {
+ LogActor logActor = CurrentActor.get();
+ if(logActor.getRootMessageLogger().isMessageEnabled(logActor, _logSubject, message.getLogHierarchy()))
+ {
+ logActor.message(_logSubject, message);
+ }
+ else
+ {
+ LOGGER.warn(alternateLogPrefix + " " + _logSubject.toLogString() + " " + timeSoFar + " ms");
+ }
+ }
+ }
+
+ public boolean isTimedOut(long timeSoFar, long timeout)
+ {
+ return timeout > 0L && timeSoFar > timeout;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
index 2efd4cee26..9b3be624e0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java
@@ -35,11 +35,13 @@ public class Binding
private final Exchange _exchange;
private final Map<String, Object> _arguments;
private final UUID _id;
+ private final UUID _qmfId;
private final AtomicLong _matches = new AtomicLong();
- public Binding(UUID id, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
+ public Binding(UUID id, UUID qmfId, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
{
_id = id;
+ _qmfId = qmfId;
_bindingKey = bindingKey;
_queue = queue;
_exchange = exchange;
@@ -51,6 +53,11 @@ public class Binding
return _id;
}
+ public UUID getQMFId()
+ {
+ return _qmfId;
+ }
+
public String getBindingKey()
{
return _bindingKey;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
index abf252c733..b805056311 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
@@ -60,7 +60,7 @@ public class BindingFactory
private BindingImpl(UUID id, String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
{
- super(id, bindingKey, queue, exchange, arguments);
+ super(id, queue.getVirtualHost().getConfigStore().createId(), bindingKey, queue, exchange, arguments);
_logSubject = new BindingLogSubject(bindingKey,exchange,queue);
}
@@ -166,7 +166,7 @@ public class BindingFactory
if (id == null)
{
- id = UUIDGenerator.generateUUID();
+ id = UUIDGenerator.generateBindingUUID(exchange.getName(), queue.getName(), bindingKey, _virtualHost.getName());
}
BindingImpl b = new BindingImpl(id, bindingKey, queue, exchange, arguments);
BindingImpl existingMapping = _bindings.putIfAbsent(b, b);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
index aff07250f3..c519a0c0fa 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
@@ -101,7 +101,7 @@ public class ConfigStore
}
- typeMap.put(object.getId(), object);
+ typeMap.put(object.getQMFId(), object);
sendEvent(Event.CREATED, object);
}
@@ -111,7 +111,7 @@ public class ConfigStore
ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType());
if(typeMap != null)
{
- typeMap.remove(object.getId());
+ typeMap.remove(object.getQMFId());
sendEvent(Event.DELETED, object);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java
index 78666a3f93..ff4e38d9f7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java
@@ -25,7 +25,7 @@ import java.util.UUID;
public interface ConfiguredObject<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>>
{
- public UUID getId();
+ public UUID getQMFId();
public T getConfigType();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
index 41c51d9684..6633d93adf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
index ea4f723dda..847cae87f5 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
@@ -76,7 +76,7 @@ public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkC
}
};
- public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("host")
+ public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("port")
{
public Integer getValue(LinkConfig object)
{
@@ -134,4 +134,4 @@ public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkC
-} \ No newline at end of file
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
index 40bafb4275..8f03383777 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 46027d02c6..f9e2d93cff 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -20,6 +20,16 @@
package org.apache.qpid.server.configuration;
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
@@ -28,7 +38,6 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger;
-
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.exchange.DefaultExchangeFactory;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
@@ -40,17 +49,6 @@ import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.net.ssl.KeyManagerFactory;
-
public class ServerConfiguration extends ConfigurationPlugin
{
protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class);
@@ -66,6 +64,9 @@ 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 int DEFAULT_HTTPS_MANAGEMENT_PORT = 8443;
+ public static final long DEFAULT_MINIMUM_ALERT_REPEAT_GAP = 30000l;
public static final String QPID_HOME = "QPID_HOME";
public static final String QPID_WORK = "QPID_WORK";
@@ -77,6 +78,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>();
@@ -86,6 +89,9 @@ public class ServerConfiguration extends ConfigurationPlugin
public static final String MGMT_CUSTOM_REGISTRY_SOCKET = "management.custom-registry-socket";
public static final String MGMT_JMXPORT_REGISTRYSERVER = "management.jmxport.registryServer";
public static final String MGMT_JMXPORT_CONNECTORSERVER = "management.jmxport.connectorServer";
+ public static final String SECURITY_DEFAULT_AUTH_MANAGER = "security.default-auth-manager";
+ public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER = "security.port-mappings.port-mapping.auth-manager";
+ public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT = "security.port-mappings.port-mapping.port";
public static final String STATUS_UPDATES = "status-updates";
public static final String ADVANCED_LOCALE = "advanced.locale";
public static final String CONNECTOR_AMQP10ENABLED = "connector.amqp10enabled";
@@ -94,6 +100,11 @@ public class ServerConfiguration extends ConfigurationPlugin
public static final String CONNECTOR_AMQP09ENABLED = "connector.amqp09enabled";
public static final String CONNECTOR_AMQP08ENABLED = "connector.amqp08enabled";
public static final String CONNECTOR_AMQP_SUPPORTED_REPLY = "connector.amqpDefaultSupportedProtocolReply";
+ public static final String CONNECTOR_INCLUDE_10 = "connector.include10";
+ public static final String CONNECTOR_INCLUDE_010 = "connector.include010";
+ public static final String CONNECTOR_INCLUDE_091 = "connector.include091";
+ public static final String CONNECTOR_INCLUDE_09 = "connector.include09";
+ public static final String CONNECTOR_INCLUDE_08 = "connector.include08";
{
envVarMap.put("QPID_PORT", "connector.port");
@@ -104,6 +115,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");
@@ -177,7 +190,7 @@ public class ServerConfiguration extends ConfigurationPlugin
* This has been made a two step process to allow the Plugin Manager and
* Configuration Manager to be initialised in the Application Registry.
* <p>
- * If using this ServerConfiguration via an ApplicationRegistry there is no
+ * If using this ServerConfiguration via an ApplicationRegistry there is no
* need to explicitly call {@link #initialise()} as this is done via the
* {@link ApplicationRegistry#initialise()} method.
*
@@ -199,12 +212,12 @@ public class ServerConfiguration extends ConfigurationPlugin
* Called by {@link ApplicationRegistry#initialise()}.
* <p>
* NOTE: A DEFAULT ApplicationRegistry must exist when using this method
- * or a new ApplicationRegistry will be created.
+ * or a new ApplicationRegistry will be created.
*
* @throws ConfigurationException
*/
public void initialise() throws ConfigurationException
- {
+ {
setConfiguration("", getConfig());
setupVirtualHosts(getConfig());
}
@@ -219,10 +232,10 @@ public class ServerConfiguration extends ConfigurationPlugin
{
// Support for security.jmx.access was removed when JMX access rights were incorporated into the main ACL.
// This ensure that users remove the element from their configuration file.
-
+
if (getListValue("security.jmx.access").size() > 0)
{
- String message = "Validation error : security/jmx/access is no longer a supported element within the configuration xml."
+ String message = "Validation error : security/jmx/access is no longer a supported element within the configuration xml."
+ (_configFile == null ? "" : " Configuration file : " + _configFile);
throw new ConfigurationException(message);
}
@@ -236,7 +249,7 @@ public class ServerConfiguration extends ConfigurationPlugin
if (getListValue("security.principal-databases.principal-database(0).class").size() > 0)
{
- String message = "Validation error : security/principal-databases is no longer supported within the configuration xml."
+ String message = "Validation error : security/principal-databases is no longer supported within the configuration xml."
+ (_configFile == null ? "" : " Configuration file : " + _configFile);
throw new ConfigurationException(message);
}
@@ -249,6 +262,13 @@ public class ServerConfiguration extends ConfigurationPlugin
throw new ConfigurationException(message);
}
+ String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT);
+ String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER);
+ if (ports.length != authManagers.length)
+ {
+ throw new ConfigurationException("Validation error: Each port-mapping must have exactly one port and exactly one auth-manager.");
+ }
+
// QPID-3517: Inconsistency in capitalisation in the SSL configuration keys used within the connector and management configuration
// sections. For the moment, continue to understand both but generate a deprecated warning if the less preferred keystore is used.
for (String key : new String[] {"management.ssl.keystorePath",
@@ -280,7 +300,7 @@ public class ServerConfiguration extends ConfigurationPlugin
@SuppressWarnings("unchecked")
protected void setupVirtualHosts(Configuration conf) throws ConfigurationException
{
- List<String> vhostFiles = conf.getList("virtualhosts");
+ List<String> vhostFiles = (List) conf.getList("virtualhosts");
Configuration vhostConfig = conf.subset("virtualhosts");
// Only one configuration mechanism allowed
@@ -470,7 +490,7 @@ public class ServerConfiguration extends ConfigurationPlugin
Configuration newConfig = parseConfig(_configFile);
setConfiguration("", newConfig);
ApplicationRegistry.getInstance().getSecurityManager().configureHostPlugins(this);
-
+
// Reload virtualhosts from correct location
Configuration newVhosts;
if (_vhostsFile == null)
@@ -495,15 +515,29 @@ public class ServerConfiguration extends ConfigurationPlugin
_logger.warn(SECURITY_CONFIG_RELOADED);
}
}
-
+
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)
@@ -541,16 +575,36 @@ 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", DEFAULT_HTTP_MANAGEMENT_PORT);
+ }
+
+ public boolean getHTTPSManagementEnabled()
+ {
+ return getBooleanValue("management.https.enabled", false);
+ }
+
+ public int getHTTPSManagementPort()
+ {
+ return getIntValue("management.https.port", DEFAULT_HTTPS_MANAGEMENT_PORT);
+ }
+
public String[] getVirtualHosts()
{
return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]);
}
-
+
public String getPluginDirectory()
{
return getStringValue("plugin-directory");
}
-
+
public String getCacheDirectory()
{
return getStringValue("cache-directory");
@@ -581,6 +635,26 @@ public class ServerConfiguration extends ConfigurationPlugin
return getBooleanValue("security.msg-auth");
}
+ public String getDefaultAuthenticationManager()
+ {
+ return getStringValue(SECURITY_DEFAULT_AUTH_MANAGER);
+ }
+
+ public Map<Integer, String> getPortAuthenticationMappings()
+ {
+ String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT);
+ String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER);
+
+ Map<Integer,String> portMappings = new HashMap<Integer, String>();
+ for(int i = 0; i < ports.length; i++)
+ {
+ portMappings.put(Integer.valueOf(ports[i]), authManagers[i]);
+ }
+
+ return portMappings;
+ }
+
+
public String getManagementKeyStorePath()
{
final String fallback = getStringValue("management.ssl.keystorePath");
@@ -589,7 +663,7 @@ public class ServerConfiguration extends ConfigurationPlugin
public boolean getManagementSSLEnabled()
{
- return getBooleanValue("management.ssl.enabled", true);
+ return getBooleanValue("management.ssl.enabled", false);
}
public String getManagementKeyStorePassword()
@@ -603,16 +677,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);
@@ -645,7 +714,7 @@ public class ServerConfiguration extends ConfigurationPlugin
public long getMinimumAlertRepeatGap()
{
- return getLongValue("minimumAlertRepeatGap");
+ return getLongValue("minimumAlertRepeatGap", DEFAULT_MINIMUM_ALERT_REPEAT_GAP);
}
public long getCapacity()
@@ -693,6 +762,31 @@ public class ServerConfiguration extends ConfigurationPlugin
return getListValue("connector.non08port");
}
+ public List getPortInclude08()
+ {
+ return getListValue(CONNECTOR_INCLUDE_08);
+ }
+
+ public List getPortInclude09()
+ {
+ return getListValue(CONNECTOR_INCLUDE_09);
+ }
+
+ public List getPortInclude091()
+ {
+ return getListValue(CONNECTOR_INCLUDE_091);
+ }
+
+ public List getPortInclude010()
+ {
+ return getListValue(CONNECTOR_INCLUDE_010);
+ }
+
+ public List getPortInclude10()
+ {
+ return getListValue(CONNECTOR_INCLUDE_10);
+ }
+
public String getBind()
{
return getStringValue("connector.bind", WILDCARD_ADDRESS);
@@ -740,6 +834,11 @@ public class ServerConfiguration extends ConfigurationPlugin
return getStringValue("connector.ssl.keyStorePassword", fallback);
}
+ public String getConnectorKeyStoreType()
+ {
+ return getStringValue("connector.ssl.keyStoreType", "JKS");
+ }
+
public String getConnectorKeyManagerFactoryAlgorithm()
{
final String systemFallback = KeyManagerFactory.getDefaultAlgorithm();
@@ -748,6 +847,41 @@ public class ServerConfiguration extends ConfigurationPlugin
return getStringValue("connector.ssl.keyManagerFactoryAlgorithm", fallback);
}
+ public String getConnectorTrustStorePath()
+ {
+ return getStringValue("connector.ssl.trustStorePath", null);
+ }
+
+ public String getConnectorTrustStorePassword()
+ {
+ return getStringValue("connector.ssl.trustStorePassword", null);
+ }
+
+ public String getConnectorTrustStoreType()
+ {
+ return getStringValue("connector.ssl.trustStoreType", "JKS");
+ }
+
+ public String getConnectorTrustManagerFactoryAlgorithm()
+ {
+ return getStringValue("connector.ssl.trustManagerFactoryAlgorithm", TrustManagerFactory.getDefaultAlgorithm());
+ }
+
+ public String getCertAlias()
+ {
+ return getStringValue("connector.ssl.certAlias", null);
+ }
+
+ public boolean needClientAuth()
+ {
+ return getConfig().getBoolean("connector.ssl.needClientAuth", false);
+ }
+
+ public boolean wantClientAuth()
+ {
+ return getConfig().getBoolean("connector.ssl.wantClientAuth", false);
+ }
+
public String getDefaultVirtualHost()
{
return getStringValue("virtualhosts.default");
@@ -756,7 +890,7 @@ public class ServerConfiguration extends ConfigurationPlugin
public void setDefaultVirtualHost(String vhost)
{
getConfig().setProperty("virtualhosts.default", vhost);
- }
+ }
public void setHousekeepingCheckPeriod(long value)
{
@@ -883,4 +1017,15 @@ 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/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
index f6fe47b996..51dcc38c47 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
@@ -28,7 +28,7 @@ public class ServerNetworkTransportConfiguration implements NetworkTransportConf
private final String _transport;
private InetSocketAddress _address;
- public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig,
+ public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig,
final InetSocketAddress address,
final String transport)
{
@@ -76,4 +76,15 @@ public class ServerNetworkTransportConfiguration implements NetworkTransportConf
{
return _address;
}
+
+ public boolean needClientAuth()
+ {
+ return _serverConfig.needClientAuth();
+ }
+
+ @Override
+ public boolean wantClientAuth()
+ {
+ return _serverConfig.wantClientAuth();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
index 98109ce1e8..80c2e8b2f1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
@@ -33,7 +33,7 @@ public class SystemConfigImpl implements SystemConfig
private static final String OS_ARCH = System.getProperty("os.arch");
private static final String OS_VERSION = System.getProperty("os.version");
- private final UUID _id;
+ private final UUID _qmfId;
private String _name;
private final String _host;
@@ -48,9 +48,9 @@ public class SystemConfigImpl implements SystemConfig
this(store.createId(), store);
}
- public SystemConfigImpl(UUID id, ConfigStore store)
+ public SystemConfigImpl(UUID qmfId, ConfigStore store)
{
- _id = id;
+ _qmfId = qmfId;
_store = store;
String host;
try
@@ -95,9 +95,10 @@ public class SystemConfigImpl implements SystemConfig
return OS_ARCH;
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public SystemConfigType getConfigType()
@@ -119,12 +120,12 @@ public class SystemConfigImpl implements SystemConfig
{
broker.setSystem(this);
_store.addConfiguredObject(broker);
- _brokers.put(broker.getId(), broker);
+ _brokers.put(broker.getQMFId(), broker);
}
public void removeBroker(final BrokerConfig broker)
{
- _brokers.remove(broker.getId());
+ _brokers.remove(broker.getQMFId());
_store.removeConfiguredObject(broker);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
index d7c36da4e0..4a383cce7a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
@@ -65,7 +65,7 @@ public final class SystemConfigType extends ConfigObjectType<SystemConfigType, S
{
public UUID getValue(SystemConfig object)
{
- return object.getId();
+ return object.getQMFId();
}
};
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java
index 10e40151b0..aaa1766489 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java
@@ -61,7 +61,6 @@ public class TopicConfig extends ConfigurationPlugin
throw new ConfigurationException("Topic section must have a 'name' or 'subscriptionName' element.");
}
- System.err.println("********* Created TC:"+this);
}
@@ -75,5 +74,5 @@ public class TopicConfig extends ConfigurationPlugin
}
return response;
- }
+ }
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
index 5f472b6ddd..e557085631 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
@@ -32,7 +32,6 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.MemoryMessageStore;
-import org.apache.qpid.server.store.MemoryMessageStoreFactory;
import java.util.ArrayList;
import java.util.Arrays;
@@ -103,14 +102,14 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
return getConfig().subset("store");
}
- public String getMessageStoreFactoryClass()
+ public String getMessageStoreClass()
{
- return getStringValue("store.factoryclass", MemoryMessageStoreFactory.class.getName());
+ return getStringValue("store.class", MemoryMessageStore.class.getName());
}
- public void setMessageStoreFactoryClass(String storeFactoryClass)
+ public void setMessageStoreClass(String storeFactoryClass)
{
- getConfig().setProperty("store.factoryclass", storeFactoryClass);
+ getConfig().setProperty("store.class", storeFactoryClass);
}
public List getExchanges()
@@ -271,7 +270,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
public Long getMinimumAlertRepeatGap()
{
- return getLongValue("queues.minimumAlertRepeatGap");
+ return getLongValue("queues.minimumAlertRepeatGap", ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap());
}
public long getCapacity()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java
deleted file mode 100644
index f0ca5dc139..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
index 4a58314f51..451754e6d8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
@@ -22,13 +22,12 @@ package org.apache.qpid.server.connection;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.transport.TransportException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -37,6 +36,8 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
private List<AMQConnectionModel> _registry = new CopyOnWriteArrayList<AMQConnectionModel>();
private Logger _logger = Logger.getLogger(ConnectionRegistry.class);
+ private final Collection<RegistryChangeListener> _listeners =
+ new ArrayList<RegistryChangeListener>();
public void initialise()
{
@@ -62,34 +63,77 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
}
}
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message)
+ private void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message)
{
try
{
connection.close(cause, message);
}
- catch (TransportException e)
+ catch (Exception e)
{
- _logger.warn("Error closing connection:" + e.getMessage());
- }
- catch (AMQException e)
- {
- _logger.warn("Error closing connection:" + e.getMessage());
+ _logger.warn("Exception closing connection", e);
}
}
public void registerConnection(AMQConnectionModel connnection)
{
- _registry.add(connnection);
+ synchronized (this)
+ {
+ _registry.add(connnection);
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionRegistered(connnection);
+ }
+ }
+ }
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionRegistered(connnection);
+ }
+ }
}
public void deregisterConnection(AMQConnectionModel connnection)
{
- _registry.remove(connnection);
+ synchronized (this)
+ {
+ _registry.remove(connnection);
+
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionUnregistered(connnection);
+ }
+ }
+ }
+
+ synchronized (_listeners)
+ {
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.connectionUnregistered(connnection);
+ }
+ }
+ }
+
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ synchronized (_listeners)
+ {
+ _listeners.add(listener);
+ }
}
public List<AMQConnectionModel> getConnections()
{
- return new ArrayList<AMQConnectionModel>(_registry);
+ synchronized (this)
+ {
+ return new ArrayList<AMQConnectionModel>(_registry);
+ }
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
index 954c448b72..82adcf4dde 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
@@ -37,11 +37,18 @@ public interface IConnectionRegistry
public void close(String replyText) throws AMQException;
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message);
-
public List<AMQConnectionModel> getConnections();
public void registerConnection(AMQConnectionModel connnection);
public void deregisterConnection(AMQConnectionModel connnection);
+
+ void addRegistryChangeListener(RegistryChangeListener listener);
+
+ interface RegistryChangeListener
+ {
+ void connectionRegistered(AMQConnectionModel connection);
+ void connectionUnregistered(AMQConnectionModel connection);
+
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 9493f400f2..512a8c6996 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/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,12 +78,16 @@ 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>();
//TODO : persist creation time
private long _createTime = System.currentTimeMillis();
+ private UUID _qmfId;
+
public AbstractExchange(final ExchangeType<? extends Exchange> type)
{
_type = type;
@@ -107,13 +103,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
{
@@ -124,28 +113,14 @@ public abstract class AbstractExchange implements Exchange, Managable
_ticket = ticket;
_id = id;
-
+ _qmfId = getConfigStore().createId();
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 +146,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 +167,6 @@ public abstract class AbstractExchange implements Exchange, Managable
return getClass().getSimpleName() + "[" + getNameShortString() +"]";
}
- public ManagedObject getManagedObject()
- {
- return _exchangeMbean;
- }
-
public VirtualHost getVirtualHost()
{
return _virtualHost;
@@ -332,6 +298,12 @@ public abstract class AbstractExchange implements Exchange, Managable
return _id;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return _qmfId;
+ }
+
public ExchangeConfigType getConfigType()
{
return ExchangeConfigType.getInstance();
@@ -359,6 +331,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 +351,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 +366,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/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
deleted file mode 100644
index 034331abd9..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index bf4184bf0b..07813b073b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/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
+ for(RegistryChangeListener listener : _listeners)
{
- abstractExchange.getManagedObject().unregister();
- }
- catch (AMQException e)
- {
- LOGGER.warn("Failed to unregister mbean", e);
+ listener.exchangeUnregistered(exchange);
}
}
}
@@ -196,4 +225,21 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
}
}
+ public boolean isReservedExchangeName(String name)
+ {
+ if (name == null || "".equals(name) || ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString().equals(name)
+ || name.startsWith("amq.") || name.startsWith("qpid."))
+ {
+ return true;
+ }
+ Collection<ExchangeType<? extends Exchange>> registeredTypes = _host.getExchangeFactory().getRegisteredTypes();
+ for (ExchangeType<? extends Exchange> type : registeredTypes)
+ {
+ if (type.getDefaultExchangeName().toString().equals(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
index af9322764a..92326412c1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java
deleted file mode 100644
index 0bfaf7035d..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
index 289cb1a923..762686e68d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
@@ -147,4 +147,6 @@ public interface Exchange extends ExchangeReferrer, ExchangeConfig
{
public void onClose(Exchange exchange) throws AMQSecurityException, AMQInternalException;
}
+
+ UUID getId();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
index 795ae2e140..4dcedb4797 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
+++ b/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,21 @@ public interface ExchangeRegistry
void clearAndUnregisterMbeans();
Exchange getExchange(UUID exchangeId);
+
+ Collection<Exchange> getExchanges();
+
+ void addRegistryChangeListener(RegistryChangeListener listener);
+
+ /**
+ * Validates the name of user custom exchange.
+ * <p>
+ * Return true if the exchange name is reserved and false otherwise.
+ */
+ boolean isReservedExchangeName(String name);
+
+ interface RegistryChangeListener
+ {
+ void exchangeRegistered(Exchange exchange);
+ void exchangeUnregistered(Exchange exchange);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
index 5ebcfd095f..5f4998f77f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java
deleted file mode 100644
index 61e23c896c..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index 16ba3c0431..6bad59c2ae 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java
deleted file mode 100644
index 395c6c8a91..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
index 7ea7a41826..0ce16bd3f7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java
@@ -291,7 +291,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
{
- Binding binding = new Binding(null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments));
+ Binding binding = new Binding(null, null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments));
if (arguments == null)
{
@@ -314,7 +314,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue)
{
- Binding binding = new Binding(null, bindingKey, queue, this, arguments);
+ Binding binding = new Binding(null, null, bindingKey, queue, this, arguments);
if (arguments == null)
{
return _bindings.containsKey(binding);
@@ -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/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java
deleted file mode 100644
index 481a377fc4..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java
index dfe4d85320..dad951c3ca 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.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.exchange.topic;
import org.apache.qpid.framing.AMQShortString;
@@ -16,26 +36,6 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
-/*
-*
-* 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.
-*
-*/
public class TopicMatcherDFAState
{
private static final AtomicInteger stateId = new AtomicInteger();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherResult.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherResult.java
index 71d30adfac..6084b18b31 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherResult.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherResult.java
@@ -1,5 +1,3 @@
-package org.apache.qpid.server.exchange.topic;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,6 +18,8 @@ package org.apache.qpid.server.exchange.topic;
* under the License.
*
*/
+package org.apache.qpid.server.exchange.topic;
+
public interface TopicMatcherResult
{
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java
index 1cb4301838..6f47e4e7f2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.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.exchange.topic;
import org.apache.qpid.framing.AMQShortString;
@@ -13,26 +33,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
-/*
-*
-* 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.
-*
-*/
public class TopicParser
{
private static final byte TOPIC_DELIMITER = (byte)'.';
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java
index b23b3db272..7345d30a0a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java
@@ -1,7 +1,3 @@
-package org.apache.qpid.server.exchange.topic;
-
-import org.apache.qpid.framing.AMQShortString;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -22,6 +18,11 @@ import org.apache.qpid.framing.AMQShortString;
* under the License.
*
*/
+
+package org.apache.qpid.server.exchange.topic;
+
+import org.apache.qpid.framing.AMQShortString;
+
public final class TopicWord
{
public static final TopicWord ANY_WORD = new TopicWord("*");
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
index 65a0cd3107..181c26dd66 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWordDictionary.java
@@ -1,9 +1,3 @@
-package org.apache.qpid.server.exchange.topic;
-
-import org.apache.qpid.framing.AMQShortString;
-
-import java.util.concurrent.ConcurrentHashMap;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -24,6 +18,12 @@ import java.util.concurrent.ConcurrentHashMap;
* under the License.
*
*/
+package org.apache.qpid.server.exchange.topic;
+
+import org.apache.qpid.framing.AMQShortString;
+
+import java.util.concurrent.ConcurrentHashMap;
+
public class TopicWordDictionary
{
private final ConcurrentHashMap<AMQShortString,TopicWord> _dictionary =
diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
index c7046f8e53..7eb476b15a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
@@ -91,7 +91,7 @@ public class Bridge implements BridgeConfig
private final String _tag;
private final String _excludes;
private final BrokerLink _link;
- private UUID _id;
+ private UUID _qmfId;
private long _createTime = System.currentTimeMillis();
private Session _session;
@@ -124,7 +124,7 @@ public class Bridge implements BridgeConfig
_key = key;
_tag = tag;
_excludes = excludes;
- _id = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId();
+ _qmfId = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId();
_transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
@@ -198,7 +198,7 @@ public class Bridge implements BridgeConfig
{
_link = brokerLink;
_bridgeNo = bridgeNo;
- _id = id;
+ _qmfId = id;
brokerLink.getConfigStore().persistentIdInUse(id);
_createTime = createTime;
@@ -249,9 +249,10 @@ public class Bridge implements BridgeConfig
return Collections.unmodifiableMap(arguments);
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public BridgeConfigType getConfigType()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
index 4bcc0d6136..1ef57c53cb 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
@@ -89,7 +89,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
private final String _username;
private final String _password;
private final VirtualHost _virtualHost;
- private UUID _id;
+ private UUID _qmfId;
private AtomicBoolean _closing = new AtomicBoolean();
private final long _createTime;
private Connection _qpidConnection;
@@ -133,7 +133,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
private class ConnectionConfigAdapter implements ConnectionConfig
{
private long _adapterCreateTime = System.currentTimeMillis();
- private UUID _id = BrokerLink.this.getConfigStore().createId();
+ private UUID _qmfId = BrokerLink.this.getConfigStore().createId();
public VirtualHost getVirtualHost()
{
@@ -185,9 +185,10 @@ public class BrokerLink implements LinkConfig, ConnectionListener
return getVirtualHost().getConfigStore();
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public ConnectionConfigType getConfigType()
@@ -230,11 +231,11 @@ public class BrokerLink implements LinkConfig, ConnectionListener
}
};
- public BrokerLink(final VirtualHost virtualHost, UUID id, long createTime, Map<String, String> arguments)
+ public BrokerLink(final VirtualHost virtualHost, UUID qmfId, long createTime, Map<String, String> arguments)
{
_virtualHost = virtualHost;
- _id = id;
- virtualHost.getConfigStore().persistentIdInUse(id);
+ _qmfId = qmfId;
+ virtualHost.getConfigStore().persistentIdInUse(qmfId);
_createTime = createTime;
_transport = arguments.get(TRANSPORT);
@@ -289,7 +290,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
_authMechanism = authMechanism;
_username = username;
_password = password;
- _id = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId();
+ _qmfId = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId();
if(durable)
{
@@ -457,9 +458,10 @@ public class BrokerLink implements LinkConfig, ConnectionListener
return _remoteVhost;
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public LinkConfigType getConfigType()
@@ -672,7 +674,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
public String toString()
{
return "BrokerLink{" +
- " _id=" + _id +
+ " _id=" + _qmfId +
", _transport='" + _transport + '\'' +
", _host='" + _host + '\'' +
", _port=" + _port +
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java b/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
index 5a5ef5e6c5..be3a13d2d3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
@@ -1,8 +1,3 @@
-package org.apache.qpid.server.flow;
-
-
-import java.util.concurrent.atomic.AtomicLong;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -23,6 +18,11 @@ import java.util.concurrent.atomic.AtomicLong;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
+
+import java.util.concurrent.atomic.AtomicLong;
+
public class BytesOnlyCreditManager extends AbstractFlowCreditManager
{
private final AtomicLong _bytesCredit;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java b/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
index 8a80262983..280f2851a4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
@@ -1,6 +1,3 @@
-package org.apache.qpid.server.flow;
-
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -21,6 +18,10 @@ package org.apache.qpid.server.flow;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
+
+
public interface FlowCreditManager
{
long getMessageCredit();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager_0_10.java
index 48c336c0b1..fea6eaf744 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager_0_10.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager_0_10.java
@@ -1,5 +1,3 @@
-package org.apache.qpid.server.flow;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,6 +18,8 @@ package org.apache.qpid.server.flow;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
public interface FlowCreditManager_0_10 extends FlowCreditManager
{
public void addCredit(long count, long bytes);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java b/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
index 6fcc687440..89fc60666b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
@@ -1,6 +1,3 @@
-package org.apache.qpid.server.flow;
-
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -21,6 +18,9 @@ package org.apache.qpid.server.flow;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
+
public class LimitlessCreditManager extends AbstractFlowCreditManager implements FlowCreditManager
{
public long getMessageCredit()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java b/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
index 0e6ce70a60..31c1fda968 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
@@ -1,6 +1,3 @@
-package org.apache.qpid.server.flow;
-
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -21,6 +18,9 @@ package org.apache.qpid.server.flow;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
+
public class MessageAndBytesCreditManager extends AbstractFlowCreditManager implements FlowCreditManager
{
private long _messageCredit;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java b/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
index 9b7c40e923..1817e8ad31 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
@@ -1,8 +1,3 @@
-package org.apache.qpid.server.flow;
-
-
-import java.util.concurrent.atomic.AtomicLong;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -23,6 +18,10 @@ import java.util.concurrent.atomic.AtomicLong;
* under the License.
*
*/
+package org.apache.qpid.server.flow;
+
+import java.util.concurrent.atomic.AtomicLong;
+
public class MessageOnlyCreditManager extends AbstractFlowCreditManager implements FlowCreditManager
{
private final AtomicLong _messageCredit;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java
index e1c2782dec..84812485fd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.handler;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.handler;
* under the License.
*
*/
+package org.apache.qpid.server.handler;
import org.apache.qpid.AMQException;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java
index 1e0c0273df..43ee8da64f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.handler;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.handler;
* under the License.
*
*/
+package org.apache.qpid.server.handler;
import org.apache.log4j.Logger;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index 2ccf97f17c..b8c8411c5d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.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
@@ -61,7 +61,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
{
AMQProtocolSession session = stateManager.getProtocolSession();
- AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+ AuthenticationManager authMgr = stateManager.getAuthenticationManager();
SaslServer ss = session.getSaslServer();
if (ss == null)
@@ -92,7 +92,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
case SUCCESS:
if (_logger.isInfoEnabled())
{
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
+ _logger.info("Connected as: " + authResult.getSubject());
}
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
@@ -102,7 +102,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
session.setAuthorizedSubject(authResult.getSubject());
- disposeSaslServer(session);
+ disposeSaslServer(session);
break;
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 162e4e0215..a522b9f60f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.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
@@ -61,15 +61,15 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
-
+
_logger.info("SASL Mechanism selected: " + body.getMechanism());
_logger.info("Locale selected: " + body.getLocale());
- AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+ AuthenticationManager authMgr = stateManager.getAuthenticationManager();
SaslServer ss = null;
try
- {
- ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN());
+ {
+ ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal());
if (ss == null)
{
@@ -106,7 +106,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
case SUCCESS:
if (_logger.isInfoEnabled())
{
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
+ _logger.info("Connected as: " + authResult.getSubject());
}
session.setAuthorizedSubject(authResult.getSubject());
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index 396829df91..ae725b9ec1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -225,7 +225,10 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
String owner = body.getExclusive() ? AMQShortString.toString(session.getContextKey()) : null;
Map<String, Object> arguments = FieldTable.convertToMap(body.getArguments());
- final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateUUID(), AMQShortString.toString(queueName), body.getDurable(), owner, body.getAutoDelete(),
+ String queueNameString = AMQShortString.toString(queueName);
+
+ final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateQueueUUID(queueNameString, virtualHost.getName()),
+ queueNameString, body.getDurable(), owner, body.getAutoDelete(),
body.getExclusive(),virtualHost, arguments);
if (body.getExclusive() && !body.getDurable())
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
index a8ae2099cc..66a6ff6527 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.handler;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.handler;
* under the License.
*
*/
+package org.apache.qpid.server.handler;
import org.apache.log4j.Logger;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java
index 6e8896a023..afa5fdb72a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java
@@ -46,9 +46,9 @@ public class TxCommitHandler implements StateAwareMethodListener<TxCommitBody>
{
}
- public void methodReceived(AMQStateManager stateManager, TxCommitBody body, int channelId) throws AMQException
+ public void methodReceived(AMQStateManager stateManager, TxCommitBody body, final int channelId) throws AMQException
{
- AMQProtocolSession session = stateManager.getProtocolSession();
+ final AMQProtocolSession session = stateManager.getProtocolSession();
try
{
@@ -62,11 +62,19 @@ public class TxCommitHandler implements StateAwareMethodListener<TxCommitBody>
{
throw body.getChannelNotFoundException(channelId);
}
- channel.commit();
+ channel.commit(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ MethodRegistry methodRegistry = session.getMethodRegistry();
+ AMQMethodBody responseBody = methodRegistry.createTxCommitOkBody();
+ session.writeFrame(responseBody.generateFrame(channelId));
+ }
+ }, true);
+
- MethodRegistry methodRegistry = session.getMethodRegistry();
- AMQMethodBody responseBody = methodRegistry.createTxCommitOkBody();
- session.writeFrame(responseBody.generateFrame(channelId));
}
catch (AMQException e)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java b/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
deleted file mode 100644
index 4d395f625a..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java b/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java
new file mode 100644
index 0000000000..a1065319d3
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java
new file mode 100644
index 0000000000..931171b175
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java
@@ -0,0 +1,579 @@
+/*
+ *
+ * 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.log4j;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.log4j.xml.Log4jEntityResolver;
+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.xml.sax.SAXParseException;
+
+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.TransformerConfigurationException;
+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.FileOutputStream;
+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;
+
+/**
+ * A facade over log4j that allows both the control of the runtime logging behaviour (that is, the ability to
+ * turn {@link Logger} on, off and control their {@link Level}, and the manipulation and reload
+ * of the log4j configuration file.
+ */
+public class LoggingFacade
+{
+ private static Logger LOGGER;
+ private static transient LoggingFacade _instance;
+ private final String _filename;
+ private final int _delay;
+
+ public static LoggingFacade configure(String filename) throws LoggingFacadeException
+ {
+ _instance = new LoggingFacade(filename);
+ return _instance;
+ }
+
+ public static LoggingFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException
+ {
+ _instance = new LoggingFacade(filename, delay);
+ return _instance;
+ }
+
+ public static LoggingFacade getCurrentInstance()
+ {
+ return _instance;
+ }
+
+ private LoggingFacade(String filename)
+ {
+ DOMConfigurator.configure(filename);
+
+ if(LOGGER == null)
+ {
+ LOGGER = Logger.getLogger(LoggingFacade.class);
+ }
+ _filename = filename;
+ _delay = 0;
+ }
+
+ private LoggingFacade(String filename, int delay)
+ {
+ DOMConfigurator.configureAndWatch(filename, delay);
+
+ if(LOGGER == null)
+ {
+ LOGGER = Logger.getLogger(LoggingFacade.class);
+ }
+
+ _filename = filename;
+ _delay = delay;
+ }
+
+ public int getLog4jLogWatchInterval()
+ {
+ return _delay;
+ }
+
+ public synchronized void reload() throws LoggingFacadeException
+ {
+ DOMConfigurator.configure(_filename);
+ }
+
+ /** 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 synchronized Map<String,String> retrieveConfigFileLoggersLevels() throws LoggingFacadeException
+ {
+ try
+ {
+ Map<String,String> loggerLevelList = new HashMap<String,String>();
+ LOGGER.info("Getting logger levels from log4j configuration file");
+
+ Document doc = parseConfigFile(_filename);
+ List<Element> categoryOrLoggerElements = buildListOfCategoryOrLoggerElements(doc);
+
+ for (Element categoryOrLogger : categoryOrLoggerElements)
+ {
+
+ Element priorityOrLevelElement;
+ try
+ {
+ priorityOrLevelElement = getPriorityOrLevelElement(categoryOrLogger);
+ }
+ catch (LoggingFacadeException lfe)
+ {
+ //there is no exiting priority or level to view, move onto next category/logger
+ continue;
+ }
+
+ String categoryName = categoryOrLogger.getAttribute("name");
+ String priorityOrLevelValue = priorityOrLevelElement.getAttribute("value");
+ loggerLevelList.put(categoryName, priorityOrLevelValue);
+ }
+
+ return loggerLevelList;
+ }
+ catch (IOException e)
+ {
+ throw new LoggingFacadeException(e);
+ }
+ }
+
+ /**
+ * 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 synchronized String retrieveConfigFileRootLoggerLevel() throws LoggingFacadeException
+ {
+ try
+ {
+ 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);
+ Element levelElement = getPriorityOrLevelElement(rootElement);
+
+ if(levelElement != null)
+ {
+ return levelElement.getAttribute("value");
+ }
+ else
+ {
+ return "N/A";
+ }
+ }
+ catch (IOException e)
+ {
+ throw new LoggingFacadeException(e);
+ }
+ }
+
+ public synchronized void setConfigFileLoggerLevel(String logger, String level) throws LoggingFacadeException
+ {
+ LOGGER.info("Setting level to " + level + " for logger '" + logger
+ + "' in log4j xml configuration file: " + _filename);
+
+ try
+ {
+ Document doc = parseConfigFile(_filename);
+
+ List<Element> logElements = buildListOfCategoryOrLoggerElements(doc);
+
+ //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)
+ {
+ throw new LoggingFacadeException("Can't find logger " + logger);
+ }
+
+ Element levelElement = getPriorityOrLevelElement(logElement);
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level);
+
+ //output the new file
+ writeUpdatedConfigFile(_filename, doc);
+ }
+ catch (IOException ioe)
+ {
+ throw new LoggingFacadeException(ioe);
+ }
+ catch (TransformerConfigurationException e)
+ {
+ throw new LoggingFacadeException(e);
+ }
+ }
+
+ public synchronized void setConfigFileRootLoggerLevel(String level) throws LoggingFacadeException
+ {
+ try
+ {
+ LOGGER.info("Setting level to " + level + " for the Root logger in " +
+ "log4j xml configuration file: " + _filename);
+
+ Document doc = parseConfigFile(_filename);
+
+ //retrieve the optional 'root' element node
+ NodeList rootElements = doc.getElementsByTagName("root");
+
+ if (rootElements.getLength() == 0)
+ {
+ throw new LoggingFacadeException("Configuration contains no root element");
+ }
+
+ Element rootElement = (Element) rootElements.item(0);
+ Element levelElement = getPriorityOrLevelElement(rootElement);
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level);
+
+ //output the new file
+ writeUpdatedConfigFile(_filename, doc);
+ }
+ catch (IOException e)
+ {
+ throw new LoggingFacadeException(e);
+ }
+ catch (TransformerConfigurationException e)
+ {
+ throw new LoggingFacadeException(e);
+ }
+ }
+
+ public List<String> getAvailableLoggerLevels()
+ {
+ return new ArrayList<String>()
+ {{
+ add(Level.ALL.toString());
+ add(Level.TRACE.toString());
+ add(Level.DEBUG.toString());
+ add(Level.INFO.toString());
+ add(Level.WARN.toString());
+ add(Level.ERROR.toString());
+ add(Level.FATAL.toString());
+ add(Level.OFF.toString());
+ }};
+ }
+
+ public String retrieveRuntimeRootLoggerLevel()
+ {
+ Logger rootLogger = Logger.getRootLogger();
+ return rootLogger.getLevel().toString();
+ }
+
+ public void setRuntimeRootLoggerLevel(String level)
+ {
+ Level newLevel = Level.toLevel(level);
+
+ LOGGER.info("Setting RootLogger level to " + level);
+
+ Logger log = Logger.getRootLogger();
+ log.setLevel(newLevel);
+ }
+
+ public void setRuntimeLoggerLevel(String loggerName, String level) throws LoggingFacadeException
+ {
+ Level newLevel = level == null ? null : Level.toLevel(level);
+
+ Logger targetLogger = findRuntimeLogger(loggerName);
+
+ if(targetLogger == null)
+ {
+ throw new LoggingFacadeException("Can't find logger " + loggerName);
+ }
+
+ LOGGER.info("Setting level to " + newLevel + " for logger '" + targetLogger.getName() + "'");
+
+ targetLogger.setLevel(newLevel);
+ }
+
+ public Map<String,String> retrieveRuntimeLoggersLevels()
+ {
+ LOGGER.info("Getting levels for currently active log4j loggers");
+
+ Map<String, String> levels = new HashMap<String, String>();
+ @SuppressWarnings("unchecked")
+ Enumeration<Logger> loggers = LogManager.getCurrentLoggers();
+
+ while (loggers.hasMoreElements())
+ {
+ Logger logger = loggers.nextElement();
+ levels.put(logger.getName(), logger.getEffectiveLevel().toString());
+ }
+
+ return levels;
+ }
+
+ private void writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException, TransformerConfigurationException
+ {
+ 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;
+ transformer = TransformerFactory.newInstance().newTransformer();
+
+ 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.getAbsolutePath() + r.nextInt() + ".tmp");
+ }
+ while(tmp.exists());
+
+ tmp.deleteOnExit();
+
+ try
+ {
+ StreamResult result = new StreamResult(new FileOutputStream(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");
+ }
+ }
+
+ //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
+ private static Document parseConfigFile(String fileName) throws IOException
+ {
+ //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);
+ throw new IOException("Unable to parse the log4j XML file due to possible configuration error: ", e);
+ }
+ catch (SAXException e)
+ {
+ LOGGER.warn("The specified log4j XML file is invalid: ", e);
+ throw new IOException("The specified log4j XML file is invalid: ", e);
+ }
+ 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);
+ }
+
+ return doc;
+ }
+
+ private Logger findRuntimeLogger(String loggerName)
+ {
+ Logger targetLogger = null;
+ @SuppressWarnings("unchecked")
+ Enumeration<Logger> loggers = LogManager.getCurrentLoggers();
+ while(loggers.hasMoreElements())
+ {
+ targetLogger = loggers.nextElement();
+ if (targetLogger.getName().equals(loggerName))
+ {
+ return targetLogger;
+ }
+ }
+ return null;
+ }
+
+ private List<Element> buildListOfCategoryOrLoggerElements(Document doc)
+ {
+ //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));
+ }
+ return logElements;
+ }
+
+ private Element getPriorityOrLevelElement(Element categoryOrLogger) throws LoggingFacadeException
+ {
+ //retrieve the optional 'priority' or 'level' sub-element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = categoryOrLogger.getElementsByTagName("priority");
+ NodeList levelElements = categoryOrLogger.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
+ {
+ throw new LoggingFacadeException("Configuration " + categoryOrLogger.getNodeName()
+ + " element contains neither priority nor level child");
+ }
+ return levelElement;
+ }
+
+ private static class QpidLog4JSaxErrorHandler implements ErrorHandler
+ {
+ public void error(SAXParseException e) throws SAXException
+ {
+ if(LOGGER != null)
+ {
+ LOGGER.warn(constructMessage("Error parsing XML file", e));
+ }
+ else
+ {
+ System.err.println(constructMessage("Error parsing XML file", e));
+ }
+ }
+
+ public void fatalError(SAXParseException e) throws SAXException
+ {
+ throw new SAXException(constructMessage("Fatal error parsing XML file", e));
+ }
+
+ public void warning(SAXParseException e) throws SAXException
+ {
+ if(LOGGER != null)
+ {
+ LOGGER.warn(constructMessage("Warning parsing XML file", e));
+ }
+ else
+ {
+ System.err.println(constructMessage("Warning parsing XML file", e));
+ }
+ }
+
+ private static String constructMessage(final String msg, final SAXParseException ex)
+ {
+ return msg + ": Line " + ex.getLineNumber()+" column " +ex.getColumnNumber() + ": " + ex.getMessage();
+ }
+ }
+}
+
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacadeException.java
index 12d7f64a8d..468b06be34 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacadeException.java
@@ -17,24 +17,29 @@
* under the License.
*
*/
-package org.apache.qpid.server.store.derby;
+package org.apache.qpid.server.logging.log4j;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.MessageStoreFactory;
-
-public class DerbyMessageStoreFactory implements MessageStoreFactory
+public class LoggingFacadeException extends Exception
{
- @Override
- public MessageStore createMessageStore()
+ public LoggingFacadeException()
+ {
+ super();
+ }
+
+ public LoggingFacadeException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public LoggingFacadeException(String message)
{
- return new DerbyMessageStore();
+ super(message);
}
- @Override
- public String getStoreClassName()
+ public LoggingFacadeException(Throwable cause)
{
- return DerbyMessageStore.class.getSimpleName();
+ super(cause);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
deleted file mode 100644
index c699dff175..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties
index 081f2bbca3..d3823a71a0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/MessageStore_logmessages.properties
@@ -26,3 +26,5 @@ RECOVERY_START = MST-1004 : Recovery Start
RECOVERED = MST-1005 : Recovered {0,number} messages
RECOVERY_COMPLETE = MST-1006 : Recovery Complete
PASSIVATE = MST-1007 : Store Passivated
+OVERFULL = MST-1008 : Store overfull, flow control will be enforced
+UNDERFULL = MST-1009 : Store overfull condition cleared
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
index 3e640c7929..5695026cbc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
@@ -23,4 +23,6 @@ CREATED = VHT-1001 : Created : {0}
CLOSED = VHT-1002 : Closed
STATS_DATA = VHT-1003 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} kB/s peak : {3,number,#} bytes total
-STATS_MSGS = VHT-1004 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} msg/s peak : {3,number,#} msgs total` \ No newline at end of file
+STATS_MSGS = VHT-1004 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} msg/s peak : {3,number,#} msgs total
+
+ERRORED = VHT-1005 : Unexpected fatal error \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java b/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
deleted file mode 100644
index 5c57c01f6e..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java b/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java
deleted file mode 100644
index 6cfc827046..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
deleted file mode 100644
index 10d7503800..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
deleted file mode 100644
index 04a5b27991..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ /dev/null
@@ -1,491 +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.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;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-
-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 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.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.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 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());
- 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 UsernamePrincipal usernamePrincipalFromSubject = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- connectionIdUsernameMap.put(connectionId, usernamePrincipalFromSubject.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/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java
deleted file mode 100644
index 89b74f939d..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
deleted file mode 100644
index 651372db16..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java b/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java
deleted file mode 100644
index 166a2a376d..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/management/Managable.java
+++ /dev/null
@@ -1,34 +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;
-
-/**
- * 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
-{
- ManagedObject getManagedObject();
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java
deleted file mode 100644
index 483b325455..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java
deleted file mode 100644
index b3323c569c..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
deleted file mode 100644
index e77350c3e4..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java
+++ /dev/null
@@ -1,58 +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 javax.management.JMException;
-
-/**
- * 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
-{
- 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()
- {
-
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java b/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
index faac14f8a7..63bd1e45a0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageHeader.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
index e87b67d242..01c1021070 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index 583f0c09a7..e890bf5ef8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
index 7d030fe711..2cc1a92853 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
index 126e7c28cb..91384f7c22 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java b/java/broker/src/main/java/org/apache/qpid/server/model/Attribute.java
new file mode 100644
index 0000000000..4fccf47e0e
--- /dev/null
+++ b/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/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStoreFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java
index 44070f22ad..7a5927a365 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStoreFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationMethod.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -17,21 +18,16 @@
* under the License.
*
*/
-package org.apache.qpid.server.store;
+package org.apache.qpid.server.model;
-public class TestableMemoryMessageStoreFactory implements MessageStoreFactory
-{
+import java.util.Collection;
- @Override
- public MessageStore createMessageStore()
- {
- return new TestableMemoryMessageStore();
- }
+public interface AuthenticationMethod extends ConfiguredObject
+{
+ // name is the SASL mech where this is a SASL authentication
- @Override
- public String getStoreClassName()
- {
- return TestableMemoryMessageStore.class.getSimpleName();
- }
+ // parents
+ VirtualHostAlias getVirtualHostAlias();
+ AuthenticationProvider getAuthenticationProvider();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java
new file mode 100644
index 0000000000..6000886956
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
new file mode 100644
index 0000000000..08b01a1b65
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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 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,
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java
index 6477633a9b..78b98faffe 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
index fb47a54d0a..414b2d083a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
new file mode 100644
index 0000000000..6a7d6f8f7b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.Collection;
+
+public class ConfiguredObjectFinder
+{
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java b/java/broker/src/main/java/org/apache/qpid/server/model/Connection.java
new file mode 100644
index 0000000000..aaf6007afd
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/Event.java
index a35db62b03..91b684f06e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/Event.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -17,11 +18,10 @@
* under the License.
*
*/
-package org.apache.qpid.server.store;
-public interface MessageStoreFactory
-{
- MessageStore createMessageStore();
+package org.apache.qpid.server.model;
- String getStoreClassName();
+abstract public class Event<T extends EventType>
+{
+ abstract public T getEventType();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java b/java/broker/src/main/java/org/apache/qpid/server/model/EventType.java
new file mode 100644
index 0000000000..edd5ce4250
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java
index e872273d05..e63c71e955 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/java/broker/src/main/java/org/apache/qpid/server/model/Model.java
new file mode 100644
index 0000000000..fd429321c8
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/PasswordCredentialManagingAuthenticationProvider.java
new file mode 100644
index 0000000000..1027e5ce8c
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Port.java b/java/broker/src/main/java/org/apache/qpid/server/model/Port.java
new file mode 100644
index 0000000000..50c0ebcd14
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java
new file mode 100644
index 0000000000..5d9de69f9a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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,
+ HTTPS
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java b/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java
index 7c4f0de22b..bf703e6fbe 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/Queue.java
+++ b/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";
@@ -98,7 +99,7 @@ public interface Queue extends ConfiguredObject
public static final String QUEUE_FLOW_STOPPED = "queueFlowStopped";
public static final String SORT_KEY = "sortKey";
public static final String TYPE = "type";
-
+ public static final String PRIORITIES = "priorities";
@@ -106,6 +107,7 @@ public interface Queue extends ConfiguredObject
Collections.unmodifiableList(
Arrays.asList(ID,
NAME,
+ DESCRIPTION,
STATE,
DURABLE,
LIFETIME_POLICY,
@@ -130,7 +132,8 @@ public interface Queue extends ConfiguredObject
ALERT_THRESHOLD_MESSAGE_SIZE,
ALERT_THRESHOLD_QUEUE_DEPTH_BYTES,
ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES,
- ALERT_REPEAT_GAP
+ ALERT_REPEAT_GAP,
+ PRIORITIES
));
//children
@@ -143,4 +146,6 @@ public interface Queue extends ConfiguredObject
void visit(QueueEntryVisitor visitor);
void delete();
+
+ void setNotificationListener(QueueNotificationListener listener);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java b/java/broker/src/main/java/org/apache/qpid/server/model/QueueNotificationListener.java
index 959ca03c80..ab601f685c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/QueueType.java b/java/broker/src/main/java/org/apache/qpid/server/model/QueueType.java
new file mode 100644
index 0000000000..96f2a7e2e5
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/QueueType.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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 QueueType
+{
+ STANDARD,
+ PRIORITY,
+ LVQ,
+ SORTED
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Session.java b/java/broker/src/main/java/org/apache/qpid/server/model/Session.java
new file mode 100644
index 0000000000..e813d0c129
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java b/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java
index 2cb81eae82..92d6f47741 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java b/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java
new file mode 100644
index 0000000000..03cd46be01
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
index d8493c6df4..36b6a454dc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java
@@ -22,33 +22,59 @@ package org.apache.qpid.server.model;
import java.util.UUID;
-import org.apache.qpid.exchange.ExchangeDefaults;
-
-
public class UUIDGenerator
{
-
- public static UUID generateUUID()
+ //Generates a random UUID. Used primarily by tests.
+ public static UUID generateRandomUUID()
{
return UUID.randomUUID();
}
- public static UUID generateUUID(String objectName, String virtualHostName)
+ private static UUID createUUID(String objectType, String... names)
{
StringBuilder sb = new StringBuilder();
- sb.append(virtualHostName).append(objectName);
+ sb.append(objectType);
+
+ for(String name : names)
+ {
+ sb.append("/").append(name);
+ }
+
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."))
- {
- return generateUUID(echangeName, virtualHostName);
- }
- else
- {
- return generateUUID();
- }
+ return createUUID(Exchange.class.getName(), virtualHostName, exchangeName);
+ }
+
+ public static UUID generateQueueUUID(String queueName, String virtualHostName)
+ {
+ return createUUID(Queue.class.getName(), virtualHostName, queueName);
+ }
+
+ public static UUID generateBindingUUID(String exchangeName, String queueName, String bindingKey, String virtualHostName)
+ {
+ return createUUID(Binding.class.getName(), virtualHostName, exchangeName, queueName, bindingKey);
+ }
+
+ public static UUID generateUserUUID(String authenticationProviderName, String userName)
+ {
+ return createUUID(User.class.getName(), authenticationProviderName, userName);
+ }
+
+ public static UUID generateVhostUUID(String virtualHostName)
+ {
+ return createUUID(VirtualHost.class.getName(), virtualHostName);
+ }
+
+ public static UUID generateVhostAliasUUID(String virtualHostName, String portName)
+ {
+ return createUUID(VirtualHostAlias.class.getName(), virtualHostName, portName);
+ }
+
+ public static UUID generateConsumerUUID(String virtualHostName, String queueName, String connectionRemoteAddress, String channelNumber, String consumerName)
+ {
+ return createUUID(Consumer.class.getName(), virtualHostName, queueName, connectionRemoteAddress, channelNumber, consumerName);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/User.java b/java/broker/src/main/java/org/apache/qpid/server/model/User.java
new file mode 100644
index 0000000000..d97bf46d31
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
new file mode 100644
index 0000000000..24a3d43386
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java
@@ -0,0 +1,152 @@
+/*
+ *
+ * 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;
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHostAlias.java
new file mode 100644
index 0000000000..31403d78e5
--- /dev/null
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
new file mode 100644
index 0000000000..7d6aa9b2cb
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
@@ -0,0 +1,283 @@
+/*
+ *
+ * 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(UUID id)
+ {
+ _id = id;
+ }
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
new file mode 100644
index 0000000000..8c2bc98ba7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
@@ -0,0 +1,488 @@
+/*
+ *
+ * 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)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _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(UUIDGenerator.generateUserUUID(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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
new file mode 100644
index 0000000000..abd3160686
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java
@@ -0,0 +1,232 @@
+/*
+ *
+ * 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.IllegalStateTransitionException;
+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(binding.getId());
+ _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;
+ }
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
new file mode 100644
index 0000000000..f1cce2d45c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -0,0 +1,494 @@
+/*
+ *
+ * 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.List;
+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.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.UUIDGenerator;
+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 Collection<HTTPPortAdapter> _httpManagementPorts;
+
+ private final Map<AuthenticationManager, AuthenticationProviderAdapter> _authManagerAdapters =
+ new HashMap<AuthenticationManager, AuthenticationProviderAdapter>();
+
+
+ public BrokerAdapter(final IApplicationRegistry instance)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _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() || _applicationRegistry.useHTTPSManagement())
+ {
+ ArrayList<HTTPPortAdapter> httpPorts = new ArrayList<HTTPPortAdapter>();
+ if (_applicationRegistry.useHTTPManagement())
+ {
+ httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPManagementPort()));
+ }
+ if (_applicationRegistry.useHTTPSManagement())
+ {
+ httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPSManagementPort(), Protocol.HTTPS, Transport.SSL));
+ }
+ _httpManagementPorts = Collections.unmodifiableCollection(httpPorts);
+ }
+ }
+ }
+
+ public Collection<Port> getPorts()
+ {
+ synchronized (_portAdapters)
+ {
+ final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values());
+ if(_httpManagementPorts != null)
+ {
+ ports.addAll(_httpManagementPorts);
+ }
+ 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(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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
new file mode 100644
index 0000000000..5439f6a560
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java
@@ -0,0 +1,313 @@
+/*
+ *
+ * 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.model.UUIDGenerator;
+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)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java
new file mode 100644
index 0000000000..031d518670
--- /dev/null
+++ b/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.model.UUIDGenerator;
+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(UUIDGenerator.generateConsumerUUID(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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
new file mode 100644
index 0000000000..df0f29fbc3
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java
@@ -0,0 +1,437 @@
+/*
+ *
+ * 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.protocol.AMQConstant;
+import org.apache.qpid.server.binding.Binding;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeType;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+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.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(exchange.getId());
+ _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)))
+ {
+ virtualHost.getBindingFactory().replaceBinding(oldBinding.getId(), 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
+ {
+ ExchangeRegistry exchangeRegistry = _vhost.getVirtualHost().getExchangeRegistry();
+ if (exchangeRegistry.isReservedExchangeName(getName()))
+ {
+ throw new UnsupportedOperationException("'" + getName() + "' is a reserved exchange and can't be deleted");
+ }
+
+ if(_exchange.hasReferrers())
+ {
+ throw new AMQException( AMQConstant.NOT_ALLOWED, "Exchange in use as an alternate exchange", null);
+ }
+
+ synchronized(exchangeRegistry)
+ {
+ exchangeRegistry.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;
+ }
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
new file mode 100644
index 0000000000..823d27160b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
@@ -0,0 +1,273 @@
+/*
+ *
+ * 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.UUIDGenerator;
+import org.apache.qpid.server.model.VirtualHostAlias;
+
+public class HTTPPortAdapter extends AbstractAdapter implements Port
+{
+ private final BrokerAdapter _broker;
+ private final int _port;
+ private final Protocol _protocol;
+ private final Transport _transport;
+
+ public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port)
+ {
+ this(brokerAdapter, port, Protocol.HTTP, Transport.TCP);
+ }
+
+ public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port, Protocol protocol, Transport transport)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _broker = brokerAdapter;
+ _port = port;
+ _protocol = protocol;
+ _transport = transport;
+ }
+
+ @Override
+ public String getBindingAddress()
+ {
+ return "0.0.0.0";
+ }
+
+ @Override
+ public int getPort()
+ {
+ return _port;
+ }
+
+ @Override
+ public Collection<Transport> getTransports()
+ {
+ return Collections.singleton(_transport);
+ }
+
+ @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);
+ }
+
+ @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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.java
new file mode 100644
index 0000000000..03fdbd1e85
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/NoStatistics.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.adapter;
+
+import org.apache.qpid.server.model.Statistics;
+
+import java.util.Collection;
+import java.util.Collections;
+
+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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
new file mode 100644
index 0000000000..7653fcc9b9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
@@ -0,0 +1,320 @@
+/*
+ *
+ * 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.UUIDGenerator;
+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)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
new file mode 100644
index 0000000000..78f6d38d93
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java
@@ -0,0 +1,726 @@
+/*
+ *
+ * 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.IllegalStateTransitionException;
+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-age");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, "x-qpid-maximum-message-size");
+ 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, AMQQueueFactory.QPID_QUEUE_SORT_KEY);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.LVQ_KEY, AMQQueueFactory.QPID_LAST_VALUE_QUEUE_KEY);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.PRIORITIES, AMQQueueFactory.X_QPID_PRIORITIES);
+ }
+
+ 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(queue.getId());
+ _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
+ {
+ QueueRegistry queueRegistry = _queue.getVirtualHost().getQueueRegistry();
+ synchronized(queueRegistry)
+ {
+ _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();
+ }
+ else if(PRIORITIES.equals(name))
+ {
+ if(_queue instanceof AMQPriorityQueue)
+ {
+ return ((AMQPriorityQueue)_queue).getPriorities();
+ }
+ }
+ 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);
+ }
+ }
+
+ @Override
+ public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ delete();
+ return State.DELETED;
+ }
+ return super.setDesiredState(currentState, desiredState);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java
new file mode 100644
index 0000000000..d802697d67
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java
@@ -0,0 +1,240 @@
+/*
+ *
+ * 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.model.UUIDGenerator;
+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)
+ {
+ super(UUIDGenerator.generateRandomUUID());
+ _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))
+ {
+ return _session.getConsumerCount();
+ }
+ else if(name.equals(LOCAL_TRANSACTION_BEGINS))
+ {
+ return _session.getTxnStart();
+ }
+ else if(name.equals(LOCAL_TRANSACTION_OPEN))
+ {
+ long open = _session.getTxnStart() - (_session.getTxnCommits() + _session.getTxnRejects());
+ return (Boolean) (open > 0l);
+ }
+ else if(name.equals(LOCAL_TRANSACTION_ROLLBACKS))
+ {
+ return _session.getTxnRejects();
+ }
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java
new file mode 100644
index 0000000000..28c46a0339
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/StatisticsAdapter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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;
+
+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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
new file mode 100644
index 0000000000..35838e51d2
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
@@ -0,0 +1,892 @@
+/*
+ *
+ * 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.QueueType;
+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.getId());
+ _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
+ {
+ checkVHostStateIsActive();
+
+ try
+ {
+ ExchangeRegistry exchangeRegistry = _virtualHost.getExchangeRegistry();
+ if (exchangeRegistry.isReservedExchangeName(name))
+ {
+ throw new UnsupportedOperationException("'" + name + "' is a reserved exchange name");
+ }
+ synchronized(exchangeRegistry)
+ {
+ org.apache.qpid.server.exchange.Exchange exchange = exchangeRegistry.getExchange(name);
+ if (exchange != null)
+ {
+ throw new IllegalArgumentException("Exchange with name '" + name + "' already exists");
+ }
+ 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);
+
+ if (attributes.containsKey(Queue.TYPE))
+ {
+ String typeAttribute = getStringAttribute(Queue.TYPE, attributes, null);
+ QueueType queueType = null;
+ try
+ {
+ queueType = QueueType.valueOf(typeAttribute.toUpperCase());
+ }
+ catch(Exception e)
+ {
+ throw new IllegalArgumentException("Unsupported queue type :" + typeAttribute);
+ }
+ if (queueType == QueueType.LVQ && attributes.get(Queue.LVQ_KEY) == null)
+ {
+ attributes.put(Queue.LVQ_KEY, AMQQueueFactory.QPID_LVQ_KEY);
+ }
+ else if (queueType == QueueType.PRIORITY && attributes.get(Queue.PRIORITIES) == null)
+ {
+ attributes.put(Queue.PRIORITIES, 10);
+ }
+ else if (queueType == QueueType.SORTED && attributes.get(Queue.SORT_KEY) == null)
+ {
+ throw new IllegalArgumentException("Sort key is not specified for sorted queue");
+ }
+ }
+ 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
+ {
+ checkVHostStateIsActive();
+
+ String owner = null;
+ if(exclusive)
+ {
+ Set<Principal> principals =
+ SecurityManager.getThreadSubject().getPrincipals();
+ if(principals != null && !principals.isEmpty())
+ {
+ owner = principals.iterator().next().getName();
+ }
+ }
+ try
+ {
+ QueueRegistry queueRegistry = _virtualHost.getQueueRegistry();
+ synchronized (queueRegistry)
+ {
+ if(_virtualHost.getQueueRegistry().getQueue(name)!=null)
+ {
+ throw new IllegalArgumentException("Queue with name "+name+" already exists");
+ }
+ AMQQueue queue =
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateQueueUUID(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 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 void checkVHostStateIsActive()
+ {
+ if (!org.apache.qpid.server.virtualhost.State.ACTIVE.equals(_virtualHost.getState()))
+ {
+ throw new IllegalStateException("The virtual hosts state of " + _virtualHost.getState()
+ + " does not permit this operation.");
+ }
+ }
+
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java
new file mode 100644
index 0000000000..367d1ff518
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java
@@ -0,0 +1,143 @@
+/*
+ *
+ * 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.UUIDGenerator;
+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(UUIDGenerator.generateVhostAliasUUID(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/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java
index cfdcf7fb43..a68ac5439c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.output;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.output;
* under the License.
*
*/
+package org.apache.qpid.server.output;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQBody;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
index badeffca05..6479546355 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
+++ b/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,41 +58,66 @@ 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.server.ssl=7.6.3
+org.eclipse.jetty.server.nio=7.6.3
+org.eclipse.jetty.servlet=7.6.3
+org.eclipse.jetty.util.ssl=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.log4j=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
org.apache.qpid.server.queue=0.0.0
+org.apache.qpid.server.subscription=0.0.0
org.apache.qpid.server.registry=0.0.0
org.apache.qpid.server.security=0.0.0
org.apache.qpid.server.security.access=0.0.0
@@ -88,7 +125,11 @@ 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/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
index 407ce57ad6..74abbccd2b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
@@ -18,17 +18,20 @@
*/
package org.apache.qpid.server.plugins;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.felix.framework.Felix;
import org.apache.felix.framework.util.StringMap;
import org.apache.log4j.Logger;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.framework.launch.Framework;
-import org.osgi.util.tracker.ServiceTracker;
-
import org.apache.qpid.common.Closeable;
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.server.configuration.TopicConfiguration;
@@ -40,24 +43,23 @@ import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.SecurityPluginFactory;
import org.apache.qpid.server.security.access.plugins.LegacyAccess;
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager;
import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
import org.apache.qpid.server.virtualhost.plugins.policies.TopicDeletePolicy;
import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory;
import org.apache.qpid.util.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+import org.osgi.framework.launch.Framework;
+import org.osgi.util.tracker.ServiceTracker;
import static org.apache.felix.framework.util.FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP;
import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY;
@@ -100,18 +102,18 @@ public class PluginManager implements Closeable
/** The default name of the OSGI system package list. */
private static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/server/plugins/OsgiSystemPackages.properties";
-
+
/** The name of the override system property that holds the name of the OSGI system package list. */
private static final String FILE_PROPERTY = "qpid.osgisystempackages.properties";
-
+
private static final String OSGI_SYSTEM_PACKAGES;
-
- static
+
+ static
{
final String filename = System.getProperty(FILE_PROPERTY);
final InputStream is = FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
PluginManager.class.getClassLoader());
-
+
try
{
Version qpidReleaseVersion;
@@ -123,14 +125,14 @@ public class PluginManager implements Closeable
{
qpidReleaseVersion = null;
}
-
+
final Properties p = new Properties();
p.load(is);
-
+
final OsgiSystemPackageUtil osgiSystemPackageUtil = new OsgiSystemPackageUtil(qpidReleaseVersion, (Map)p);
-
+
OSGI_SYSTEM_PACKAGES = osgiSystemPackageUtil.getFormattedSystemPackageString();
-
+
_logger.debug("List of OSGi system packages to be added: " + OSGI_SYSTEM_PACKAGES);
}
catch (IOException e)
@@ -139,8 +141,8 @@ public class PluginManager implements Closeable
throw new ExceptionInInitializerError(e);
}
}
-
-
+
+
public PluginManager(String pluginPath, String cachePath, BundleContext bundleContext) throws Exception
{
// Store all non-OSGi plugins
@@ -156,7 +158,12 @@ public class PluginManager implements Closeable
new SlowConsumerDetectionConfigurationFactory(),
new SlowConsumerDetectionPolicyConfigurationFactory(),
new SlowConsumerDetectionQueueConfigurationFactory(),
- PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY))
+ PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY,
+ AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY,
+ KerberosAuthenticationManager.KerberosAuthenticationManagerConfiguration.FACTORY,
+ SimpleLDAPAuthenticationManager.SimpleLDAPAuthenticationManagerConfiguration.FACTORY,
+ ExternalAuthenticationManager.ExternalAuthenticationManagerConfiguration.FACTORY
+ ))
{
_configPlugins.put(configFactory.getParentPaths(), configFactory);
}
@@ -172,7 +179,9 @@ public class PluginManager implements Closeable
}
for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList(
- PrincipalDatabaseAuthenticationManager.FACTORY))
+ PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY,
+ KerberosAuthenticationManager.FACTORY, SimpleLDAPAuthenticationManager.FACTORY,
+ ExternalAuthenticationManager.FACTORY))
{
_authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory);
}
@@ -265,7 +274,7 @@ public class PluginManager implements Closeable
_virtualHostTracker = new ServiceTracker(bundleContext, VirtualHostPluginFactory.class.getName(), null);
_virtualHostTracker.open();
_trackers.add(_virtualHostTracker);
-
+
_policyTracker = new ServiceTracker(bundleContext, SlowConsumerPolicyPluginFactory.class.getName(), null);
_policyTracker.open();
_trackers.add(_policyTracker);
@@ -278,9 +287,9 @@ public class PluginManager implements Closeable
}
private static <T> Map<String, T> getServices(ServiceTracker tracker)
- {
+ {
Map<String, T> services = new HashMap<String, T>();
-
+
if ((tracker != null) && (tracker.getServices() != null))
{
for (Object service : tracker.getServices())
@@ -300,16 +309,16 @@ public class PluginManager implements Closeable
}
public static <T> Map<String, T> getServices(ServiceTracker tracker, Map<String, T> plugins)
- {
+ {
Map<String, T> services = getServices(tracker);
services.putAll(plugins);
return services;
}
public Map<List<String>, ConfigurationPluginFactory> getConfigurationPlugins()
- {
+ {
Map<List<String>, ConfigurationPluginFactory> services = new IdentityHashMap<List<String>, ConfigurationPluginFactory>();
-
+
if (_configTracker != null && _configTracker.getServices() != null)
{
for (Object service : _configTracker.getServices())
@@ -318,19 +327,19 @@ public class PluginManager implements Closeable
services.put(factory.getParentPaths(), factory);
}
}
-
+
services.putAll(_configPlugins);
return services;
}
public Map<String, VirtualHostPluginFactory> getVirtualHostPlugins()
- {
+ {
return getServices(_virtualHostTracker, _vhostPlugins);
}
public Map<String, SlowConsumerPolicyPluginFactory> getSlowConsumerPlugins()
- {
+ {
return getServices(_policyTracker, _policyPlugins);
}
@@ -338,7 +347,7 @@ public class PluginManager implements Closeable
{
return getServices(_exchangeTracker);
}
-
+
public Map<String, SecurityPluginFactory> getSecurityPlugins()
{
return getServices(_securityTracker, _securityPlugins);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
index 5af3899890..36fafba1cd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
@@ -31,24 +31,21 @@ import java.util.UUID;
public interface AMQConnectionModel extends StatisticsGatherer
{
/**
- * get a unique id for this connection.
- *
- * @return a {@link UUID} representing the connection
- */
- public UUID getId();
-
- /**
* Close the underlying Connection
- *
+ *
* @param cause
* @param message
* @throws org.apache.qpid.AMQException
*/
public void close(AMQConstant cause, String message) throws AMQException;
+ public void block();
+
+ public void unblock();
+
/**
* Close the given requested Session
- *
+ *
* @param session
* @param cause
* @param message
@@ -57,10 +54,10 @@ public interface AMQConnectionModel extends StatisticsGatherer
public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException;
public long getConnectionId();
-
+
/**
* Get a list of all sessions using this connection.
- *
+ *
* @return a list of {@link AMQSessionModel}s
*/
public List<AMQSessionModel> getSessionModels();
@@ -73,4 +70,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/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index b750b29952..1e649c3cb7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -20,8 +20,26 @@
*/
package org.apache.qpid.server.protocol;
-import org.apache.log4j.Logger;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.security.auth.Subject;
+import javax.security.sasl.SaslServer;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
@@ -46,13 +64,10 @@ 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;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.stats.StatisticsCounter;
@@ -66,25 +81,7 @@ import org.apache.qpid.transport.TransportException;
import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.util.BytesDataOutput;
-import javax.management.JMException;
-import javax.security.auth.Subject;
-import javax.security.sasl.SaslServer;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
+public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession, ConnectionConfig
{
private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class);
@@ -109,8 +106,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private AMQCodecFactory _codecFactory;
- private AMQProtocolSessionMBean _managedObject;
-
private SaslServer _saslServer;
private Object _lastReceived;
@@ -147,12 +142,10 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private long _maxFrameSize;
private final AtomicBoolean _closing = new AtomicBoolean(false);
- private final UUID _id;
+ private final UUID _qmfId;
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;
@@ -160,14 +153,13 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
private volatile boolean _deferFlush;
private long _lastReceivedTime;
+ private boolean _blocking;
- public ManagedObject getManagedObject()
- {
- return _managedObject;
- }
+ private final Lock _receivedLock;
public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network, final long connectionId)
{
+ _receivedLock = new ReentrantLock();
_stateManager = new AMQStateManager(virtualHostRegistry, this);
_codecFactory = new AMQCodecFactory(true, this);
@@ -179,12 +171,12 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_logSubject = new ConnectionLogSubject(this);
_configStore = virtualHostRegistry.getConfigStore();
- _id = _configStore.createId();
+ _qmfId = _configStore.createId();
_actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false));
- _registry = virtualHostRegistry.getApplicationRegistry();
initialiseStatistics();
+
}
public void setNetworkConnection(NetworkConnection network)
@@ -198,11 +190,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_sender = sender;
}
- private AMQProtocolSessionMBean createMBean() throws JMException
- {
- return new AMQProtocolSessionMBean(this);
- }
-
public long getSessionID()
{
return _connectionID;
@@ -244,6 +231,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
final long arrivalTime = System.currentTimeMillis();
_lastReceivedTime = arrivalTime;
_lastIoTime = arrivalTime;
+
+ _receivedLock.lock();
try
{
final ArrayList<AMQDataBlock> dataBlocks = _codecFactory.getDecoder().decodeBuffer(msg);
@@ -268,6 +257,10 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
_logger.error("Unexpected exception when processing datablock", e);
closeProtocolSession();
}
+ finally
+ {
+ _receivedLock.unlock();
+ }
}
private void receiveComplete()
@@ -374,7 +367,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
// This sets the protocol version (and hence framing classes) for this session.
setProtocolVersion(pv);
- String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager().getMechanisms();
+ String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager(getLocalAddress()).getMechanisms();
String locales = "en_US";
@@ -576,7 +569,10 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
public List<AMQChannel> getChannels()
{
- return new ArrayList<AMQChannel>(_channelMap.values());
+ synchronized (_channelMap)
+ {
+ return new ArrayList<AMQChannel>(_channelMap.values());
+ }
}
public AMQChannel getAndAssertChannel(int channelId) throws AMQException
@@ -633,24 +629,21 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
}
else
{
- _channelMap.put(channel.getChannelId(), channel);
+ synchronized (_channelMap)
+ {
+ _channelMap.put(channel.getChannelId(), channel);
+
+ if(_blocking)
+ {
+ channel.block();
+ }
+ }
}
if (((channelId & CHANNEL_CACHE_SIZE) == channelId))
{
_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()
@@ -735,10 +728,14 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
*/
public void removeChannel(int channelId)
{
- _channelMap.remove(channelId);
- if ((channelId & CHANNEL_CACHE_SIZE) == channelId)
+ synchronized (_channelMap)
{
- _cachedChannels[channelId] = null;
+ _channelMap.remove(channelId);
+
+ if ((channelId & CHANNEL_CACHE_SIZE) == channelId)
+ {
+ _cachedChannels[channelId] = null;
+ }
}
}
@@ -763,12 +760,14 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
*/
private void closeAllChannels() throws AMQException
{
- for (AMQChannel channel : _channelMap.values())
+ for (AMQChannel channel : getChannels())
{
channel.close();
}
-
- _channelMap.clear();
+ synchronized (_channelMap)
+ {
+ _channelMap.clear();
+ }
for (int i = 0; i <= CHANNEL_CACHE_SIZE; i++)
{
_cachedChannels[i] = null;
@@ -780,6 +779,9 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
{
if(_closing.compareAndSet(false,true))
{
+ // force sync of outstanding async work
+ receiveComplete();
+
// REMOVE THIS SHOULD NOT BE HERE.
if (CurrentActor.get() == null)
{
@@ -796,13 +798,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);
@@ -835,7 +830,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
}
}
- public void closeConnection(int channelId, AMQConnectionException e) throws AMQException
+ private void closeConnection(int channelId, AMQConnectionException e) throws AMQException
{
try
{
@@ -846,12 +841,18 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
markChannelAwaitingCloseOk(channelId);
closeSession();
- _stateManager.changeState(AMQState.CONNECTION_CLOSING);
- writeFrame(e.getCloseFrame(channelId));
}
finally
{
- closeProtocolSession();
+ try
+ {
+ _stateManager.changeState(AMQState.CONNECTION_CLOSING);
+ writeFrame(e.getCloseFrame(channelId));
+ }
+ finally
+ {
+ closeProtocolSession();
+ }
}
@@ -983,16 +984,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)
@@ -1026,7 +1017,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
public Principal getAuthorizedPrincipal()
{
- return _authorizedSubject == null ? null : UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
+ return _authorizedSubject == null ? null : _authorizedSubject.getPrincipals().iterator().next();
}
public SocketAddress getRemoteAddress()
@@ -1039,6 +1030,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
return _network.getLocalAddress();
}
+ public Principal getPeerPrincipal()
+ {
+ return _network.getPeerPrincipal();
+ }
+
public MethodRegistry getMethodRegistry()
{
return _methodRegistry;
@@ -1144,6 +1140,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;
@@ -1199,9 +1205,10 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
return false;
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public long getConnectionId()
@@ -1337,6 +1344,36 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
(Throwable) null));
}
+ public void block()
+ {
+ synchronized (_channelMap)
+ {
+ if(!_blocking)
+ {
+ _blocking = true;
+ for(AMQChannel channel : _channelMap.values())
+ {
+ channel.block();
+ }
+ }
+ }
+ }
+
+ public void unblock()
+ {
+ synchronized (_channelMap)
+ {
+ if(_blocking)
+ {
+ _blocking = false;
+ for(AMQChannel channel : _channelMap.values())
+ {
+ channel.unblock();
+ }
+ }
+ }
+ }
+
public boolean isClosed()
{
return _closed;
@@ -1344,12 +1381,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()
@@ -1359,21 +1391,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);
}
@@ -1407,29 +1433,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)
@@ -1466,4 +1489,9 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr
{
return _reference;
}
+
+ public Lock getReceivedLock()
+ {
+ return _receivedLock;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
index 6cd5b21f89..ba806c04bd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
@@ -20,12 +20,14 @@
*/
package org.apache.qpid.server.protocol;
+import java.net.SocketAddress;
+import java.security.Principal;
import java.util.List;
+import java.util.concurrent.locks.Lock;
import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
-import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -60,6 +62,13 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
long getLastReceivedTime();
+ /**
+ * Return the local socket address for the connection
+ *
+ * @return the socket address
+ */
+ SocketAddress getLocalAddress();
+
public static interface Task
{
public void doTask(AMQProtocolSession session) throws AMQException;
@@ -145,10 +154,6 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
void closeProtocolSession();
- /** This must be called to close the session in order to free up any resources managed by the session. */
- void closeConnection(int channelId, AMQConnectionException e) throws AMQException;
-
-
/** @return a key that uniquely identifies this session */
Object getKey();
@@ -210,4 +215,7 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
void mgmtCloseChannel(int channelId);
+ public Principal getPeerPrincipal();
+
+ Lock getReceivedLock();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
deleted file mode 100644
index e70720600e..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
index fa171815ca..a8f62b0fa2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
@@ -37,26 +37,26 @@ import org.apache.qpid.server.queue.SimpleAMQQueue;
public interface AMQSessionModel extends Comparable<AMQSessionModel>
{
/** Unique session ID across entire broker*/
- public UUID getId();
+ public UUID getQMFId();
public AMQConnectionModel getConnectionModel();
public String getClientID();
-
+
public void close() throws AMQException;
public LogSubject getLogSubject();
-
+
/**
* This method is called from the housekeeping thread to check the status of
* transactions on this session and react appropriately.
- *
+ *
* If a transaction is open for too long or idle for too long then a warning
* 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.
- *
+ * from the time the transaction was started. An idle transaction is one that
+ * 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
* @param idleWarn time in milliseconds before alerting on idle transaction
@@ -68,6 +68,22 @@ public interface AMQSessionModel extends Comparable<AMQSessionModel>
void unblock(AMQQueue queue);
+ void block();
+
+ void unblock();
+
+ boolean getBlocking();
boolean onSameConnection(InboundMessage inbound);
+
+ int getUnacknowledgedMessageCount();
+
+ Long getTxnCount();
+ Long getTxnStart();
+ Long getTxnCommits();
+ Long getTxnRejects();
+
+ int getChannelId();
+
+ int getConsumerCount();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
index 652ffee004..5c92aa95b6 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
@@ -302,7 +302,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
final ConnectionDelegate connDelegate =
- new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn);
+ new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn, _appRegistry.getAuthenticationManager(getLocalAddress()));
ServerConnection conn = new ServerConnection(_id);
conn.setConnectionDelegate(connDelegate);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
index 182ef1ed82..fd6e9300ec 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
@@ -47,7 +47,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
private long _readBytes;
private long _writtenBytes;
private ServerConnection _connection;
- private final UUID _id;
+ private final UUID _qmfId;
private final IApplicationRegistry _appRegistry;
private long _createTime = System.currentTimeMillis();
@@ -59,7 +59,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
_connection = conn;
_connection.setConnectionConfig(this);
- _id = appRegistry.getConfigStore().createId();
+ _qmfId = appRegistry.getConfigStore().createId();
_appRegistry = appRegistry;
if(network != null)
@@ -88,7 +88,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
_network = network;
_connection.setSender(new Disassembler(sender, MAX_FRAME_SIZE));
-
+ _connection.setPeerPrincipal(_network.getPeerPrincipal());
// FIXME Two log messages to maintain compatibility with earlier protocol versions
_connection.getLogActor().message(ConnectionMessages.OPEN(null, null, null, false, false, false));
_connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", null, false, true, false));
@@ -180,9 +180,10 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
return _appRegistry.getConfigStore();
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public ConnectionConfigType getConfigType()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java
index f31ad5052b..e6282315c6 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java
@@ -26,12 +26,13 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import org.apache.qpid.amqp_1_0.codec.FrameWriter;
import org.apache.qpid.amqp_1_0.framing.AMQFrame;
import org.apache.qpid.amqp_1_0.framing.FrameHandler;
import org.apache.qpid.amqp_1_0.framing.OversizeFrameException;
-import org.apache.qpid.amqp_1_0.transport.CallbackHandlerSource;
+import org.apache.qpid.amqp_1_0.transport.SaslServerProvider;
import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
import org.apache.qpid.amqp_1_0.transport.Container;
import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler;
@@ -95,7 +96,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
}
private State _state = State.A;
-
+
public ProtocolEngine_1_0_0(final IApplicationRegistry appRegistry, long id)
@@ -143,8 +144,9 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
Container container = new Container(_appRegistry.getBrokerId().toString());
- _conn = new ConnectionEndpoint(container,asCallbackHandlerSource(_appRegistry.getAuthenticationManager()));
- _conn.setConnectionEventListener(new Connection_1_0(_appRegistry));
+ _conn = new ConnectionEndpoint(container, asSaslServerProvider(_appRegistry.getAuthenticationManager(
+ getLocalAddress())));
+ _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId));
_conn.setFrameOutputHandler(this);
_conn.setRemoteAddress(_network.getRemoteAddress());
@@ -155,14 +157,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
_sender.flush();
}
- private CallbackHandlerSource asCallbackHandlerSource(final AuthenticationManager authenticationManager)
+ private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager)
{
- return new CallbackHandlerSource()
+ return new SaslServerProvider()
{
@Override
- public CallbackHandler getHandler(String mechanism)
+ public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException
{
- return authenticationManager.getHandler(mechanism);
+ return authenticationManager.createSaslServer(mechanism, fqdn, null);
}
};
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java
index ffd5e750b4..a48441bf30 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java
@@ -26,13 +26,14 @@ import java.nio.ByteBuffer;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import org.apache.qpid.amqp_1_0.codec.FrameWriter;
import org.apache.qpid.amqp_1_0.codec.ProtocolHandler;
import org.apache.qpid.amqp_1_0.framing.AMQFrame;
import org.apache.qpid.amqp_1_0.framing.OversizeFrameException;
import org.apache.qpid.amqp_1_0.framing.SASLFrameHandler;
-import org.apache.qpid.amqp_1_0.transport.CallbackHandlerSource;
+import org.apache.qpid.amqp_1_0.transport.SaslServerProvider;
import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
import org.apache.qpid.amqp_1_0.transport.Container;
import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler;
@@ -57,7 +58,7 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
private long _createTime = System.currentTimeMillis();
private ConnectionEndpoint _conn;
private long _connectionId;
-
+
private static final ByteBuffer HEADER =
ByteBuffer.wrap(new byte[]
{
@@ -163,9 +164,9 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
Container container = new Container(_appRegistry.getBrokerId().toString());
- _conn = new ConnectionEndpoint(container, asCallbackHandlerSource(ApplicationRegistry.getInstance()
- .getAuthenticationManager()));
- _conn.setConnectionEventListener(new Connection_1_0(_appRegistry));
+ _conn = new ConnectionEndpoint(container, asSaslServerProvider(ApplicationRegistry.getInstance()
+ .getAuthenticationManager(getLocalAddress())));
+ _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId));
_conn.setRemoteAddress(getRemoteAddress());
@@ -200,14 +201,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
}
- private CallbackHandlerSource asCallbackHandlerSource(final AuthenticationManager authenticationManager)
+ private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager)
{
- return new CallbackHandlerSource()
+ return new SaslServerProvider()
{
@Override
- public CallbackHandler getHandler(String mechanism)
+ public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException
{
- return authenticationManager.getHandler(mechanism);
+ return authenticationManager.createSaslServer(mechanism, fqdn, null);
}
};
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java
index 318a240b27..f429d8ba9f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java
@@ -20,21 +20,35 @@
*/
package org.apache.qpid.server.protocol.v1_0;
+import java.text.MessageFormat;
+import java.util.Collection;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
import org.apache.qpid.amqp_1_0.transport.ConnectionEventListener;
import org.apache.qpid.amqp_1_0.transport.SessionEndpoint;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT;
+
public class Connection_1_0 implements ConnectionEventListener
{
private IApplicationRegistry _appRegistry;
private VirtualHost _vhost;
+ private final ConnectionEndpoint _conn;
+ private final long _connectionId;
+ private final Collection<Session_1_0> _sessions = Collections.synchronizedCollection(new ArrayList<Session_1_0>());
public static interface Task
@@ -48,18 +62,27 @@ public class Connection_1_0 implements ConnectionEventListener
- public Connection_1_0(IApplicationRegistry appRegistry)
+ public Connection_1_0(IApplicationRegistry appRegistry, ConnectionEndpoint conn, long connectionId)
{
_appRegistry = appRegistry;
_vhost = _appRegistry.getVirtualHostRegistry().getDefaultVirtualHost();
+ _conn = conn;
+ _connectionId = connectionId;
+ _vhost.getConnectionRegistry().registerConnection(_model);
+
}
public void remoteSessionCreation(SessionEndpoint endpoint)
{
Session_1_0 session = new Session_1_0(_vhost, _appRegistry, this);
+ _sessions.add(session);
endpoint.setSessionEventListener(session);
}
+ void sessionEnded(Session_1_0 session)
+ {
+ _sessions.remove(session);
+ }
void removeConnectionCloseTask(final Task task)
{
@@ -86,6 +109,8 @@ public class Connection_1_0 implements ConnectionEventListener
{
_closeTasks.clear();
}
+ _vhost.getConnectionRegistry().deregisterConnection(_model);
+
}
@@ -94,5 +119,174 @@ public class Connection_1_0 implements ConnectionEventListener
closeReceived();
}
+ private final AMQConnectionModel _model = new AMQConnectionModel()
+ {
+ private final StatisticsCounter _messageDeliveryStatistics = new StatisticsCounter();
+ private final StatisticsCounter _messageReceiptStatistics = new StatisticsCounter();
+ private final StatisticsCounter _dataDeliveryStatistics = new StatisticsCounter();
+ private final StatisticsCounter _dataReceiptStatistics = new StatisticsCounter();
+
+ private final LogSubject _logSubject = new LogSubject()
+ {
+ @Override
+ public String toLogString()
+ {
+ return "[" +
+ MessageFormat.format(CONNECTION_FORMAT,
+ getConnectionId(),
+ getClientId(),
+ getRemoteAddressString(),
+ _vhost.getName())
+ + "] ";
+
+ }
+ };
+
+ @Override
+ public void close(AMQConstant cause, String message) throws AMQException
+ {
+ // TODO
+ }
+
+ @Override
+ public void block()
+ {
+ // TODO
+ }
+
+ @Override
+ public void unblock()
+ {
+ // TODO
+ }
+
+ @Override
+ public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException
+ {
+ // TODO
+ }
+
+ @Override
+ public long getConnectionId()
+ {
+ return _connectionId;
+ }
+
+ @Override
+ public List<AMQSessionModel> getSessionModels()
+ {
+ return new ArrayList<AMQSessionModel>(_sessions);
+ }
+
+ @Override
+ public LogSubject getLogSubject()
+ {
+ return _logSubject;
+ }
+
+ @Override
+ public String getUserName()
+ {
+ return getPrincipalAsString();
+ }
+
+ @Override
+ public boolean isSessionNameUnique(byte[] name)
+ {
+ return true; // TODO
+ }
+
+ @Override
+ public String getRemoteAddressString()
+ {
+ return String.valueOf(_conn.getRemoteAddress());
+ }
+
+ @Override
+ public String getClientId()
+ {
+ return _conn.getRemoteContainerId();
+ }
+
+ @Override
+ public String getClientVersion()
+ {
+ return ""; //TODO
+ }
+
+ @Override
+ public String getPrincipalAsString()
+ {
+ return String.valueOf(_conn.getUser());
+ }
+
+ @Override
+ public long getSessionCountLimit()
+ {
+ return 0; // TODO
+ }
+
+ @Override
+ public long getLastIoTime()
+ {
+ return 0; // TODO
+ }
+
+ @Override
+ public void initialiseStatistics()
+ {
+ // TODO
+ }
+
+ @Override
+ public void registerMessageReceived(long messageSize, long timestamp)
+ {
+ // TODO
+ }
+
+ @Override
+ public void registerMessageDelivered(long messageSize)
+ {
+ // TODO
+ }
+
+ @Override
+ public StatisticsCounter getMessageDeliveryStatistics()
+ {
+ return _messageDeliveryStatistics;
+ }
+
+ @Override
+ public StatisticsCounter getMessageReceiptStatistics()
+ {
+ return _messageReceiptStatistics;
+ }
+
+ @Override
+ public StatisticsCounter getDataDeliveryStatistics()
+ {
+ return _dataDeliveryStatistics;
+ }
+
+ @Override
+ public StatisticsCounter getDataReceiptStatistics()
+ {
+ return _dataReceiptStatistics;
+ }
+
+ @Override
+ public void resetStatistics()
+ {
+ // TODO
+ }
+
+
+ };
+
+ AMQConnectionModel getModel()
+ {
+ return _model;
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java
index 42eea05d37..0bb9a15968 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.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.protocol.v1_0;
import java.util.HashMap;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java
index 6da5081185..46b9682c74 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.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.protocol.v1_0;
import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java
index 9d7af24135..09a2ddea3a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.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.protocol.v1_0;
import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
index b3e9a74d04..75235c7ef0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java
@@ -200,7 +200,7 @@ public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryS
if(queue == null)
{
queue = AMQQueueFactory.createAMQQueueImpl(
- UUIDGenerator.generateUUID(),
+ UUIDGenerator.generateQueueUUID(name, _vhost.getName()),
name,
isDurable,
null,
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
index 48a551e42a..999ffc55e5 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.protocol.v1_0;
+import java.text.MessageFormat;
import org.apache.qpid.amqp_1_0.transport.LinkEndpoint;
import org.apache.qpid.amqp_1_0.transport.ReceivingLinkEndpoint;
import org.apache.qpid.amqp_1_0.transport.SendingLinkEndpoint;
@@ -35,18 +36,26 @@ import org.apache.qpid.amqp_1_0.type.transport.*;
import org.apache.qpid.amqp_1_0.type.transport.Error;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
+import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.model.UUIDGenerator;
+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.AMQQueueFactory;
import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.*;
-public class Session_1_0 implements SessionEventListener
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
+
+public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSubject
{
private static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy");
private IApplicationRegistry _appRegistry;
@@ -56,6 +65,7 @@ public class Session_1_0 implements SessionEventListener
private final LinkedHashMap<Integer, ServerTransaction> _openTransactions =
new LinkedHashMap<Integer, ServerTransaction>();
private final Connection_1_0 _connection;
+ private UUID _id = UUID.randomUUID();
public Session_1_0(VirtualHost vhost, IApplicationRegistry appRegistry, final Connection_1_0 connection)
@@ -319,7 +329,7 @@ public class Session_1_0 implements SessionEventListener
? null
: (LifetimePolicy) properties.get(LIFETIME_POLICY);
- final AMQQueue tempQueue = queue = AMQQueueFactory.createAMQQueueImpl( UUIDGenerator.generateUUID(),
+ final AMQQueue tempQueue = queue = AMQQueueFactory.createAMQQueueImpl( UUIDGenerator.generateQueueUUID(queueName, _vhost.getName()),
queueName,
false, // durable
null, // owner
@@ -405,6 +415,8 @@ public class Session_1_0 implements SessionEventListener
iter.remove();
}
+ _connection.sessionEnded(this);
+
}
Integer binaryToInteger(final Binary txnId)
@@ -443,4 +455,153 @@ public class Session_1_0 implements SessionEventListener
public void forceEnd()
{
}
+
+ @Override
+ public UUID getQMFId()
+ {
+ return _id;
+ }
+
+ @Override
+ public AMQConnectionModel getConnectionModel()
+ {
+ return _connection.getModel();
+ }
+
+ @Override
+ public String getClientID()
+ {
+ // TODO
+ return "";
+ }
+
+ @Override
+ public void close() throws AMQException
+ {
+ // TODO - required for AMQSessionModel / management initiated closing
+ }
+
+ @Override
+ public LogSubject getLogSubject()
+ {
+ return this;
+ }
+
+ @Override
+ public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
+ {
+ // TODO - required for AMQSessionModel / long running transaction detection
+ }
+
+ @Override
+ public void block(AMQQueue queue)
+ {
+ // TODO - required for AMQSessionModel / producer side flow control
+ }
+
+ @Override
+ public void unblock(AMQQueue queue)
+ {
+ // TODO - required for AMQSessionModel / producer side flow control
+ }
+
+ @Override
+ public void block()
+ {
+ // TODO - required for AMQSessionModel / producer side flow control
+ }
+
+ @Override
+ public void unblock()
+ {
+ // TODO - required for AMQSessionModel / producer side flow control
+ }
+
+ @Override
+ public boolean getBlocking()
+ {
+ // TODO
+ return false;
+ }
+
+ @Override
+ public boolean onSameConnection(InboundMessage inbound)
+ {
+ // TODO
+ return false;
+ }
+
+ @Override
+ public int getUnacknowledgedMessageCount()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public Long getTxnCount()
+ {
+ // TODO
+ return 0l;
+ }
+
+ @Override
+ public Long getTxnStart()
+ {
+ // TODO
+ return 0l;
+ }
+
+ @Override
+ public Long getTxnCommits()
+ {
+ // TODO
+ return 0l;
+ }
+
+ @Override
+ public Long getTxnRejects()
+ {
+ // TODO
+ return 0l;
+ }
+
+ @Override
+ public int getChannelId()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public int getConsumerCount()
+ {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public int compareTo(AMQSessionModel o)
+ {
+ return getQMFId().compareTo(o.getQMFId());
+ }
+
+
+
+ public String toLogString()
+ {
+ long connectionId = getConnectionModel().getConnectionId();
+
+ String remoteAddress = getConnectionModel().getRemoteAddressString();
+
+ return "[" +
+ MessageFormat.format(CHANNEL_FORMAT,
+ connectionId,
+ getClientID(),
+ remoteAddress,
+ _vhost.getName(), // TODO - virtual host
+ 0) // TODO - channel)
+ + "] ";
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java
index 08926d000d..8a3d3716c7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java
+++ b/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;
@@ -66,7 +67,7 @@ class Subscription_1_0 implements Subscription
private final QueueEntry.SubscriptionAssignedState _assignedState = new QueueEntry.SubscriptionAssignedState(this);
private final long _id;
private final boolean _acquires;
- private AMQQueue.Context _queueContext;
+ private volatile AMQQueue.Context _queueContext;
private Map<String, Object> _properties = new ConcurrentHashMap<String, Object>();
private ReentrantLock _stateChangeLock = new ReentrantLock();
@@ -631,4 +632,46 @@ class Subscription_1_0 implements Subscription
{
_filters = filters;
}
+
+ @Override
+ public AMQSessionModel getSessionModel()
+ {
+ // TODO
+ return getSession();
+ }
+
+ @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/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java
index c497cc5146..0fee4086b4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.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.protocol.v1_0;
import org.apache.qpid.amqp_1_0.type.DeliveryState;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index e643338c3d..d3efd63ee0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
index f2b7d7c56b..3a18fae2ec 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
+++ b/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";
@@ -169,29 +171,7 @@ public class AMQQueueFactory
};
/**
- * Creates a new queue with a random id.
- *
- * @see #createAMQQueueImpl(UUID, String, boolean, String, boolean, boolean, VirtualHost, Map)
- * @deprecated because only called from unit tests
- * */
- @Deprecated
- public static AMQQueue createAMQQueueImpl(AMQShortString name,
- boolean durable,
- AMQShortString owner,
- boolean autoDelete,
- boolean exclusive,
- VirtualHost virtualHost, final FieldTable arguments) throws AMQException
- {
- return createAMQQueueImpl(UUIDGenerator.generateUUID(),
- name == null ? null : name.toString(),
- durable,
- owner == null ? null : owner.toString(),
- autoDelete,
- exclusive, virtualHost, FieldTable.convertToMap(arguments));
- }
-
- /**
- * @param id the id to use. If default then one is generated from queueName. TODO check correctness of calls that pass a null value.
+ * @param id the id to use.
*/
public static AMQQueue createAMQQueueImpl(UUID id,
String queueName,
@@ -300,7 +280,7 @@ public class AMQQueueFactory
if(dlExchange == null)
{
- dlExchange = exchangeFactory.createExchange(UUIDGenerator.generateUUID(dlExchangeName, virtualHost.getName()), new AMQShortString(dlExchangeName), ExchangeDefaults.FANOUT_EXCHANGE_CLASS, true, false, 0);
+ dlExchange = exchangeFactory.createExchange(UUIDGenerator.generateExchangeUUID(dlExchangeName, virtualHost.getName()), new AMQShortString(dlExchangeName), ExchangeDefaults.FANOUT_EXCHANGE_CLASS, true, false, 0);
exchangeRegistry.registerExchange(dlExchange);
@@ -322,7 +302,7 @@ public class AMQQueueFactory
args.put(X_QPID_DLQ_ENABLED, false);
args.put(X_QPID_MAXIMUM_DELIVERY_COUNT, 0);
- dlQueue = createAMQQueueImpl(UUIDGenerator.generateUUID(dlQueueName, virtualHost.getName()), dlQueueName, true, owner, false, exclusive, virtualHost, args);
+ dlQueue = createAMQQueueImpl(UUIDGenerator.generateQueueUUID(dlQueueName, virtualHost.getName()), dlQueueName, true, owner, false, exclusive, virtualHost, args);
//enter the dlq in the persistent store
virtualHost.getMessageStore().createQueue(dlQueue, FieldTable.convertToFieldTable(args));
@@ -350,42 +330,16 @@ 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());
+ UUID id = UUIDGenerator.generateQueueUUID(queueName, host.getName());
AMQQueue q = createAMQQueueImpl(id, queueName, durable, owner, autodelete, exclusive, host, arguments);
q.configure(config);
return q;
}
-
/**
* Validates DLQ and DLE names
* <p>
@@ -475,4 +429,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/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
deleted file mode 100644
index b0d4cb3486..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
index 6a2e4f155d..53420ded9b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java
@@ -24,17 +24,25 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Collections;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
public class ConflationQueueList extends SimpleQueueEntryList
{
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConflationQueueList.class);
private final String _conflationKey;
private final ConcurrentHashMap<Object, AtomicReference<QueueEntry>> _latestValuesMap =
new ConcurrentHashMap<Object, AtomicReference<QueueEntry>>();
+ private final QueueEntry _deleteInProgress = new SimpleQueueEntryImpl(this);
+ private final QueueEntry _newerEntryAlreadyBeenAndGone = new SimpleQueueEntryImpl(this);
+
public ConflationQueueList(AMQQueue queue, String conflationKey)
{
super(queue);
@@ -52,48 +60,98 @@ public class ConflationQueueList extends SimpleQueueEntryList
return new ConflationQueueEntry(this, message);
}
-
+ /**
+ * Updates the list using super.add and also updates {@link #_latestValuesMap} and discards entries as necessary.
+ */
@Override
public ConflationQueueEntry add(final ServerMessage message)
{
- ConflationQueueEntry entry = (ConflationQueueEntry) (super.add(message));
- AtomicReference<QueueEntry> latestValueReference = null;
+ final ConflationQueueEntry addedEntry = (ConflationQueueEntry) (super.add(message));
- Object value = message.getMessageHeader().getHeader(_conflationKey);
- if(value != null)
+ final Object keyValue = message.getMessageHeader().getHeader(_conflationKey);
+ if (keyValue != null)
{
- latestValueReference = _latestValuesMap.get(value);
- if(latestValueReference == null)
+ if(LOGGER.isDebugEnabled())
{
- _latestValuesMap.putIfAbsent(value, new AtomicReference<QueueEntry>(entry));
- latestValueReference = _latestValuesMap.get(value);
+ LOGGER.debug("Adding entry " + addedEntry + " for message " + message.getMessageNumber() + " with conflation key " + keyValue);
}
- QueueEntry oldEntry;
+ final AtomicReference<QueueEntry> referenceToEntry = new AtomicReference<QueueEntry>(addedEntry);
+ AtomicReference<QueueEntry> entryReferenceFromMap = null;
+ QueueEntry entryFromMap;
+
+ // Iterate until we have got a valid atomic reference object and either the referent is newer than the current
+ // entry, or the current entry has replaced it in the reference. Note that the _deletedEntryPlaceholder is a special value
+ // indicating that the reference object is no longer valid (it is being removed from the map).
+ boolean keepTryingToUpdateEntryReference = true;
do
{
- oldEntry = latestValueReference.get();
+ do
+ {
+ entryReferenceFromMap = getOrPutIfAbsent(keyValue, referenceToEntry);
+
+ // entryFromMap can be either an older entry, a newer entry (added recently by another thread), or addedEntry (if it's for a new key value)
+ entryFromMap = entryReferenceFromMap.get();
+ }
+ while(entryFromMap == _deleteInProgress);
+
+ boolean entryFromMapIsOlder = entryFromMap != _newerEntryAlreadyBeenAndGone && entryFromMap.compareTo(addedEntry) < 0;
+
+ keepTryingToUpdateEntryReference = entryFromMapIsOlder
+ && !entryReferenceFromMap.compareAndSet(entryFromMap, addedEntry);
}
- while(oldEntry.compareTo(entry) < 0 && !latestValueReference.compareAndSet(oldEntry, entry));
+ while(keepTryingToUpdateEntryReference);
- if(oldEntry.compareTo(entry) < 0)
+ if (entryFromMap == _newerEntryAlreadyBeenAndGone)
+ {
+ discardEntry(addedEntry);
+ }
+ else if (entryFromMap.compareTo(addedEntry) > 0)
{
- // We replaced some other entry to become the newest value
- if(oldEntry.acquire())
+ if(LOGGER.isDebugEnabled())
{
- discardEntry(oldEntry);
+ LOGGER.debug("New entry " + addedEntry.getEntryId() + " for message " + addedEntry.getMessage().getMessageNumber() + " being immediately discarded because a newer entry arrived. The newer entry is: " + entryFromMap + " for message " + entryFromMap.getMessage().getMessageNumber());
}
+ discardEntry(addedEntry);
}
- else if (oldEntry.compareTo(entry) > 0)
+ else if (entryFromMap.compareTo(addedEntry) < 0)
{
- // A newer entry came along
- discardEntry(entry);
-
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Entry " + addedEntry + " for message " + addedEntry.getMessage().getMessageNumber() + " replacing older entry " + entryFromMap + " for message " + entryFromMap.getMessage().getMessageNumber());
+ }
+ discardEntry(entryFromMap);
}
+
+ addedEntry.setLatestValueReference(entryReferenceFromMap);
}
- entry.setLatestValueReference(latestValueReference);
- return entry;
+ return addedEntry;
+ }
+
+ /**
+ * Returns:
+ *
+ * <ul>
+ * <li>the existing entry reference if the value already exists in the map, or</li>
+ * <li>referenceToValue if none exists, or</li>
+ * <li>a reference to {@link #_newerEntryAlreadyBeenAndGone} if another thread concurrently
+ * adds and removes during execution of this method.</li>
+ * </ul>
+ */
+ private AtomicReference<QueueEntry> getOrPutIfAbsent(final Object key, final AtomicReference<QueueEntry> referenceToAddedValue)
+ {
+ AtomicReference<QueueEntry> latestValueReference = _latestValuesMap.putIfAbsent(key, referenceToAddedValue);
+
+ if(latestValueReference == null)
+ {
+ latestValueReference = _latestValuesMap.get(key);
+ if(latestValueReference == null)
+ {
+ return new AtomicReference<QueueEntry>(_newerEntryAlreadyBeenAndGone);
+ }
+ }
+ return latestValueReference;
}
private void discardEntry(final QueueEntry entry)
@@ -104,11 +162,13 @@ public class ConflationQueueList extends SimpleQueueEntryList
txn.dequeue(entry.getQueue(),entry.getMessage(),
new ServerTransaction.Action()
{
+ @Override
public void postCommit()
{
entry.discard();
}
+ @Override
public void onRollback()
{
@@ -120,7 +180,6 @@ public class ConflationQueueList extends SimpleQueueEntryList
private final class ConflationQueueEntry extends SimpleQueueEntryImpl
{
-
private AtomicReference<QueueEntry> _latestValueReference;
public ConflationQueueEntry(SimpleQueueEntryList queueEntryList, ServerMessage message)
@@ -128,25 +187,56 @@ public class ConflationQueueList extends SimpleQueueEntryList
super(queueEntryList, message);
}
-
+ @Override
public void release()
{
super.release();
- if(_latestValueReference != null)
+ discardIfReleasedEntryIsNoLongerLatest();
+ }
+
+ @Override
+ public boolean delete()
+ {
+ if(super.delete())
{
- if(_latestValueReference.get() != this)
+ if(_latestValueReference != null && _latestValueReference.compareAndSet(this, _deleteInProgress))
{
- discardEntry(this);
+ Object key = getMessageHeader().getHeader(_conflationKey);
+ _latestValuesMap.remove(key,_latestValueReference);
}
+ return true;
+ }
+ else
+ {
+ return false;
}
-
}
public void setLatestValueReference(final AtomicReference<QueueEntry> latestValueReference)
{
_latestValueReference = latestValueReference;
}
+
+ private void discardIfReleasedEntryIsNoLongerLatest()
+ {
+ if(_latestValueReference != null)
+ {
+ if(_latestValueReference.get() != this)
+ {
+ discardEntry(this);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Exposed purposes of unit test only.
+ */
+ Map<Object, AtomicReference<QueueEntry>> getLatestValuesMap()
+ {
+ return Collections.unmodifiableMap(_latestValuesMap);
}
static class Factory implements QueueEntryListFactory
@@ -163,5 +253,4 @@ public class ConflationQueueList extends SimpleQueueEntryList
return new ConflationQueueList(queue, _conflationKey);
}
}
-
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
index 2493974d45..27a9e13617 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
index c1ebbe412f..3efef9ab98 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java b/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java
index 1d13ee66c0..66315af9fb 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java
@@ -37,7 +37,7 @@ public class PriorityQueueList implements QueueEntryList<SimpleQueueEntryImpl>
_priorityOffset = 5-((priorities + 1)/2);
for(int i = 0; i < priorities; i++)
{
- _priorityLists[i] = new PriorityQueueEntrySubList(queue);
+ _priorityLists[i] = new PriorityQueueEntrySubList(queue, i);
}
}
@@ -164,9 +164,12 @@ public class PriorityQueueList implements QueueEntryList<SimpleQueueEntryImpl>
private static class PriorityQueueEntrySubList extends SimpleQueueEntryList
{
- public PriorityQueueEntrySubList(AMQQueue queue)
+ private int _listPriority;
+
+ public PriorityQueueEntrySubList(AMQQueue queue, int listPriority)
{
super(queue);
+ _listPriority = listPriority;
}
@Override
@@ -174,6 +177,11 @@ public class PriorityQueueList implements QueueEntryList<SimpleQueueEntryImpl>
{
return new PriorityQueueEntryImpl(this, message);
}
+
+ public int getListPriority()
+ {
+ return _listPriority;
+ }
}
private static class PriorityQueueEntryImpl extends SimpleQueueEntryImpl
@@ -186,8 +194,9 @@ public class PriorityQueueList implements QueueEntryList<SimpleQueueEntryImpl>
@Override
public int compareTo(final QueueEntry o)
{
- byte thisPriority = getMessageHeader().getPriority();
- byte otherPriority = o.getMessageHeader().getPriority();
+ PriorityQueueEntrySubList pqel = (PriorityQueueEntrySubList)((PriorityQueueEntryImpl)o).getQueueEntryList();
+ int otherPriority = pqel.getListPriority();
+ int thisPriority = ((PriorityQueueEntrySubList) getQueueEntryList()).getListPriority();
if(thisPriority != otherPriority)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
index c33309b6d3..be2ab8b3ae 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -1,9 +1,3 @@
-package org.apache.qpid.server.queue;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.subscription.Subscription;
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -24,6 +18,12 @@ import org.apache.qpid.server.subscription.Subscription;
* under the License.
*
*/
+package org.apache.qpid.server.queue;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.subscription.Subscription;
+
public interface QueueEntry extends Comparable<QueueEntry>, Filterable
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index 209553e8fa..25e771a9cf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java
index 1578d21321..9ecaf6dafd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java
@@ -1,21 +1,21 @@
-package org.apache.qpid.server.queue;
-
-/**
+/*
* 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.
*/
+package org.apache.qpid.server.queue;
+
public interface QueueEntryVisitor
{
boolean visit(QueueEntry entry);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
index 72a54c9889..e8c34128e9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index d7eb304c92..d42bd6cf03 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/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;
@@ -28,12 +30,11 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
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 +53,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 +70,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 +78,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 +117,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 +130,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 +174,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;
@@ -185,12 +185,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
//TODO : persist creation time
private long _createTime = System.currentTimeMillis();
+ private UUID _qmfId;
private ConfigurationPlugin _queueConfiguration;
/** the maximum delivery count for each message on this queue or 0 if maximum delivery count is not to be enforced. */
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,17 +234,16 @@ 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;
-
+ _qmfId = getConfigStore().createId();
_asyncDelivery = ReferenceCountingExecutorService.getInstance().acquireExecutorService();
_logSubject = new QueueLogSubject(this);
@@ -255,16 +261,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"))
@@ -302,7 +298,22 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
public void execute(Runnable runnable)
{
- _asyncDelivery.execute(runnable);
+ try
+ {
+ _asyncDelivery.execute(runnable);
+ }
+ catch (RejectedExecutionException ree)
+ {
+ if (_stopped.get())
+ {
+ // Ignore - SubFlusherRunner or QueueRunner submitted execution as queue was being stopped.
+ }
+ else
+ {
+ _logger.error("Unexpected rejected execution", ree);
+ throw ree;
+ }
+ }
}
public AMQShortString getNameShortString()
@@ -320,6 +331,12 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
return _id;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return _qmfId;
+ }
+
public QueueConfigType getConfigType()
{
return QueueConfigType.getInstance();
@@ -339,15 +356,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 +380,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 +430,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
throw new AMQSecurityException("Permission denied");
}
-
-
+
+
if (hasExclusiveSubscriber())
{
throw new ExistingExclusiveSubscription();
@@ -463,15 +463,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 +516,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 +543,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 +621,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 +649,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
public void removeBinding(final Binding binding)
{
_bindings.remove(binding);
-
+
reconfigure();
}
@@ -718,10 +763,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
}
- if(_managedObject != null)
- {
- _managedObject.checkForNotification(entry.getMessage());
- }
+ checkForNotification(entry.getMessage());
if(action != null)
{
@@ -738,8 +780,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 +830,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 +839,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 +872,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
setLastSeenEntry(sub, entry);
_deliveredMessages.incrementAndGet();
- incrementUnackedMsgCount();
+ incrementUnackedMsgCount(entry);
sub.send(entry, batch);
}
@@ -833,12 +886,15 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private void setLastSeenEntry(final Subscription sub, final QueueEntry entry)
{
QueueContext subContext = (QueueContext) sub.getQueueContext();
- QueueEntry releasedEntry = subContext.getReleasedEntry();
-
- QueueContext._lastSeenUpdater.set(subContext, entry);
- if(releasedEntry == entry)
+ if (subContext != null)
{
- QueueContext._releasedUpdater.compareAndSet(subContext, releasedEntry, null);
+ QueueEntry releasedEntry = subContext.getReleasedEntry();
+
+ QueueContext._lastSeenUpdater.set(subContext, entry);
+ if(releasedEntry == entry)
+ {
+ QueueContext._releasedUpdater.compareAndSet(subContext, releasedEntry, null);
+ }
}
}
@@ -887,7 +943,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
_deliveredMessages.decrementAndGet();
}
-
+
if(sub != null && sub.isSessionTransactional())
{
incrementTxnDequeueStats(entry);
@@ -940,11 +996,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
}
+
+
public int getConsumerCount()
{
return _subscriptionList.size();
}
-
+
public int getConsumerCountHigh()
{
return _counsumerCountHigh.get();
@@ -1148,7 +1206,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 +1253,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 +1265,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 +1284,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
public long clearQueue() throws AMQException
- {
+ {
return clear(0l);
}
@@ -1422,7 +1295,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 +1362,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
throw new AMQSecurityException("Permission denied: " + getName());
}
-
+
if (!_deleted.getAndSet(true))
{
@@ -1617,12 +1490,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 +1968,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 +2099,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 +2189,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
return _queueConfiguration;
}
- public String getResourceName()
- {
- return _resourceName;
- }
-
-
public ConfigStore getConfigStore()
{
return getVirtualHost().getConfigStore();
@@ -2355,22 +2208,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 +2260,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 +2307,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/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
index 8f3b7ae4ce..47a7d733dd 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.queue;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.queue;
* under the License.
*
*/
+package org.apache.qpid.server.queue;
import org.apache.log4j.Logger;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 4ed28b965d..e0e317f75d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/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,24 +35,18 @@ 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.plugins.Plugin;
+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.SecurityManager.SecurityConfiguration;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManagerRegistry;
+import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -60,13 +54,8 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.UUID;
+import java.net.SocketAddress;
+import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
@@ -78,19 +67,19 @@ 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);
private final ServerConfiguration _configuration;
- private final Map<InetSocketAddress, QpidAcceptor> _acceptors = new HashMap<InetSocketAddress, QpidAcceptor>();
-
- private ManagedObjectRegistry _managedObjectRegistry;
+ private final Map<InetSocketAddress, QpidAcceptor> _acceptors =
+ Collections.synchronizedMap(new HashMap<InetSocketAddress, QpidAcceptor>());
- private AuthenticationManager _authenticationManager;
+ private IAuthenticationManagerRegistry _authenticationManagerRegistry;
- private VirtualHostRegistry _virtualHostRegistry;
+ private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(this);
private SecurityManager _securityManager;
@@ -106,39 +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;
- protected static Logger get_logger()
- {
- return _logger;
- }
+ private final List<PortBindingListener> _portBindingListeners = new ArrayList<PortBindingListener>();
- protected Map<InetSocketAddress, QpidAcceptor> getAcceptors()
- {
- return _acceptors;
- }
+ private int _httpManagementPort = -1, _httpsManagementPort = -1;
- protected void setManagedObjectRegistry(ManagedObjectRegistry managedObjectRegistry)
- {
- _managedObjectRegistry = managedObjectRegistry;
- }
+ private LogRecorder _logRecorder;
- protected void setAuthenticationManager(AuthenticationManager authenticationManager)
- {
- _authenticationManager = authenticationManager;
- }
+ 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)
@@ -205,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
{
@@ -222,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)
{
@@ -297,18 +279,32 @@ 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();
+ }
+ if (_configuration.getHTTPSManagementEnabled())
+ {
+ _httpsManagementPort = _configuration.getHTTPSManagementPort();
+ }
+
+ _broker = new BrokerAdapter(this);
configure();
@@ -316,13 +312,23 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
logStartupMessages(CurrentActor.get());
- _virtualHostRegistry = new VirtualHostRegistry(this);
-
_securityManager = new SecurityManager(_configuration, _pluginManager);
- _authenticationManager = createAuthenticationManager();
+ _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
{
@@ -333,7 +339,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
initialiseVirtualHosts();
- initialiseStatistics();
initialiseStatisticsReporting();
}
finally
@@ -343,52 +348,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
-
- /**
- * Iterates across all discovered authentication manager factories, offering the security configuration to each.
- * Expects <b>exactly</b> one authentication manager to configure and initialise itself.
- *
- * It is an error to configure more than one authentication manager, or to configure none.
- *
- * @return authentication manager
- * @throws ConfigurationException
- */
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(ServerConfiguration _configuration, PluginManager _pluginManager)
+ throws ConfigurationException
{
- final SecurityConfiguration securityConfiguration = _configuration.getConfiguration(SecurityConfiguration.class.getName());
- final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values();
-
- if (factories.size() == 0)
- {
- throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" +
- "manager plugin has been placed in the plugins directory.");
- }
-
- AuthenticationManager authMgr = null;
-
- for (final Iterator<AuthenticationManagerPluginFactory<? extends Plugin>> iterator = factories.iterator(); iterator.hasNext();)
- {
- final AuthenticationManagerPluginFactory<? extends Plugin> factory = (AuthenticationManagerPluginFactory<? extends Plugin>) iterator.next();
- final AuthenticationManager tmp = factory.newInstance(securityConfiguration);
- if (tmp != null)
- {
- if (authMgr != null)
- {
- throw new ConfigurationException("Cannot configure more than one authentication manager."
- + " Both " + tmp.getClass() + " and " + authMgr.getClass() + " are configured."
- + " Remove configuration for one of the authentication manager, or remove the plugin JAR"
- + " from the classpath.");
- }
- authMgr = tmp;
- }
- }
-
- if (authMgr == null)
- {
- throw new ConfigurationException("No authentication managers configured within the configure file.");
- }
-
- return authMgr;
+ return new AuthenticationManagerRegistry(_configuration, _pluginManager);
}
protected void initialiseVirtualHosts() throws Exception
@@ -400,23 +363,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),
@@ -545,15 +503,13 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
//Shutdown virtualhosts
close(_virtualHostRegistry);
- close(_authenticationManager);
+ close(_authenticationManagerRegistry);
close(_qmfService);
close(_pluginManager);
- close(_managedObjectRegistry);
-
- BrokerConfig broker = getBroker();
+ BrokerConfig broker = getBrokerConfig();
if(broker != null)
{
broker.getSystem().removeBroker(broker);
@@ -569,12 +525,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();
@@ -587,6 +545,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()
@@ -600,6 +568,13 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_acceptors.put(bindAddress, acceptor);
}
+ synchronized (_portBindingListeners)
+ {
+ for(PortBindingListener listener : _portBindingListeners)
+ {
+ listener.bound(acceptor, bindAddress);
+ }
+ }
}
public VirtualHostRegistry getVirtualHostRegistry()
@@ -612,14 +587,16 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _securityManager;
}
- public ManagedObjectRegistry getManagedObjectRegistry()
+ @Override
+ public AuthenticationManager getAuthenticationManager(SocketAddress address)
{
- return _managedObjectRegistry;
+ return _authenticationManagerRegistry.getAuthenticationManager(address);
}
- public AuthenticationManager getAuthenticationManager()
+ @Override
+ public IAuthenticationManagerRegistry getAuthenticationManagerRegistry()
{
- return _authenticationManager;
+ return _authenticationManagerRegistry;
}
public PluginManager getPluginManager()
@@ -636,7 +613,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
return _rootMessageLogger;
}
-
+
public RootMessageLogger getCompositeStartupMessageLogger()
{
return _startupMessageLogger;
@@ -652,69 +629,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();
@@ -723,25 +694,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()));
@@ -755,4 +713,60 @@ 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;
+ }
+
+ @Override
+ public boolean useHTTPSManagement()
+ {
+ return _httpsManagementPort != -1;
+ }
+
+ @Override
+ public int getHTTPSManagementPort()
+ {
+ return _httpsManagementPort;
+ }
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
index db436b99e8..950a090b43 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
@@ -44,13 +44,13 @@ public class BrokerConfigAdapter implements BrokerConfig
private final Map<UUID, VirtualHostConfig> _vhosts = new ConcurrentHashMap<UUID, VirtualHostConfig>();
private final long _createTime = System.currentTimeMillis();
- private UUID _id;
+ private UUID _qmfId;
private String _federationTag;
public BrokerConfigAdapter(final IApplicationRegistry instance)
{
_instance = instance;
- _id = instance.getConfigStore().createId();
+ _qmfId = instance.getConfigStore().createId();
_federationTag = UUID.randomUUID().toString();
}
@@ -114,7 +114,7 @@ public class BrokerConfigAdapter implements BrokerConfig
public void addVirtualHost(final VirtualHostConfig virtualHost)
{
- _vhosts.put(virtualHost.getId(), virtualHost);
+ _vhosts.put(virtualHost.getQMFId(), virtualHost);
getConfigStore().addConfiguredObject(virtualHost);
}
@@ -141,9 +141,10 @@ public class BrokerConfigAdapter implements BrokerConfig
vhost.createBrokerConnection(transport, host, port, "", durable, authMechanism, username, password);
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public BrokerConfigType getConfigType()
@@ -184,7 +185,7 @@ public class BrokerConfigAdapter implements BrokerConfig
public String toString()
{
return "BrokerConfigAdapter{" +
- "_id=" + _id +
+ "_id=" + _qmfId +
", _system=" + _system +
", _vhosts=" + _vhosts +
", _createTime=" + _createTime +
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index b28e3d6c89..774d0338ef 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index 59bf250590..88c3c93156 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -27,16 +27,19 @@ 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;
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
@@ -60,9 +63,18 @@ public interface IApplicationRegistry extends StatisticsGatherer
*/
ServerConfiguration getConfiguration();
- ManagedObjectRegistry getManagedObjectRegistry();
+ /**
+ * Get the AuthenticationManager for the given socket address
+ *
+ * If no AuthenticationManager has been specifically set for the given address, then use the default
+ * AuthenticationManager
+ *
+ * @param address The (listening) socket address for which the AuthenticationManager is required
+ * @return the AuthenticationManager
+ */
+ AuthenticationManager getAuthenticationManager(SocketAddress address);
- AuthenticationManager getAuthenticationManager();
+ IAuthenticationManagerRegistry getAuthenticationManagerRegistry();
VirtualHostRegistry getVirtualHostRegistry();
@@ -85,15 +97,39 @@ public interface IApplicationRegistry extends StatisticsGatherer
QMFService getQMFService();
- void setBroker(BrokerConfig broker);
+ void setBrokerConfig(BrokerConfig broker);
- BrokerConfig getBroker();
+ BrokerConfig getBrokerConfig();
+
+ 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();
+
+ boolean useHTTPSManagement();
+
+ int getHTTPSManagementPort();
+
+ void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener);
+
+ public interface PortBindingListener
+ {
+ public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress);
+ public void unbound(QpidAcceptor acceptor);
+
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
index 7088fae50c..cac60a5283 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
deleted file mode 100644
index 1314a5d6a6..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java
new file mode 100644
index 0000000000..5676c43754
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java
@@ -0,0 +1,192 @@
+/*
+ * 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.manager;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser;
+import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousSaslServer;
+
+public class AnonymousAuthenticationManager implements AuthenticationManager
+{
+ private static final Logger _logger = Logger.getLogger(AnonymousAuthenticationManager.class);
+
+ private static final AnonymousInitialiser SASL_INITIALISER = new AnonymousInitialiser();
+
+ private static final String ANONYMOUS = SASL_INITIALISER.getMechanismName();
+
+ private static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal("ANONYMOUS");
+
+ public static final Subject ANONYMOUS_SUBJECT = new Subject();
+ static
+ {
+ ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL);
+ }
+
+ private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_SUBJECT);
+
+
+ private static CallbackHandler _callbackHandler = SASL_INITIALISER.getCallbackHandler();
+
+ static final AnonymousAuthenticationManager INSTANCE = new AnonymousAuthenticationManager();
+
+ public static class AnonymousAuthenticationManagerConfiguration extends ConfigurationPlugin
+ {
+
+ public static final ConfigurationPluginFactory FACTORY =
+ new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.anonymous-auth-manager");
+ }
+
+ public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ {
+ final ConfigurationPlugin instance = new AnonymousAuthenticationManagerConfiguration();
+
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[0];
+ }
+
+ public void validateConfiguration() throws ConfigurationException
+ {
+ }
+
+ }
+
+
+ public static final AuthenticationManagerPluginFactory<AnonymousAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<AnonymousAuthenticationManager>()
+ {
+ public AnonymousAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
+ {
+ AnonymousAuthenticationManagerConfiguration configuration =
+ config == null
+ ? null
+ : (AnonymousAuthenticationManagerConfiguration) config.getConfiguration(AnonymousAuthenticationManagerConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ _logger.info("No authentication-manager configuration found for AnonymousAuthenticationManager");
+ return null;
+ }
+ return INSTANCE;
+ }
+
+ public Class<AnonymousAuthenticationManager> getPluginClass()
+ {
+ return AnonymousAuthenticationManager.class;
+ }
+
+ public String getPluginName()
+ {
+ return AnonymousAuthenticationManager.class.getName();
+ }
+ };
+
+
+ private AnonymousAuthenticationManager()
+ {
+ }
+
+ @Override
+ public void initialise()
+ {
+
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ return ANONYMOUS;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(ANONYMOUS.equals(mechanism))
+ {
+ return new AnonymousSaslServer();
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ try
+ {
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
+ {
+ return ANONYMOUS_AUTHENTICATION;
+ }
+ else
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ return ANONYMOUS_AUTHENTICATION;
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void configure(ConfigurationPlugin config) throws ConfigurationException
+ {
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 6c1a917d5b..ccddcb7669 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.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,25 +20,24 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import java.security.Principal;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.security.auth.AuthenticationResult;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
/**
* Implementations of the AuthenticationManager are responsible for determining
* the authenticity of a user's credentials.
- *
+ *
* If the authentication is successful, the manager is responsible for producing a populated
* {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing
* groups to which the user belongs.
* <p>
* The {@link #initialise()} method is responsible for registering SASL mechanisms required by
* the manager. The {@link #close()} method must reverse this registration.
- *
+ *
*/
public interface AuthenticationManager extends Closeable, Plugin
{
@@ -64,11 +63,11 @@ public interface AuthenticationManager extends Closeable, Plugin
*
* @param mechanism mechanism name
* @param localFQDN domain name
- *
+ * @param externalPrincipal externally authenticated Principal
* @return SASL server
* @throws SaslException
*/
- SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException;
+ SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException;
/**
* Authenticates a user using SASL negotiation.
@@ -90,5 +89,4 @@ public interface AuthenticationManager extends Closeable, Plugin
*/
AuthenticationResult authenticate(String username, String password);
- CallbackHandler getHandler(String mechanism);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
new file mode 100644
index 0000000000..89a4d8ae66
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
@@ -0,0 +1,203 @@
+/*
+ * 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.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;
+import org.apache.qpid.common.Closeable;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.plugins.Plugin;
+import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration;
+
+/**
+ * A concrete implementation of {@link IAuthenticationManagerRegistry} that registers all {@link AuthenticationManager}
+ * instances defined in the configuration, building an optional mapping between port number and AuthenticationManager.
+ *
+ * <p>The default AuthenticationManager is either the one nominated as default within the configuration with
+ * {@link ServerConfiguration#getDefaultAuthenticationManager()}, or if there is only one, it is implicitly
+ * the default.</p>
+ *
+ * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers
+ * to reverse any security registrations they have performed.</p>
+ */
+public class AuthenticationManagerRegistry implements Closeable, IAuthenticationManagerRegistry
+{
+ 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
+ {
+ final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values();
+
+ if (factories.size() == 0)
+ {
+ throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" +
+ " manager plugin has been placed in the plugins directory.");
+ }
+
+ final SecurityConfiguration securityConfiguration = serverConfiguration.getConfiguration(SecurityConfiguration.class.getName());
+
+ boolean willClose = true;
+ try
+ {
+ createAuthenticationManagersRejectingDuplicates(factories, securityConfiguration);
+
+ if(_classToAuthManagerMap.isEmpty())
+ {
+ throw new ConfigurationException("No authentication managers configured within the configuration file.");
+ }
+
+ _defaultAuthenticationManager = getDefaultAuthenticationManager(serverConfiguration);
+
+ _portToAuthenticationManagerMap = getPortToAuthenticationManagerMap(serverConfiguration);
+ willClose = false;
+ }
+ finally
+ {
+ // if anything went wrong whilst configuring the registry, try to close all the AuthentcationManagers instantiated so far.
+ // This is done to allow the AuthenticationManager to undo any security registrations that they have performed.
+ if (willClose)
+ {
+ close();
+ }
+ }
+ }
+
+ @Override
+ public AuthenticationManager getAuthenticationManager(SocketAddress address)
+ {
+ AuthenticationManager authManager =
+ address instanceof InetSocketAddress
+ ? _portToAuthenticationManagerMap.get(((InetSocketAddress)address).getPort())
+ : null;
+
+ return authManager == null ? _defaultAuthenticationManager : authManager;
+ }
+
+ @Override
+ public void close()
+ {
+ for (AuthenticationManager authManager : _classToAuthManagerMap.values())
+ {
+ authManager.close();
+ }
+ }
+
+ private void createAuthenticationManagersRejectingDuplicates(
+ final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories,
+ final SecurityConfiguration securityConfiguration)
+ throws ConfigurationException
+ {
+ for(AuthenticationManagerPluginFactory<? extends Plugin> factory : factories)
+ {
+ final AuthenticationManager tmp = factory.newInstance(securityConfiguration);
+ if (tmp != null)
+ {
+ if(_classToAuthManagerMap.containsKey(tmp.getClass().getSimpleName()))
+ {
+ throw new ConfigurationException("Cannot configure more than one authentication manager of type "
+ + tmp.getClass().getSimpleName() + "."
+ + " Remove configuration for one of the authentication managers.");
+ }
+ _classToAuthManagerMap.put(tmp.getClass().getSimpleName(),tmp);
+
+ for(RegistryChangeListener listener : _listeners)
+ {
+ listener.authenticationManagerRegistered(tmp);
+ }
+ }
+ }
+ }
+
+ private AuthenticationManager getDefaultAuthenticationManager(
+ ServerConfiguration serverConfiguration)
+ throws ConfigurationException
+ {
+ final AuthenticationManager defaultAuthenticationManager;
+ if(_classToAuthManagerMap.size() == 1)
+ {
+ defaultAuthenticationManager = _classToAuthManagerMap.values().iterator().next();
+ }
+ else if(serverConfiguration.getDefaultAuthenticationManager() != null)
+ {
+ defaultAuthenticationManager = _classToAuthManagerMap.get(serverConfiguration.getDefaultAuthenticationManager());
+ if(defaultAuthenticationManager == null)
+ {
+ throw new ConfigurationException("No authentication managers configured of type "
+ + serverConfiguration.getDefaultAuthenticationManager()
+ + " which is specified as the default. Available managers are: "
+ + _classToAuthManagerMap.keySet());
+ }
+ }
+ else
+ {
+ throw new ConfigurationException("If more than one authentication manager is configured a default MUST be specified.");
+ }
+ return defaultAuthenticationManager;
+ }
+
+ private Map<Integer,AuthenticationManager> getPortToAuthenticationManagerMap(
+ ServerConfiguration serverConfiguration)
+ throws ConfigurationException
+ {
+ Map<Integer,AuthenticationManager> portToAuthenticationManagerMap = new HashMap<Integer, AuthenticationManager>();
+
+ for(Map.Entry<Integer,String> portMapping : serverConfiguration.getPortAuthenticationMappings().entrySet())
+ {
+
+ AuthenticationManager authenticationManager = _classToAuthManagerMap.get(portMapping.getValue());
+ if(authenticationManager == null)
+ {
+ throw new ConfigurationException("Unknown authentication manager class " + portMapping.getValue() +
+ " configured for port " + portMapping.getKey());
+ }
+ portToAuthenticationManagerMap.put(portMapping.getKey(), authenticationManager);
+ }
+
+ 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/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
new file mode 100644
index 0000000000..2d6866b657
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java
@@ -0,0 +1,177 @@
+/*
+ * 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.manager;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+import javax.security.auth.Subject;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer;
+
+public class ExternalAuthenticationManager implements AuthenticationManager
+{
+ private static final Logger _logger = Logger.getLogger(ExternalAuthenticationManager.class);
+
+ private static final String EXTERNAL = "EXTERNAL";
+
+ static final ExternalAuthenticationManager INSTANCE = new ExternalAuthenticationManager();
+
+ public static class ExternalAuthenticationManagerConfiguration extends ConfigurationPlugin
+ {
+
+ public static final ConfigurationPluginFactory FACTORY =
+ new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.external-auth-manager");
+ }
+
+ public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ {
+ final ConfigurationPlugin instance = new ExternalAuthenticationManagerConfiguration();
+
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[0];
+ }
+
+ public void validateConfiguration() throws ConfigurationException
+ {
+ }
+
+ }
+
+
+ public static final AuthenticationManagerPluginFactory<ExternalAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<ExternalAuthenticationManager>()
+ {
+ public ExternalAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
+ {
+ ExternalAuthenticationManagerConfiguration configuration =
+ config == null
+ ? null
+ : (ExternalAuthenticationManagerConfiguration) config.getConfiguration(ExternalAuthenticationManagerConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ _logger.info("No authentication-manager configuration found for ExternalAuthenticationManager");
+ return null;
+ }
+ return INSTANCE;
+ }
+
+ public Class<ExternalAuthenticationManager> getPluginClass()
+ {
+ return ExternalAuthenticationManager.class;
+ }
+
+ public String getPluginName()
+ {
+ return ExternalAuthenticationManager.class.getName();
+ }
+ };
+
+
+ private ExternalAuthenticationManager()
+ {
+ }
+
+ @Override
+ public void initialise()
+ {
+
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ return EXTERNAL;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(EXTERNAL.equals(mechanism))
+ {
+ return new ExternalSaslServer(externalPrincipal);
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ // Process response from the client
+ try
+ {
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal();
+
+ if(principal != null)
+ {
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(principal);
+ return new AuthenticationResult(subject);
+ }
+ else
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR,e);
+ }
+
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void configure(ConfigurationPlugin config) throws ConfigurationException
+ {
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java
new file mode 100644
index 0000000000..485ca2e1e9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.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.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.
+ *
+ * <p>A lookup method {@link #getAuthenticationManager(SocketAddress)} allows a caller to determine
+ * the AuthenticationManager associated with a particular port number.</p>
+ *
+ * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers
+ * to reverse any security registrations they have performed.</p>
+ */
+public interface IAuthenticationManagerRegistry extends Closeable
+{
+ /**
+ * Returns the {@link AuthenticationManager} associated with a particular {@link SocketAddress}.
+ * If no authentication manager is associated with this address, a default authentication manager will be
+ * returned. Null is never returned.
+ *
+ * @param address
+ * @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/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
new file mode 100644
index 0000000000..d735ecb1d4
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
@@ -0,0 +1,213 @@
+/*
+ * 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.manager;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
+public class KerberosAuthenticationManager implements AuthenticationManager
+{
+ private static final Logger _logger = Logger.getLogger(KerberosAuthenticationManager.class);
+
+ private static final String GSSAPI_MECHANISM = "GSSAPI";
+ private final CallbackHandler _callbackHandler = new GssApiCallbackHandler();
+
+ public static class KerberosAuthenticationManagerConfiguration extends ConfigurationPlugin
+ {
+
+ public static final ConfigurationPluginFactory FACTORY =
+ new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.kerberos-auth-manager");
+ }
+
+ public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ {
+ final ConfigurationPlugin instance = new KerberosAuthenticationManagerConfiguration();
+
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[0];
+ }
+
+ public void validateConfiguration() throws ConfigurationException
+ {
+ }
+
+ }
+
+
+ public static final AuthenticationManagerPluginFactory<KerberosAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<KerberosAuthenticationManager>()
+ {
+ public KerberosAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
+ {
+ KerberosAuthenticationManagerConfiguration configuration =
+ config == null
+ ? null
+ : (KerberosAuthenticationManagerConfiguration) config.getConfiguration(KerberosAuthenticationManagerConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ _logger.info("No authentication-manager configuration found for KerberosAuthenticationManager");
+ return null;
+ }
+ KerberosAuthenticationManager kerberosAuthenticationManager = new KerberosAuthenticationManager();
+ kerberosAuthenticationManager.configure(configuration);
+ return kerberosAuthenticationManager;
+ }
+
+ public Class<KerberosAuthenticationManager> getPluginClass()
+ {
+ return KerberosAuthenticationManager.class;
+ }
+
+ public String getPluginName()
+ {
+ return KerberosAuthenticationManager.class.getName();
+ }
+ };
+
+
+ private KerberosAuthenticationManager()
+ {
+ }
+
+ @Override
+ public void initialise()
+ {
+
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ return GSSAPI_MECHANISM;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(GSSAPI_MECHANISM.equals(mechanism))
+ {
+ try
+ {
+ return Sasl.createSaslServer(GSSAPI_MECHANISM, "AMQP", localFQDN,
+ new HashMap<String, Object>(), _callbackHandler);
+ }
+ catch (SaslException e)
+ {
+ e.printStackTrace(System.err);
+ throw e;
+ }
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ try
+ {
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
+ {
+ final Subject subject = new Subject();
+ _logger.debug("Authenticated as " + server.getAuthorizationID());
+ subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
+ return new AuthenticationResult(subject);
+ }
+ else
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (SaslException e)
+ {
+ e.printStackTrace(System.err);
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void configure(ConfigurationPlugin config) throws ConfigurationException
+ {
+ }
+
+ private static class GssApiCallbackHandler implements CallbackHandler
+ {
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ for(Callback callback : callbacks)
+ {
+ if (callback instanceof AuthorizeCallback)
+ {
+ ((AuthorizeCallback) callback).setAuthorized(true);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index b5d70d9200..e6498919a1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -14,12 +14,13 @@
* "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.
+ * under the License.
+ *
*
- *
*/
package org.apache.qpid.server.security.auth.manager;
+import java.security.Principal;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -31,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;
@@ -60,9 +60,9 @@ import java.util.TreeMap;
* Concrete implementation of the AuthenticationManager that determines if supplied
* user credentials match those appearing in a PrincipalDatabase. The implementation
* of the PrincipalDatabase is determined from the configuration.
- *
+ *
* This implementation also registers the JMX UserManagemement MBean.
- *
+ *
* This plugin expects configuration such as:
*
* <pre>
@@ -97,13 +97,14 @@ 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
{
- final PrincipalDatabaseAuthenticationManagerConfiguration configuration = config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName());
+ final PrincipalDatabaseAuthenticationManagerConfiguration configuration =
+ config == null
+ ? null
+ : (PrincipalDatabaseAuthenticationManagerConfiguration) config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName());
// If there is no configuration for this plugin then don't load it.
if (configuration == null)
@@ -130,7 +131,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
};
public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin {
-
+
public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
{
public List<String> getParentPaths()
@@ -141,7 +142,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
{
final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration();
-
+
instance.setConfiguration(path, config);
return instance;
}
@@ -157,16 +158,16 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
public void validateConfiguration() throws ConfigurationException
{
}
-
+
public String getPrincipalDatabaseClass()
{
return getConfig().getString("principal-database.class");
}
-
+
public Map<String,String> getPdClassAttributeMap() throws ConfigurationException
{
- final List<String> argumentNames = getConfig().getList("principal-database.attributes.attribute.name");
- final List<String> argumentValues = getConfig().getList("principal-database.attributes.attribute.value");
+ final List<String> argumentNames = (List) getConfig().getList("principal-database.attributes.attribute.name");
+ final List<String> argumentValues = (List) getConfig().getList("principal-database.attributes.attribute.value");
final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size());
for (int i = 0; i < argumentNames.size(); i++)
@@ -181,7 +182,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
}
}
- protected PrincipalDatabaseAuthenticationManager()
+ protected PrincipalDatabaseAuthenticationManager()
{
}
@@ -207,11 +208,9 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_logger.warn("No additional SASL providers registered.");
}
-
- registerManagement();
}
- private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database)
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database)
{
if (database == null || database.getMechanisms().size() == 0)
{
@@ -259,7 +258,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
_principalDatabase = createPrincipalDatabaseImpl(pdClazz);
- configPrincipalDatabase(_principalDatabase, pdamConfig);
+ configPrincipalDatabase(_principalDatabase, pdamConfig);
}
public String getMechanisms()
@@ -267,7 +266,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
return _mechanisms;
}
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
{
return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
_callbackHandlerMap.get(mechanism));
@@ -300,11 +299,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
}
}
- public CallbackHandler getHandler(String mechanism)
- {
- return _callbackHandlerMap.get(mechanism);
- }
-
/**
* @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String)
*/
@@ -333,8 +327,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_mechanisms = null;
Security.removeProvider(PROVIDER_NAME);
-
- unregisterManagement();
}
private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException
@@ -408,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))
@@ -428,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/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
new file mode 100644
index 0000000000..64b24e28bc
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
@@ -0,0 +1,389 @@
+/*
+ * 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.manager;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
+
+public class SimpleLDAPAuthenticationManager implements AuthenticationManager
+{
+ private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class);
+
+ private static final String PLAIN_MECHANISM = "PLAIN";
+ private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
+ private String _providerSearchURL;
+ private String _searchContext;
+ private String _searchFilter;
+ private String _providerAuthURL;
+ private String _ldapContextFactory;
+
+ public static class SimpleLDAPAuthenticationManagerConfiguration extends ConfigurationPlugin
+ {
+
+ public static final ConfigurationPluginFactory FACTORY =
+ new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.simple-ldap-auth-manager");
+ }
+
+ public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ {
+ final ConfigurationPlugin instance = new SimpleLDAPAuthenticationManagerConfiguration();
+
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ private static final String PROVIDER_URL = "provider-url";
+ private static final String PROVIDER_SEARCH_URL = "provider-search-url";
+ private static final String PROVIDER_AUTH_URL = "provider-auth-url";
+ private static final String SEARCH_CONTEXT = "search-context";
+ private static final String SEARCH_FILTER = "search-filter";
+ private static final String LDAP_CONTEXT_FACTORY = "ldap-context-factory";
+
+ public String[] getElementsProcessed()
+ {
+ return new String[] {PROVIDER_URL, PROVIDER_SEARCH_URL, PROVIDER_AUTH_URL, SEARCH_CONTEXT, SEARCH_FILTER,
+ LDAP_CONTEXT_FACTORY};
+ }
+
+ public void validateConfiguration() throws ConfigurationException
+ {
+ }
+
+ public String getLDAPContextFactory()
+ {
+ return getConfig().getString(LDAP_CONTEXT_FACTORY, DEFAULT_LDAP_CONTEXT_FACTORY);
+ }
+
+
+ public String getProviderURL()
+ {
+ return getConfig().getString(PROVIDER_URL);
+ }
+
+ public String getProviderSearchURL()
+ {
+ return getConfig().getString(PROVIDER_SEARCH_URL, getProviderURL());
+ }
+
+ public String getSearchContext()
+ {
+ return getConfig().getString(SEARCH_CONTEXT);
+ }
+
+ public String getSearchFilter()
+ {
+ return getConfig().getString(SEARCH_FILTER);
+ }
+
+ public String getProviderAuthURL()
+ {
+ return getConfig().getString(PROVIDER_AUTH_URL, getProviderURL());
+ }
+ }
+
+
+ public static final AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager>()
+ {
+ public SimpleLDAPAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
+ {
+ SimpleLDAPAuthenticationManagerConfiguration configuration =
+ config == null
+ ? null
+ : (SimpleLDAPAuthenticationManagerConfiguration) config.getConfiguration(SimpleLDAPAuthenticationManagerConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ _logger.info("No authentication-manager configuration found for SimpleLDAPAuthenticationManager");
+ return null;
+ }
+ SimpleLDAPAuthenticationManager simpleLDAPAuthenticationManager = new SimpleLDAPAuthenticationManager();
+ simpleLDAPAuthenticationManager.configure(configuration);
+ return simpleLDAPAuthenticationManager;
+ }
+
+ public Class<SimpleLDAPAuthenticationManager> getPluginClass()
+ {
+ return SimpleLDAPAuthenticationManager.class;
+ }
+
+ public String getPluginName()
+ {
+ return SimpleLDAPAuthenticationManager.class.getName();
+ }
+ };
+
+
+ private SimpleLDAPAuthenticationManager()
+ {
+ }
+
+ @Override
+ public void initialise()
+ {
+
+ }
+
+ @Override
+ public String getMechanisms()
+ {
+ return PLAIN_MECHANISM;
+ }
+
+ @Override
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ if(PLAIN_MECHANISM.equals(mechanism))
+ {
+ return Sasl.createSaslServer(PLAIN_MECHANISM, "AMQP", localFQDN,
+ new HashMap<String, Object>(), new PlainCallbackHandler());
+
+ }
+ else
+ {
+ throw new SaslException("Unknown mechanism: " + mechanism);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ try
+ {
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
+ {
+ final Subject subject = new Subject();
+ _logger.debug("Authenticated as " + server.getAuthorizationID());
+ subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
+ return new AuthenticationResult(subject);
+ }
+ else
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+
+ @Override
+ public AuthenticationResult authenticate(String username, String password)
+ {
+
+ try
+ {
+ return doLDAPNameAuthentication(getNameFromId(username), password);
+ }
+ catch (NamingException e)
+ {
+
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+
+ }
+ }
+
+ private AuthenticationResult doLDAPNameAuthentication(String username, String password) throws NamingException
+ {
+ Hashtable<Object,Object> env = new Hashtable<Object,Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
+ env.put(Context.PROVIDER_URL, _providerAuthURL);
+
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+
+ env.put(Context.SECURITY_PRINCIPAL, username);
+ env.put(Context.SECURITY_CREDENTIALS, password);
+ DirContext ctx = new InitialDirContext(env);
+ ctx.close();
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new UsernamePrincipal(username));
+ return new AuthenticationResult(subject);
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void configure(ConfigurationPlugin config) throws ConfigurationException
+ {
+ SimpleLDAPAuthenticationManagerConfiguration ldapConfig = (SimpleLDAPAuthenticationManagerConfiguration) config;
+
+ _ldapContextFactory = ldapConfig.getLDAPContextFactory();
+ _providerSearchURL = ldapConfig.getProviderSearchURL();
+ _providerAuthURL = ldapConfig.getProviderAuthURL();
+ _searchContext = ldapConfig.getSearchContext();
+ _searchFilter = ldapConfig.getSearchFilter();
+
+ Hashtable<String,Object> env = new Hashtable<String, Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
+ env.put(Context.PROVIDER_URL, _providerSearchURL);
+ env.put(Context.SECURITY_AUTHENTICATION, "none");
+
+ try
+ {
+ new InitialDirContext(env);
+ }
+ catch (NamingException e)
+ {
+ throw new ConfigurationException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e);
+ }
+ }
+
+ private class PlainCallbackHandler implements CallbackHandler
+ {
+
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
+ {
+ String name = null;
+ String password = null;
+ AuthenticationResult authenticated = null;
+ for(Callback callback : callbacks)
+ {
+ if (callback instanceof NameCallback)
+ {
+ String id = ((NameCallback) callback).getDefaultName();
+ try
+ {
+ name = getNameFromId(id);
+ }
+ catch (NamingException e)
+ {
+ _logger.info("SASL Authentication Error", e);
+ }
+ if(password != null)
+ {
+ try
+ {
+ authenticated = doLDAPNameAuthentication(name, password);
+
+ }
+ catch (NamingException e)
+ {
+ authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+ }
+ else if (callback instanceof PlainPasswordCallback)
+ {
+ password = ((PlainPasswordCallback)callback).getPlainPassword();
+ if(name != null)
+ {
+ try
+ {
+ authenticated = doLDAPNameAuthentication(name, password);
+ if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS)
+ {
+ ((PlainPasswordCallback)callback).setAuthenticated(true);
+ }
+ }
+ catch (NamingException e)
+ {
+ authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ }
+ }
+ else if (callback instanceof AuthorizeCallback)
+ {
+ ((AuthorizeCallback) callback).setAuthorized(authenticated != null && authenticated.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS);
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+ }
+
+ private String getNameFromId(String id) throws NamingException
+ {
+ Hashtable<Object,Object> env = new Hashtable<Object,Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
+ env.put(Context.PROVIDER_URL, _providerSearchURL);
+
+
+ env.put(Context.SECURITY_AUTHENTICATION, "none");
+ DirContext ctx = null;
+
+ ctx = new InitialDirContext(env);
+
+ try
+ {
+ SearchControls searchControls = new SearchControls();
+ searchControls.setReturningAttributes(new String[] {});
+ searchControls.setCountLimit(1l);
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ NamingEnumeration<?> namingEnum = null;
+ String name = null;
+
+ namingEnum = ctx.search(_searchContext, _searchFilter, new String[] { id }, searchControls);
+ if(namingEnum.hasMore())
+ {
+ SearchResult result = (SearchResult) namingEnum.next();
+ name = result.getNameInNamespace();
+ }
+ return name;
+ }
+ finally
+ {
+ ctx.close();
+ }
+
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index e27fd99f90..2e21cfbb07 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.java
new file mode 100644
index 0000000000..9c2bca2d0b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/external/ExternalSaslServer.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.security.auth.sasl.external;
+
+import java.security.Principal;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+
+public class ExternalSaslServer implements SaslServer
+{
+ public static final String MECHANISM = "EXTERNAL";
+
+ private boolean _complete = false;
+ private final Principal _externalPrincipal;
+
+ public ExternalSaslServer(Principal externalPrincipal)
+ {
+ _externalPrincipal = externalPrincipal;
+ }
+
+ public String getMechanismName()
+ {
+ return MECHANISM;
+ }
+
+ public byte[] evaluateResponse(byte[] response) throws SaslException
+ {
+ _complete = true;
+ return null;
+ }
+
+ public boolean isComplete()
+ {
+ return _complete;
+ }
+
+ public String getAuthorizationID()
+ {
+ return null;
+ }
+
+ public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+ {
+ throw new SaslException("Unsupported operation");
+ }
+
+ public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ {
+ throw new SaslException("Unsupported operation");
+ }
+
+ public Object getNegotiatedProperty(String propName)
+ {
+ return null;
+ }
+
+ public void dispose() throws SaslException
+ {
+ }
+
+ public Principal getAuthenticatedPrincipal()
+ {
+ return _externalPrincipal;
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
index f97b77a4fe..f352bbdd2c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
@@ -32,7 +32,9 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -61,6 +63,18 @@ public class AMQStateManager implements AMQMethodListener
}
+ /**
+ * Get the ApplicationRegistry associated with this AMQStateManager
+ *
+ * returns the application registry associated with the VirtualHostRegistry of the AMQStateManager
+ *
+ * @return the ApplicationRegistry
+ */
+ public IApplicationRegistry getApplicationRegistry()
+ {
+ return _virtualHostRegistry.getApplicationRegistry();
+ }
+
public AMQState getCurrentState()
{
return _currentState;
@@ -142,4 +156,14 @@ public class AMQStateManager implements AMQMethodListener
SecurityManager.setThreadSubject(_protocolSession.getAuthorizedSubject());
return _protocolSession;
}
+
+ /**
+ * Get the AuthenticationManager associated with the ProtocolSession of the AMQStateManager
+ *
+ * @return the AuthenticationManager
+ */
+ public AuthenticationManager getAuthenticationManager()
+ {
+ return getApplicationRegistry().getAuthenticationManager(getProtocolSession().getLocalAddress());
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java b/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
index 2bd17cfa2f..f382f90010 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java b/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
index 36fec4025a..37d87bb628 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
index 1307b1dbd4..ede01d247e 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java
@@ -28,20 +28,21 @@ import java.util.UUID;
public interface ConfigurationRecoveryHandler
{
- QueueRecoveryHandler begin(MessageStore store);
+ ExchangeRecoveryHandler begin(MessageStore store);
- public static interface QueueRecoveryHandler
+ public static interface ExchangeRecoveryHandler
{
- void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments);
- ExchangeRecoveryHandler completeQueueRecovery();
+ void exchange(UUID id, String exchangeName, String type, boolean autoDelete);
+ QueueRecoveryHandler completeExchangeRecovery();
}
- public static interface ExchangeRecoveryHandler
+ public static interface QueueRecoveryHandler
{
- void exchange(UUID id, String exchangeName, String type, boolean autoDelete);
- BindingRecoveryHandler completeExchangeRecovery();
+ void queue(UUID id, String queueName, String owner, boolean exclusive, FieldTable arguments, UUID alternateExchangeId);
+ BindingRecoveryHandler completeQueueRecovery();
}
+
public static interface BindingRecoveryHandler
{
void binding(UUID bindingId, UUID exchangeId, UUID queueId, String bindingName, ByteBuffer buf);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java b/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java
index 1a67fdf540..7356e1ae83 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/store/Event.java b/java/broker/src/main/java/org/apache/qpid/server/store/Event.java
index bbde11ab4c..c681126c11 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/Event.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/Event.java
@@ -23,10 +23,20 @@ public enum Event
{
BEFORE_INIT,
AFTER_INIT,
+
BEFORE_ACTIVATE,
AFTER_ACTIVATE,
+
BEFORE_PASSIVATE,
AFTER_PASSIVATE,
+
BEFORE_CLOSE,
- AFTER_CLOSE
+ AFTER_CLOSE,
+
+ BEFORE_QUIESCE,
+ AFTER_QUIESCE,
+ BEFORE_RESTART,
+
+ PERSISTENT_MESSAGE_SIZE_OVERFULL,
+ PERSISTENT_MESSAGE_SIZE_UNDERFULL
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java b/java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java
index 21ae3924b8..bf3de2611d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java
@@ -24,9 +24,12 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Map;
+import org.apache.log4j.Logger;
+
public class EventManager
{
private Map<Event, List<EventListener>> _listeners = new EnumMap<Event, List<EventListener>> (Event.class);
+ private static final Logger _LOGGER = Logger.getLogger(EventManager.class);
public synchronized void addEventListener(EventListener listener, Event... events)
{
@@ -46,6 +49,11 @@ public class EventManager
{
if (_listeners.containsKey(event))
{
+ if(_LOGGER.isDebugEnabled())
+ {
+ _LOGGER.debug("Received event " + event);
+ }
+
for (EventListener listener : _listeners.get(event))
{
listener.event(event);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java b/java/broker/src/main/java/org/apache/qpid/server/store/HAMessageStore.java
index 8724f102c6..59483751ca 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/HAMessageStore.java
@@ -19,19 +19,11 @@
*/
package org.apache.qpid.server.store;
-public class MemoryMessageStoreFactory implements MessageStoreFactory
+public interface HAMessageStore extends MessageStore
{
-
- @Override
- public MessageStore createMessageStore()
- {
- return new MemoryMessageStore();
- }
-
- @Override
- public String getStoreClassName()
- {
- return MemoryMessageStore.class.getSimpleName();
- }
-
+ /**
+ * Used to indicate that a store requires to make itself unavailable for read and read/write
+ * operations.
+ */
+ void passivate();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
index 59624b7a75..262d7d0213 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java
@@ -83,19 +83,19 @@ public class MemoryMessageStore extends NullMessageStore
@Override
public void configureConfigStore(String name, ConfigurationRecoveryHandler recoveryHandler, Configuration config) throws Exception
{
- _stateManager.attainState(State.CONFIGURING);
+ _stateManager.attainState(State.INITIALISING);
}
@Override
public void configureMessageStore(String name, MessageStoreRecoveryHandler recoveryHandler, TransactionLogRecoveryHandler tlogRecoveryHandler, Configuration config) throws Exception
{
- _stateManager.attainState(State.CONFIGURED);
+ _stateManager.attainState(State.INITIALISED);
}
@Override
public void activate() throws Exception
{
- _stateManager.attainState(State.RECOVERING);
+ _stateManager.attainState(State.ACTIVATING);
_stateManager.attainState(State.ACTIVE);
}
@@ -134,4 +134,10 @@ public class MemoryMessageStore extends NullMessageStore
{
_eventManager.addEventListener(eventListener, events);
}
+
+ @Override
+ public String getStoreType()
+ {
+ return "Memory";
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
index cf08ee00ff..0acaf164d9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java
index aba7456a44..728da23f28 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java
@@ -23,5 +23,7 @@ public class MessageStoreConstants
{
public static final String ENVIRONMENT_PATH_PROPERTY = "environment-path";
+ public static final String OVERFULL_SIZE_PROPERTY = "overfull-size";
+ public static final String UNDERFULL_SIZE_PROPERTY = "underfull-size";
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
index 34c7d2d933..be08e309e6 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java b/java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java
index caff17daa5..4ab1a3ab05 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java
@@ -33,7 +33,14 @@ public class OperationalLoggingListener implements EventListener
private OperationalLoggingListener(final MessageStore store, LogSubject logSubject)
{
_logSubject = logSubject;
- store.addEventListener(this, Event.BEFORE_INIT, Event.AFTER_INIT, Event.BEFORE_ACTIVATE, Event.AFTER_ACTIVATE, Event.AFTER_CLOSE);
+ store.addEventListener(this,
+ Event.BEFORE_INIT,
+ Event.AFTER_INIT,
+ Event.BEFORE_ACTIVATE,
+ Event.AFTER_ACTIVATE,
+ Event.AFTER_CLOSE,
+ Event.PERSISTENT_MESSAGE_SIZE_OVERFULL,
+ Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL);
_store = store;
}
@@ -62,7 +69,13 @@ public class OperationalLoggingListener implements EventListener
case AFTER_CLOSE:
CurrentActor.get().message(_logSubject,MessageStoreMessages.CLOSED());
break;
-
+ case PERSISTENT_MESSAGE_SIZE_OVERFULL:
+ CurrentActor.get().message(_logSubject,MessageStoreMessages.OVERFULL());
+ break;
+ case PERSISTENT_MESSAGE_SIZE_UNDERFULL:
+ CurrentActor.get().message(_logSubject,MessageStoreMessages.UNDERFULL());
+ break;
+
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/State.java b/java/broker/src/main/java/org/apache/qpid/server/store/State.java
index 7cbdede85e..2783637b2a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/State.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/State.java
@@ -20,19 +20,30 @@
*/
package org.apache.qpid.server.store;
+import org.apache.qpid.server.configuration.ConfiguredObject;
+
public enum State
{
-
+ /** The initial state of the store. In practice, the store immediately transitions to the subsequent states. */
INITIAL,
- CONFIGURING,
- CONFIGURED,
- RECOVERING,
+
+ INITIALISING,
+ /**
+ * The initial set-up of the store has completed.
+ * If the store is persistent, it has not yet loaded configuration for {@link ConfiguredObject}'s from disk.
+ *
+ * From the point of view of the user, the store is essentially stopped.
+ */
+ INITIALISED,
+
+ ACTIVATING,
ACTIVE,
- QUIESCING,
- QUIESCED,
+
CLOSING,
- CLOSED;
-
+ CLOSED,
+ QUIESCING,
+ /** The virtual host (and implicitly also the store) has been manually paused by the user to allow configuration changes to take place */
+ QUIESCED;
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java b/java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java
index 5998be5bb6..613b329beb 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java
@@ -24,6 +24,8 @@ package org.apache.qpid.server.store;
import java.util.EnumMap;
import java.util.Map;
+import org.apache.qpid.server.store.StateManager.Transition;
+
public class StateManager
{
private State _state = State.INITIAL;
@@ -70,16 +72,23 @@ public class StateManager
}
- public static final Transition CONFIGURE = new Transition(State.INITIAL, State.CONFIGURING, Event.BEFORE_INIT);
- public static final Transition CONFIGURE_COMPLETE = new Transition(State.CONFIGURING, State.CONFIGURED, Event.AFTER_INIT);
- public static final Transition RECOVER = new Transition(State.CONFIGURED, State.RECOVERING, Event.BEFORE_ACTIVATE);
- public static final Transition ACTIVATE = new Transition(State.RECOVERING, State.ACTIVE, Event.AFTER_ACTIVATE);
+ public static final Transition INITIALISE = new Transition(State.INITIAL, State.INITIALISING, Event.BEFORE_INIT);
+ public static final Transition INITALISE_COMPLETE = new Transition(State.INITIALISING, State.INITIALISED, Event.AFTER_INIT);
+
+ public static final Transition ACTIVATE = new Transition(State.INITIALISED, State.ACTIVATING, Event.BEFORE_ACTIVATE);
+ public static final Transition ACTIVATE_COMPLETE = new Transition(State.ACTIVATING, State.ACTIVE, Event.AFTER_ACTIVATE);
+
+ public static final Transition CLOSE_INITIALISED = new Transition(State.INITIALISED, State.CLOSING, Event.BEFORE_CLOSE);;
public static final Transition CLOSE_ACTIVE = new Transition(State.ACTIVE, State.CLOSING, Event.BEFORE_CLOSE);
public static final Transition CLOSE_QUIESCED = new Transition(State.QUIESCED, State.CLOSING, Event.BEFORE_CLOSE);
public static final Transition CLOSE_COMPLETE = new Transition(State.CLOSING, State.CLOSED, Event.AFTER_CLOSE);
- public static final Transition QUIESCE = new Transition(State.ACTIVE, State.QUIESCING, Event.BEFORE_PASSIVATE);
- public static final Transition QUIESCE_COMPLETE = new Transition(State.QUIESCING, State.QUIESCED, Event.BEFORE_PASSIVATE);
- public static final Transition RESTART = new Transition(State.QUIESCED, State.RECOVERING, Event.BEFORE_ACTIVATE);
+
+ public static final Transition PASSIVATE = new Transition(State.ACTIVE, State.INITIALISED, Event.BEFORE_PASSIVATE);
+
+ public static final Transition QUIESCE = new Transition(State.ACTIVE, State.QUIESCING, Event.BEFORE_QUIESCE);
+ public static final Transition QUIESCE_COMPLETE = new Transition(State.QUIESCING, State.QUIESCED, Event.AFTER_QUIESCE);
+
+ public static final Transition RESTART = new Transition(State.QUIESCED, State.ACTIVATING, Event.BEFORE_RESTART);
public StateManager(final EventManager eventManager)
@@ -105,16 +114,6 @@ public class StateManager
return _state;
}
- public synchronized void stateTransition(final State current, final State desired)
- {
- if (_state != current)
- {
- throw new IllegalStateException("Cannot transition to the state: " + desired + "; need to be in state: " + current
- + "; currently in state: " + _state);
- }
- attainState(desired);
- }
-
public synchronized void attainState(State desired)
{
Transition transition = null;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
index 0371cdcfcb..154d7e6535 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java
@@ -31,6 +31,7 @@ import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.sql.Blob;
+import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
@@ -59,6 +60,7 @@ import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
+import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler;
import org.apache.qpid.server.store.ConfiguredObjectHelper;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.Event;
@@ -77,6 +79,9 @@ import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.Transaction;
import org.apache.qpid.server.store.TransactionLogRecoveryHandler;
import org.apache.qpid.server.store.TransactionLogResource;
+import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BindingRecoveryHandler;
+import org.apache.qpid.server.store.ConfigurationRecoveryHandler.ExchangeRecoveryHandler;
+import org.apache.qpid.server.store.ConfigurationRecoveryHandler.QueueRecoveryHandler;
/**
* An implementation of a {@link MessageStore} that uses Apache Derby as the persistence
@@ -111,6 +116,7 @@ public class DerbyMessageStore implements MessageStore
private static Class<Driver> DRIVER_CLASS;
+ public static final String MEMORY_STORE_LOCATION = ":memory:";
private final AtomicLong _messageId = new AtomicLong(0);
private AtomicBoolean _closed = new AtomicBoolean(false);
@@ -230,10 +236,17 @@ 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();
+ private long _totalStoreSize;
+ private boolean _limitBusted;
+ private long _persistentSizeLowThreshold;
+ private long _persistentSizeHighThreshold;
+
private MessageStoreRecoveryHandler _messageRecoveryHandler;
private TransactionLogRecoveryHandler _tlogRecoveryHandler;
@@ -253,7 +266,7 @@ public class DerbyMessageStore implements MessageStore
ConfigurationRecoveryHandler configRecoveryHandler,
Configuration storeConfiguration) throws Exception
{
- _stateManager.attainState(State.CONFIGURING);
+ _stateManager.attainState(State.INITIALISING);
_configRecoveryHandler = configRecoveryHandler;
commonConfiguration(name, storeConfiguration);
@@ -269,13 +282,13 @@ public class DerbyMessageStore implements MessageStore
_tlogRecoveryHandler = tlogRecoveryHandler;
_messageRecoveryHandler = recoveryHandler;
- _stateManager.attainState(State.CONFIGURED);
+ _stateManager.attainState(State.INITIALISED);
}
@Override
public void activate() throws Exception
{
- _stateManager.attainState(State.RECOVERING);
+ _stateManager.attainState(State.ACTIVATING);
// this recovers durable exchanges, queues, and bindings
recoverConfiguration(_configRecoveryHandler);
@@ -296,19 +309,39 @@ public class DerbyMessageStore implements MessageStore
final String databasePath = storeConfiguration.getString(MessageStoreConstants.ENVIRONMENT_PATH_PROPERTY, System.getProperty("QPID_WORK")
+ File.separator + "derbyDB");
- File environmentPath = new File(databasePath);
- if (!environmentPath.exists())
+ if(!MEMORY_STORE_LOCATION.equals(databasePath))
{
- if (!environmentPath.mkdirs())
+ File environmentPath = new File(databasePath);
+ if (!environmentPath.exists())
{
- throw new IllegalArgumentException("Environment path " + environmentPath + " could not be read or created. "
- + "Ensure the path is correct and that the permissions are correct.");
+ if (!environmentPath.mkdirs())
+ {
+ throw new IllegalArgumentException("Environment path " + environmentPath + " could not be read or created. "
+ + "Ensure the path is correct and that the permissions are correct.");
+ }
}
}
_storeLocation = databasePath;
+ _persistentSizeHighThreshold = storeConfiguration.getLong(MessageStoreConstants.OVERFULL_SIZE_PROPERTY, -1l);
+ _persistentSizeLowThreshold = storeConfiguration.getLong(MessageStoreConstants.UNDERFULL_SIZE_PROPERTY, _persistentSizeHighThreshold);
+ if(_persistentSizeLowThreshold > _persistentSizeHighThreshold || _persistentSizeLowThreshold < 0l)
+ {
+ _persistentSizeLowThreshold = _persistentSizeHighThreshold;
+ }
+
createOrOpenDatabase(name, databasePath);
+
+ Connection conn = newAutoCommitConnection();;
+ try
+ {
+ _totalStoreSize = getSizeOnDisk(conn);
+ }
+ finally
+ {
+ conn.close();
+ }
}
private static synchronized void initialiseDriver() throws ClassNotFoundException
@@ -322,7 +355,7 @@ public class DerbyMessageStore implements MessageStore
private void createOrOpenDatabase(String name, final String environmentPath) throws SQLException
{
//FIXME this the _vhost name should not be added here, but derby wont use an empty directory as was possibly just created.
- _connectionURL = "jdbc:derby:" + environmentPath + "/" + name + ";create=true";
+ _connectionURL = "jdbc:derby" + (environmentPath.equals(MEMORY_STORE_LOCATION) ? environmentPath : ":" + environmentPath + "/") + name + ";create=true";
Connection conn = newAutoCommitConnection();
@@ -529,16 +562,17 @@ public class DerbyMessageStore implements MessageStore
try
{
List<ConfiguredObjectRecord> configuredObjects = loadConfiguredObjects();
- ConfigurationRecoveryHandler.QueueRecoveryHandler qrh = recoveryHandler.begin(this);
- _configuredObjectHelper.recoverQueues(qrh, configuredObjects);
- ConfigurationRecoveryHandler.ExchangeRecoveryHandler erh = qrh.completeQueueRecovery();
+ ExchangeRecoveryHandler erh = recoveryHandler.begin(this);
_configuredObjectHelper.recoverExchanges(erh, configuredObjects);
- ConfigurationRecoveryHandler.BindingRecoveryHandler brh = erh.completeExchangeRecovery();
+ QueueRecoveryHandler qrh = erh.completeExchangeRecovery();
+ _configuredObjectHelper.recoverQueues(qrh, configuredObjects);
+
+ BindingRecoveryHandler brh = qrh.completeQueueRecovery();
_configuredObjectHelper.recoverBindings(brh, configuredObjects);
- ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
+ BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
recoverBrokerLinks(lrh);
}
catch (SQLException e)
@@ -689,7 +723,7 @@ public class DerbyMessageStore implements MessageStore
public void close() throws Exception
{
_closed.getAndSet(true);
- _stateManager.stateTransition(State.ACTIVE, State.CLOSING);
+ _stateManager.attainState(State.CLOSING);
try
{
@@ -710,7 +744,7 @@ public class DerbyMessageStore implements MessageStore
}
}
- _stateManager.stateTransition(State.CLOSING, State.CLOSED);
+ _stateManager.attainState(State.CLOSED);
}
@Override
@@ -956,8 +990,8 @@ public class DerbyMessageStore implements MessageStore
try
{
- stmt.setLong(1, link.getId().getLeastSignificantBits());
- stmt.setLong(2, link.getId().getMostSignificantBits());
+ stmt.setLong(1, link.getQMFId().getLeastSignificantBits());
+ stmt.setLong(2, link.getQMFId().getMostSignificantBits());
ResultSet rs = stmt.executeQuery();
try
{
@@ -970,8 +1004,8 @@ public class DerbyMessageStore implements MessageStore
try
{
- insertStmt.setLong(1, link.getId().getLeastSignificantBits());
- insertStmt.setLong(2, link.getId().getMostSignificantBits());
+ insertStmt.setLong(1, link.getQMFId().getLeastSignificantBits());
+ insertStmt.setLong(2, link.getQMFId().getMostSignificantBits());
insertStmt.setLong(3, link.getCreateTime());
byte[] argumentBytes = convertStringMapToBytes(link.getArguments());
@@ -1048,8 +1082,8 @@ public class DerbyMessageStore implements MessageStore
{
conn = newAutoCommitConnection();
stmt = conn.prepareStatement(DELETE_FROM_LINKS);
- stmt.setLong(1, link.getId().getLeastSignificantBits());
- stmt.setLong(2, link.getId().getMostSignificantBits());
+ stmt.setLong(1, link.getQMFId().getLeastSignificantBits());
+ stmt.setLong(2, link.getQMFId().getMostSignificantBits());
int results = stmt.executeUpdate();
if (results == 0)
@@ -1085,7 +1119,7 @@ public class DerbyMessageStore implements MessageStore
try
{
- UUID id = bridge.getId();
+ UUID id = bridge.getQMFId();
stmt.setLong(1, id.getLeastSignificantBits());
stmt.setLong(2, id.getMostSignificantBits());
ResultSet rs = stmt.executeQuery();
@@ -1105,7 +1139,7 @@ public class DerbyMessageStore implements MessageStore
insertStmt.setLong(3, bridge.getCreateTime());
- UUID linkId = bridge.getLink().getId();
+ UUID linkId = bridge.getLink().getQMFId();
insertStmt.setLong(4, linkId.getLeastSignificantBits());
insertStmt.setLong(5, linkId.getMostSignificantBits());
@@ -1151,8 +1185,8 @@ public class DerbyMessageStore implements MessageStore
{
conn = newAutoCommitConnection();
stmt = conn.prepareStatement(DELETE_FROM_BRIDGES);
- stmt.setLong(1, bridge.getId().getLeastSignificantBits());
- stmt.setLong(2, bridge.getId().getMostSignificantBits());
+ stmt.setLong(1, bridge.getQMFId().getLeastSignificantBits());
+ stmt.setLong(2, bridge.getQMFId().getMostSignificantBits());
int results = stmt.executeUpdate();
if (results == 0)
@@ -1541,7 +1575,7 @@ public class DerbyMessageStore implements MessageStore
buf = buf.slice();
MessageMetaDataType type = MessageMetaDataType.values()[dataAsBytes[0]];
StorableMessageMetaData metaData = type.getFactory().createMetaData(buf);
- StoredDerbyMessage message = new StoredDerbyMessage(messageId, metaData, false);
+ StoredDerbyMessage message = new StoredDerbyMessage(messageId, metaData, true);
messageHandler.message(message);
}
@@ -1921,6 +1955,7 @@ public class DerbyMessageStore implements MessageStore
private class DerbyTransaction implements Transaction
{
private final ConnectionWrapper _connWrapper;
+ private int _storeSizeIncrease;
private DerbyTransaction()
@@ -1938,18 +1973,19 @@ public class DerbyMessageStore implements MessageStore
@Override
public void enqueueMessage(TransactionLogResource queue, EnqueableMessage message) throws AMQStoreException
{
- if(message.getStoredMessage() instanceof StoredDerbyMessage)
+ final StoredMessage storedMessage = message.getStoredMessage();
+ if(storedMessage instanceof StoredDerbyMessage)
{
try
{
- ((StoredDerbyMessage)message.getStoredMessage()).store(_connWrapper.getConnection());
+ ((StoredDerbyMessage) storedMessage).store(_connWrapper.getConnection());
}
catch (SQLException e)
{
throw new AMQStoreException("Exception on enqueuing message " + _messageId, e);
}
}
-
+ _storeSizeIncrease += storedMessage.getMetaData().getContentSize();
DerbyMessageStore.this.enqueueMessage(_connWrapper, queue, message.getMessageNumber());
}
@@ -1964,12 +2000,15 @@ public class DerbyMessageStore implements MessageStore
public void commitTran() throws AMQStoreException
{
DerbyMessageStore.this.commitTran(_connWrapper);
+ storedSizeChange(_storeSizeIncrease);
}
@Override
public StoreFuture commitTranAsync() throws AMQStoreException
{
- return DerbyMessageStore.this.commitTranAsync(_connWrapper);
+ final StoreFuture storeFuture = DerbyMessageStore.this.commitTranAsync(_connWrapper);
+ storedSizeChange(_storeSizeIncrease);
+ return storeFuture;
}
@Override
@@ -1998,6 +2037,8 @@ public class DerbyMessageStore implements MessageStore
{
private final long _messageId;
+ private final boolean _isRecovered;
+
private StorableMessageMetaData _metaData;
private volatile SoftReference<StorableMessageMetaData> _metaDataRef;
private byte[] _data;
@@ -2006,21 +2047,21 @@ public class DerbyMessageStore implements MessageStore
StoredDerbyMessage(long messageId, StorableMessageMetaData metaData)
{
- this(messageId, metaData, true);
+ this(messageId, metaData, false);
}
StoredDerbyMessage(long messageId,
- StorableMessageMetaData metaData, boolean persist)
+ StorableMessageMetaData metaData, boolean isRecovered)
{
_messageId = messageId;
+ _isRecovered = isRecovered;
-
- _metaDataRef = new SoftReference<StorableMessageMetaData>(metaData);
- if(persist)
+ if(!_isRecovered)
{
_metaData = metaData;
}
+ _metaDataRef = new SoftReference<StorableMessageMetaData>(metaData);
}
@Override
@@ -2101,16 +2142,17 @@ public class DerbyMessageStore implements MessageStore
@Override
public synchronized StoreFuture flushToStore()
{
+ Connection conn = null;
try
{
- if(_metaData != null)
+ if(!stored())
{
- Connection conn = newConnection();
+ conn = newConnection();
store(conn);
conn.commit();
- conn.close();
+ storedSizeChange(getMetaData().getContentSize());
}
}
catch (SQLException e)
@@ -2121,12 +2163,24 @@ public class DerbyMessageStore implements MessageStore
}
throw new RuntimeException(e);
}
+ finally
+ {
+ closeConnection(conn);
+ }
return StoreFuture.IMMEDIATE_FUTURE;
}
+ @Override
+ public void remove()
+ {
+ int delta = getMetaData().getContentSize();
+ DerbyMessageStore.this.removeMessage(_messageId);
+ storedSizeChange(-delta);
+ }
+
private synchronized void store(final Connection conn) throws SQLException
{
- if(_metaData != null)
+ if (!stored())
{
try
{
@@ -2139,18 +2193,17 @@ public class DerbyMessageStore implements MessageStore
_metaData = null;
_data = null;
}
- }
- if(_logger.isDebugEnabled())
- {
- _logger.debug("Storing message " + _messageId + " to store");
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Storing message " + _messageId + " to store");
+ }
}
}
- @Override
- public void remove()
+ private boolean stored()
{
- DerbyMessageStore.this.removeMessage(_messageId);
+ return _metaData == null || _isRecovered;
}
}
@@ -2446,4 +2499,181 @@ public class DerbyMessageStore implements MessageStore
}
return results;
}
+
+ private synchronized void storedSizeChange(final int delta)
+ {
+ if(getPersistentSizeHighThreshold() > 0)
+ {
+ synchronized(this)
+ {
+ // the delta supplied is an approximation of a store size change. we don;t want to check the statistic every
+ // time, so we do so only when there's been enough change that it is worth looking again. We do this by
+ // assuming the total size will change by less than twice the amount of the message data change.
+ long newSize = _totalStoreSize += 3*delta;
+
+ Connection conn = null;
+ try
+ {
+
+ if(!_limitBusted && newSize > getPersistentSizeHighThreshold())
+ {
+ conn = newAutoCommitConnection();
+ _totalStoreSize = getSizeOnDisk(conn);
+ if(_totalStoreSize > getPersistentSizeHighThreshold())
+ {
+ _limitBusted = true;
+ _eventManager.notifyEvent(Event.PERSISTENT_MESSAGE_SIZE_OVERFULL);
+ }
+ }
+ else if(_limitBusted && newSize < getPersistentSizeLowThreshold())
+ {
+ long oldSize = _totalStoreSize;
+ conn = newAutoCommitConnection();
+ _totalStoreSize = getSizeOnDisk(conn);
+ if(oldSize <= _totalStoreSize)
+ {
+
+ reduceSizeOnDisk(conn);
+
+ _totalStoreSize = getSizeOnDisk(conn);
+ }
+
+ if(_totalStoreSize < getPersistentSizeLowThreshold())
+ {
+ _limitBusted = false;
+ _eventManager.notifyEvent(Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL);
+ }
+
+
+ }
+ }
+ catch (SQLException e)
+ {
+ closeConnection(conn);
+ throw new RuntimeException("Exception will processing store size change", e);
+ }
+ }
+ }
+ }
+
+ private void reduceSizeOnDisk(Connection conn)
+ {
+ CallableStatement cs = null;
+ PreparedStatement stmt = null;
+ try
+ {
+ String tableQuery =
+ "SELECT S.SCHEMANAME, T.TABLENAME FROM SYS.SYSSCHEMAS S, SYS.SYSTABLES T WHERE S.SCHEMAID = T.SCHEMAID AND T.TABLETYPE='T'";
+ stmt = conn.prepareStatement(tableQuery);
+ ResultSet rs = null;
+
+ List<String> schemas = new ArrayList<String>();
+ List<String> tables = new ArrayList<String>();
+
+ try
+ {
+ rs = stmt.executeQuery();
+ while(rs.next())
+ {
+ schemas.add(rs.getString(1));
+ tables.add(rs.getString(2));
+ }
+ }
+ finally
+ {
+ if(rs != null)
+ {
+ rs.close();
+ }
+ }
+
+
+ cs = conn.prepareCall
+ ("CALL SYSCS_UTIL.SYSCS_COMPRESS_TABLE(?, ?, ?)");
+
+ for(int i = 0; i < schemas.size(); i++)
+ {
+ cs.setString(1, schemas.get(i));
+ cs.setString(2, tables.get(i));
+ cs.setShort(3, (short) 0);
+ cs.execute();
+ }
+ }
+ catch (SQLException e)
+ {
+ closeConnection(conn);
+ throw new RuntimeException("Error reducing on disk size", e);
+ }
+ finally
+ {
+ closePreparedStatement(stmt);
+ closePreparedStatement(cs);
+ }
+
+ }
+
+ private long getSizeOnDisk(Connection conn)
+ {
+ PreparedStatement stmt = null;
+ try
+ {
+ String sizeQuery = "SELECT SUM(T2.NUMALLOCATEDPAGES * T2.PAGESIZE) TOTALSIZE" +
+ " FROM " +
+ " SYS.SYSTABLES systabs," +
+ " TABLE (SYSCS_DIAG.SPACE_TABLE(systabs.tablename)) AS T2" +
+ " WHERE systabs.tabletype = 'T'";
+
+ stmt = conn.prepareStatement(sizeQuery);
+
+ ResultSet rs = null;
+ long size = 0l;
+
+ try
+ {
+ rs = stmt.executeQuery();
+ while(rs.next())
+ {
+ size = rs.getLong(1);
+ }
+ }
+ finally
+ {
+ if(rs != null)
+ {
+ rs.close();
+ }
+ }
+
+ return size;
+
+ }
+ catch (SQLException e)
+ {
+ closeConnection(conn);
+ throw new RuntimeException("Error establishing on disk size", e);
+ }
+ finally
+ {
+ closePreparedStatement(stmt);
+ }
+
+ }
+
+
+ private long getPersistentSizeLowThreshold()
+ {
+ return _persistentSizeLowThreshold;
+ }
+
+ private long getPersistentSizeHighThreshold()
+ {
+ return _persistentSizeHighThreshold;
+ }
+
+ @Override
+ public String getStoreType()
+ {
+ return DERBY_STORE_TYPE;
+ }
+
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
index 6b2dff7165..efedad1181 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
index 62e94f6f2e..f38e23b342 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java
index cf2754862d..8f3822be6c 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java
index 1e37675c98..826082cc65 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java
index 66825caa24..8911754a66 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
index 1f25c215cc..c92853e400 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
+++ b/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;
@@ -75,7 +76,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
private final AtomicReference<State> _state = new AtomicReference<State>(State.ACTIVE);
- private AMQQueue.Context _queueContext;
+ private volatile AMQQueue.Context _queueContext;
private final ClientDeliveryMethod _deliveryMethod;
private final RecordDeliveryMethod _recordMethod;
@@ -90,10 +91,15 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
private final long _subscriptionID;
private LogSubject _logSubject;
private LogActor _logActor;
- private UUID _id;
+ private UUID _qmfId;
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();
@@ -389,7 +391,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
_queue = queue;
- _id = getConfigStore().createId();
+ _qmfId = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
_logSubject = new SubscriptionLogSubject(this);
@@ -468,11 +470,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
_deleted.set(true);
}
- public boolean filtersMessages()
- {
- return _filters != null || _noLocal;
- }
-
public boolean hasInterest(QueueEntry entry)
{
//check that the message hasn't been rejected
@@ -508,13 +505,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
- private String id = String.valueOf(System.identityHashCode(this));
-
- private String debugIdentity()
- {
- return id;
- }
-
private boolean checkFilters(QueueEntry msg)
{
return (_filters == null) || _filters.allAllow(msg);
@@ -599,6 +589,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 +682,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
{
_deliveryMethod.deliverToClient(this,entry,deliveryTag);
_deliveredCount.incrementAndGet();
+ _deliveredBytes.addAndGet(entry.getSize());
}
@@ -771,9 +767,10 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return true;
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public boolean isDurable()
@@ -832,4 +829,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/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 76d975a789..dfd9315226 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -98,7 +98,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private final Lock _stateChangeLock = new ReentrantLock();
private final AtomicReference<State> _state = new AtomicReference<State>(State.ACTIVE);
- private AMQQueue.Context _queueContext;
+ private volatile AMQQueue.Context _queueContext;
private final AtomicBoolean _deleted = new AtomicBoolean(false);
@@ -125,11 +125,15 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private LogActor _logActor;
private final Map<String, Object> _properties = new ConcurrentHashMap<String, Object>();
- private UUID _id;
+ private UUID _qmfId;
private String _traceExclude;
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,10 +189,10 @@ 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();
+ _qmfId = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
String filterLogString = null;
@@ -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()
@@ -990,9 +1011,10 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return _flowMode.toString();
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
public String getName()
@@ -1073,4 +1095,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/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
index 637ea7dffc..7c4188bfcd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index c38f3d0761..f21026794f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -20,6 +20,14 @@
*/
package org.apache.qpid.server.transport;
+import java.security.Principal;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.security.auth.Subject;
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.configuration.ConnectionConfig;
@@ -28,12 +36,9 @@ 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;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Connection;
@@ -48,17 +53,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;
-import javax.management.JMException;
-import javax.security.auth.Subject;
-import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-
-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;
@@ -67,24 +62,19 @@ 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;
+ private Principal _peerPrincipal;
+
public ServerConnection(final long connectionId)
{
_connectionId = connectionId;
}
- public UUID getId()
- {
- return _config.getId();
- }
-
public Object getReference()
{
return _reference;
@@ -100,12 +90,12 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
protected void setState(State state)
{
super.setState(state);
-
+
if (state == State.OPEN)
{
if (_onOpenTask != null)
{
- _onOpenTask.run();
+ _onOpenTask.run();
}
_actor.message(ConnectionMessages.OPEN(getClientId(), "0-10", getClientVersion(), true, true, true));
@@ -118,7 +108,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
{
_virtualHost.getConnectionRegistry().deregisterConnection(this);
}
- unregisterConnectionMbean();
}
if (state == State.CLOSED)
@@ -156,8 +145,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
_virtualHost = virtualHost;
initialiseStatistics();
-
- registerConnectionMbean();
}
public void setConnectionConfig(final ConnectionConfig config)
@@ -193,7 +180,7 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
((ServerSession)session).close();
}
-
+
public LogSubject getLogSubject()
{
return (LogSubject) this;
@@ -273,7 +260,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
{
@@ -286,6 +272,46 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
close(replyCode, message);
}
+ public synchronized void block()
+ {
+ if(!_blocking)
+ {
+ _blocking = true;
+ for(AMQSessionModel ssn : getSessionModels())
+ {
+ ssn.block();
+ }
+ }
+ }
+
+ public synchronized void unblock()
+ {
+ if(_blocking)
+ {
+ _blocking = false;
+ for(AMQSessionModel ssn : getSessionModels())
+ {
+ ssn.unblock();
+ }
+ }
+ }
+
+ @Override
+ public synchronized void registerSession(final Session ssn)
+ {
+ super.registerSession(ssn);
+ if(_blocking)
+ {
+ ((ServerSession)ssn).block();
+ }
+ }
+
+ @Override
+ public synchronized void removeSession(final Session ssn)
+ {
+ super.removeSession(ssn);
+ }
+
public List<AMQSessionModel> getSessionModels()
{
List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
@@ -298,44 +324,38 @@ 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);
}
-
+
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();
@@ -346,25 +366,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
*/
@@ -389,7 +396,7 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
else
{
_authorizedSubject = authorizedSubject;
- _authorizedPrincipal = UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
+ _authorizedPrincipal = authorizedSubject.getPrincipals().iterator().next();
}
}
@@ -408,6 +415,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();
@@ -436,12 +448,6 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
}
}
-
- public ManagedObject getManagedObject()
- {
- return _mBean;
- }
-
@Override
public void send(ProtocolEvent event)
{
@@ -449,53 +455,38 @@ public class ServerConnection extends Connection implements Managable, AMQConnec
super.send(event);
}
- public AtomicLong getLastIoTime()
+ public long getLastIoTime()
{
- return _lastIoTime;
+ return _lastIoTime.longValue();
}
- void checkForNotification()
+ public String getClientId()
{
- int channelsCount = getSessionModels().size();
- if (_mBean != null && channelsCount >= getConnectionDelegate().getChannelMax())
- {
- _mBean.notifyClients("Channel count (" + channelsCount + ") has reached the threshold value");
- }
+ return getConnectionDelegate().getClientId();
}
- private void registerConnectionMbean()
+ public String getClientVersion()
{
- try
- {
- _mBean = new ServerConnectionMBean(this);
- _mBean.register();
- }
- catch (JMException jme)
- {
- log.error("Unable to register mBean for ServerConnection", jme);
- }
+ return getConnectionDelegate().getClientVersion();
}
- private void unregisterConnectionMbean()
+ public String getPrincipalAsString()
{
- if (_mBean != null)
- {
- if (log.isDebugEnabled())
- {
- log.debug("Unregistering mBean for ServerConnection" + _mBean);
- }
- _mBean.unregister();
- _mBean = null;
- }
+ return getAuthorizedPrincipal().getName();
}
- public String getClientId()
+ public long getSessionCountLimit()
{
- return getConnectionDelegate().getClientId();
+ return getChannelMax();
}
- public String getClientVersion()
+ public Principal getPeerPrincipal()
{
- return getConnectionDelegate().getClientVersion();
+ return _peerPrincipal;
+ }
+
+ public void setPeerPrincipal(Principal peerPrincipal)
+ {
+ _peerPrincipal = peerPrincipal;
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index 5460c89eab..c13f63b44d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -20,18 +20,26 @@
*/
package org.apache.qpid.server.transport;
-import static org.apache.qpid.transport.Connection.State.CLOSE_RCVD;
-
+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 java.util.StringTokenizer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import org.apache.qpid.common.ServerPropertyNames;
import org.apache.qpid.properties.ConnectionStartProperties;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.configuration.BrokerConfig;
import org.apache.qpid.server.protocol.AMQConnectionModel;
-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.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.subscription.Subscription_0_10;
import org.apache.qpid.server.virtualhost.State;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -39,16 +47,7 @@ import org.apache.qpid.transport.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-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 java.util.StringTokenizer;
+import static org.apache.qpid.transport.Connection.State.CLOSE_RCVD;
public class ServerConnectionDelegate extends ServerDelegate
{
@@ -58,22 +57,25 @@ public class ServerConnectionDelegate extends ServerDelegate
private final IApplicationRegistry _appRegistry;
private int _maxNoOfChannels;
private Map<String,Object> _clientProperties;
+ private final AuthenticationManager _authManager;
- public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN)
+ public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager)
{
- this(createConnectionProperties(appRegistry.getBroker()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
+ this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager);
}
- public ServerConnectionDelegate(Map<String, Object> properties,
+ private ServerConnectionDelegate(Map<String, Object> properties,
List<Object> locales,
IApplicationRegistry appRegistry,
- String localFQDN)
+ String localFQDN,
+ AuthenticationManager authManager)
{
- super(properties, parseToList(appRegistry.getAuthenticationManager().getMechanisms()), locales);
-
+ super(properties, parseToList(authManager.getMechanisms()), locales);
+
_appRegistry = appRegistry;
_localFQDN = localFQDN;
- _maxNoOfChannels = ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount();
+ _maxNoOfChannels = appRegistry.getConfiguration().getMaxChannelCount();
+ _authManager = authManager;
}
private static Map<String, Object> createConnectionProperties(final BrokerConfig brokerConfig)
@@ -108,18 +110,17 @@ public class ServerConnectionDelegate extends ServerDelegate
return ssn;
}
- protected SaslServer createSaslServer(String mechanism) throws SaslException
+ protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException
{
- return _appRegistry.getAuthenticationManager().createSaslServer(mechanism, _localFQDN);
+ return _authManager.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
}
protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
{
- final AuthenticationResult authResult = _appRegistry.getAuthenticationManager().authenticate(ss, response);
final ServerConnection sconn = (ServerConnection) conn;
-
-
+ final AuthenticationResult authResult = _authManager.authenticate(ss, response);
+
if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
{
tuneAuthorizedConnection(sconn);
@@ -168,7 +169,7 @@ public class ServerConnectionDelegate extends ServerDelegate
vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName);
SecurityManager.setThreadSubject(sconn.getAuthorizedSubject());
-
+
if(vhost != null)
{
sconn.setVirtualHost(vhost);
@@ -194,7 +195,7 @@ public class ServerConnectionDelegate extends ServerDelegate
sconn.setState(Connection.State.CLOSING);
sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'"));
}
-
+
}
@Override
@@ -216,7 +217,7 @@ public class ServerConnectionDelegate extends ServerDelegate
setConnectionTuneOkChannelMax(sconn, okChannelMax);
}
-
+
@Override
protected int getHeartbeatMax()
{
@@ -225,7 +226,7 @@ public class ServerConnectionDelegate extends ServerDelegate
}
@Override
- protected int getChannelMax()
+ public int getChannelMax()
{
return _maxNoOfChannels;
}
@@ -265,7 +266,6 @@ public class ServerConnectionDelegate extends ServerDelegate
if(isSessionNameUnique(atc.getName(), conn))
{
super.sessionAttach(conn, atc);
- ((ServerConnection)conn).checkForNotification();
}
else
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java
deleted file mode 100644
index bb545164fb..0000000000
--- a/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/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index 6f979e035e..f82b25b3d6 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -20,17 +20,11 @@
*/
package org.apache.qpid.server.transport;
-import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
-import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.message.MessageMetaData_0_10;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.server.txn.RollbackOnlyDtxException;
-import org.apache.qpid.server.txn.TimeoutDtxException;
-import static org.apache.qpid.util.Serial.gt;
-
import java.security.Principal;
import java.text.MessageFormat;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -40,18 +34,16 @@ import java.util.SortedMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-
import javax.security.auth.Subject;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.server.TransactionTimeoutHelper;
import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ConfiguredObject;
import org.apache.qpid.server.configuration.ConnectionConfig;
@@ -63,7 +55,10 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ChannelMessages;
import org.apache.qpid.server.logging.subjects.ChannelLogSubject;
+import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.message.MessageMetaData_0_10;
import org.apache.qpid.server.message.MessageReference;
+import org.apache.qpid.server.message.MessageTransferMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
@@ -82,20 +77,25 @@ import org.apache.qpid.server.txn.IncorrectDtxStateException;
import org.apache.qpid.server.txn.JoinAndResumeDtxException;
import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.NotAssociatedDtxException;
+import org.apache.qpid.server.txn.RollbackOnlyDtxException;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.txn.SuspendAndFailDtxException;
+import org.apache.qpid.server.txn.TimeoutDtxException;
import org.apache.qpid.server.txn.UnknownDtxBranchException;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ServerSession extends Session
- implements AuthorizationHolder, SessionConfig,
+import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
+import static org.apache.qpid.util.Serial.gt;
+
+public class ServerSession extends Session
+ implements AuthorizationHolder, SessionConfig,
AMQSessionModel, LogSubject, AsyncAutoCommitTransaction.FutureRecorder
{
private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class);
-
+
private static final String NULL_DESTINTATION = UUID.randomUUID().toString();
private static final int PRODUCER_CREDIT_TOPUP_THRESHOLD = 1 << 30;
private static final int UNFINISHED_COMMAND_QUEUE_THRESHOLD = 500;
@@ -105,7 +105,7 @@ public class ServerSession extends Session
private long _createTime = System.currentTimeMillis();
private LogActor _actor = GenericActor.getInstance(this);
- private final Set<AMQQueue> _blockingQueues = new ConcurrentSkipListSet<AMQQueue>();
+ private final Set<Object> _blockingEntities = Collections.synchronizedSet(new HashSet<Object>());
private final AtomicBoolean _blocking = new AtomicBoolean(false);
private ChannelLogSubject _logSubject;
@@ -145,6 +145,8 @@ public class ServerSession extends Session
private final List<Task> _taskList = new CopyOnWriteArrayList<Task>();
+ private final TransactionTimeoutHelper _transactionTimeoutHelper;
+
ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
{
this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig());
@@ -158,6 +160,8 @@ public class ServerSession extends Session
_logSubject = new ChannelLogSubject(this);
_id = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
+
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
}
protected void setState(State state)
@@ -167,9 +171,19 @@ public class ServerSession extends Session
if (state == State.OPEN)
{
_actor.message(ChannelMessages.CREATE());
+ if(_blocking.get())
+ {
+ invokeBlock();
+ }
}
}
+ private void invokeBlock()
+ {
+ invoke(new MessageSetFlowMode("", MessageFlowMode.CREDIT));
+ invoke(new MessageStop(""));
+ }
+
private ConfigStore getConfigStore()
{
return getConnectionConfig().getConfigStore();
@@ -455,7 +469,7 @@ public class ServerSession extends Session
{
return _transaction.isTransactional();
}
-
+
public boolean inTransaction()
{
return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
@@ -621,16 +635,26 @@ 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();
}
-
+
public Subject getAuthorizedSubject()
{
return getConnection().getAuthorizedSubject();
@@ -661,7 +685,8 @@ public class ServerSession extends Session
return (VirtualHost) _connectionConfig.getVirtualHost();
}
- public UUID getId()
+ @Override
+ public UUID getQMFId()
{
return _id;
}
@@ -755,63 +780,85 @@ public class ServerSession extends Session
long openTime = currentTime - _transaction.getTransactionStartTime();
long idleTime = currentTime - _txnUpdateTime.get();
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.IDLE_TXN(idleTime));
- _logger.warn("IDLE TRANSACTION ALERT " + getLogSubject().toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + getLogSubject().toString() + " " + openTime + " ms");
- }
-
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
+ _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime),
+ TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT);
+ if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose))
{
getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
+ return;
}
- else if (openClose > 0L && openTime > openClose)
+
+ _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime),
+ TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT);
+ if (_transactionTimeoutHelper.isTimedOut(openTime, openClose))
{
getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
+ return;
}
}
}
public void block(AMQQueue queue)
{
+ block(queue, queue.getName());
+ }
+
+ public void block()
+ {
+ block(this, "** All Queues **");
+ }
- if(_blockingQueues.add(queue))
- {
- if(_blocking.compareAndSet(false,true))
+ private void block(Object queue, String name)
+ {
+ synchronized (_blockingEntities)
+ {
+ if(_blockingEntities.add(queue))
{
- invoke(new MessageSetFlowMode("", MessageFlowMode.CREDIT));
- invoke(new MessageStop(""));
- _actor.message(_logSubject, ChannelMessages.FLOW_ENFORCED(queue.getNameShortString().toString()));
- }
+
+ if(_blocking.compareAndSet(false,true))
+ {
+ if(getState() == State.OPEN)
+ {
+ invokeBlock();
+ }
+ _actor.message(_logSubject, ChannelMessages.FLOW_ENFORCED(name));
+ }
+ }
}
}
public void unblock(AMQQueue queue)
{
- if(_blockingQueues.remove(queue) && _blockingQueues.isEmpty())
+ unblock((Object)queue);
+ }
+
+ public void unblock()
+ {
+ unblock(this);
+ }
+
+ private void unblock(Object queue)
+ {
+ synchronized(_blockingEntities)
{
- if(_blocking.compareAndSet(true,false) && !isClosing())
+ if(_blockingEntities.remove(queue) && _blockingEntities.isEmpty())
{
+ if(_blocking.compareAndSet(true,false) && !isClosing())
+ {
- _actor.message(_logSubject, ChannelMessages.FLOW_REMOVED());
- MessageFlow mf = new MessageFlow();
- mf.setUnit(MessageCreditUnit.MESSAGE);
- mf.setDestination("");
- _outstandingCredit.set(Integer.MAX_VALUE);
- mf.setValue(Integer.MAX_VALUE);
- invoke(mf);
+ _actor.message(_logSubject, ChannelMessages.FLOW_REMOVED());
+ MessageFlow mf = new MessageFlow();
+ mf.setUnit(MessageCreditUnit.MESSAGE);
+ mf.setDestination("");
+ _outstandingCredit.set(Integer.MAX_VALUE);
+ mf.setValue(Integer.MAX_VALUE);
+ invoke(mf);
+ }
}
}
}
@@ -1020,7 +1067,12 @@ public class ServerSession extends Session
public int compareTo(AMQSessionModel session)
{
- return getId().compareTo(session.getId());
+ return getQMFId().compareTo(session.getQMFId());
}
+ @Override
+ public int getConsumerCount()
+ {
+ return _subscriptions.values().size();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index 79a8bc0e4c..05963ee874 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -99,9 +99,9 @@ public class ServerSessionDelegate extends SessionDelegate
Object newOutstanding = ((ServerSession)session).getAsyncCommandMark();
if(newOutstanding == null || newOutstanding == asyncCommandMark)
{
- session.processed(method);
+ session.processed(method);
}
-
+
if(newOutstanding != null)
{
((ServerSession)session).completeAsyncCommands();
@@ -240,13 +240,13 @@ public class ServerSessionDelegate extends SessionDelegate
}
FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L,0L);
-
+
FilterManager filterManager = null;
- try
+ try
{
filterManager = FilterManagerFactory.createManager(method.getArguments());
- }
- catch (AMQException amqe)
+ }
+ catch (AMQException amqe)
{
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Exception Creating FilterManager");
return;
@@ -257,7 +257,7 @@ public class ServerSessionDelegate extends SessionDelegate
method.getAcceptMode(),
method.getAcquireMode(),
MessageFlowMode.WINDOW,
- creditManager,
+ creditManager,
filterManager,
method.getArguments());
@@ -297,13 +297,13 @@ public class ServerSessionDelegate extends SessionDelegate
final MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
messageMetaData.setConnectionReference(((ServerSession)ssn).getReference());
-
+
if (!getVirtualHost(ssn).getSecurityManager().authorisePublish(messageMetaData.isImmediate(), messageMetaData.getRoutingKey(), exchange.getName()))
{
ExecutionErrorCode errorCode = ExecutionErrorCode.UNAUTHORIZED_ACCESS;
String description = "Permission denied: exchange-name '" + exchange.getName() + "'";
exception(ssn, xfr, errorCode, description);
-
+
return;
}
@@ -807,7 +807,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
- // TODO decouple AMQException and AMQConstant error codes
+ // TODO decouple AMQException and AMQConstant error codes
private void exception(Session session, Method method, AMQException exception, String message)
{
ExecutionErrorCode errorCode = ExecutionErrorCode.INTERNAL_ERROR;
@@ -823,7 +823,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
String description = message + "': " + exception.getMessage();
-
+
exception(session, method, errorCode, description);
}
@@ -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);
}
@@ -1349,9 +1345,9 @@ public class ServerSessionDelegate extends SessionDelegate
+ " as exclusive queue with same name "
+ "declared on another session";
ExecutionErrorCode errorCode = ExecutionErrorCode.RESOURCE_LOCKED;
-
+
exception(session, method, errorCode, description);
-
+
return;
}
}
@@ -1389,7 +1385,7 @@ public class ServerSessionDelegate extends SessionDelegate
{
String owner = body.getExclusive() ? session.getClientID() : null;
- final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateUUID(), queueName, body.getDurable(), owner,
+ final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateQueueUUID(queueName, virtualHost.getName()), queueName, body.getDurable(), owner,
body.getAutoDelete(), body.getExclusive(), virtualHost, body.getArguments());
return queue;
@@ -1436,7 +1432,7 @@ public class ServerSessionDelegate extends SessionDelegate
else
{
VirtualHost virtualHost = getVirtualHost(session);
-
+
try
{
queue.delete();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java
index d446434d24..efd7850a49 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java
@@ -44,11 +44,16 @@ import java.util.List;
*/
public class AsyncAutoCommitTransaction implements ServerTransaction
{
+ static final String QPID_STRICT_ORDER_WITH_MIXED_DELIVERY_MODE = "qpid.strict_order_with_mixed_delivery_mode";
+
protected static final Logger _logger = Logger.getLogger(AsyncAutoCommitTransaction.class);
private final MessageStore _messageStore;
private final FutureRecorder _futureRecorder;
+ //Set true to ensure strict ordering when enqueing messages with mixed delivery mode, i.e. disable async persistence
+ private boolean _strictOrderWithMixedDeliveryMode = Boolean.getBoolean(QPID_STRICT_ORDER_WITH_MIXED_DELIVERY_MODE);
+
public static interface FutureRecorder
{
public void recordFuture(StoreFuture future, Action action);
@@ -129,6 +134,23 @@ public class AsyncAutoCommitTransaction implements ServerTransaction
}
}
+ private void addEnqueueFuture(final StoreFuture future, final Action action, boolean persistent)
+ {
+ if(action != null)
+ {
+ // For persistent messages, do not synchronously invoke postCommit even if the future is completed.
+ // Otherwise, postCommit (which actually does the enqueuing) might be called on successive messages out of order.
+ if(future.isComplete() && !persistent && !_strictOrderWithMixedDeliveryMode)
+ {
+ action.postCommit();
+ }
+ else
+ {
+ _futureRecorder.recordFuture(future, action);
+ }
+ }
+ }
+
public void dequeue(Collection<QueueEntry> queueEntries, Action postTransactionAction)
{
Transaction txn = null;
@@ -203,7 +225,7 @@ public class AsyncAutoCommitTransaction implements ServerTransaction
{
future = StoreFuture.IMMEDIATE_FUTURE;
}
- addFuture(future, postTransactionAction);
+ addEnqueueFuture(future, postTransactionAction, message.isPersistent());
postTransactionAction = null;
}
catch (AMQException e)
@@ -257,7 +279,7 @@ public class AsyncAutoCommitTransaction implements ServerTransaction
{
future = StoreFuture.IMMEDIATE_FUTURE;
}
- addFuture(future, postTransactionAction);
+ addEnqueueFuture(future, postTransactionAction, message.isPersistent());
postTransactionAction = null;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java
index 3ac71fc6a6..fb32b654ce 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java
@@ -98,12 +98,29 @@ public class DtxBranch
public void setTimeout(long timeout)
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Setting timeout to " + timeout + "s for DtxBranch " + _xid);
+ }
+
if(_timeoutFuture != null)
{
- _timeoutFuture.cancel(false);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Attempting to cancel previous timeout task future for DtxBranch " + _xid);
+ }
+
+ boolean succeeded = _timeoutFuture.cancel(false);
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Cancelling previous timeout task " + (succeeded ? "succeeded" : "failed")
+ + " for DtxBranch " + _xid);
+ }
}
+
_timeout = timeout;
- _expiration = timeout == 0 ? 0 : System.currentTimeMillis() + timeout;
+ _expiration = timeout == 0 ? 0 : System.currentTimeMillis() + (1000 * timeout);
if(_timeout == 0)
{
@@ -111,10 +128,23 @@ public class DtxBranch
}
else
{
- _timeoutFuture = _vhost.scheduleTask(_timeout, new Runnable()
+ long delay = 1000*_timeout;
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Scheduling timeout and rollback after " + delay/1000 +
+ "s for DtxBranch " + _xid);
+ }
+
+ _timeoutFuture = _vhost.scheduleTask(delay, new Runnable()
{
public void run()
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Timing out DtxBranch " + _xid);
+ }
+
setState(State.TIMEDOUT);
try
{
@@ -122,8 +152,7 @@ public class DtxBranch
}
catch (AMQStoreException e)
{
- _logger.error("Unexpected error when attempting to rollback XA transaction ("+
- _xid + ") due to timeout", e);
+ _logger.error("Unexpected error when attempting to rollback DtxBranch "+ _xid + " due to timeout", e);
throw new RuntimeException(e);
}
}
@@ -199,6 +228,10 @@ public class DtxBranch
public void prepare() throws AMQStoreException
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Performing prepare for DtxBranch " + _xid);
+ }
Transaction txn = _store.newTransaction();
txn.recordXid(_xid.getFormat(),
@@ -213,12 +246,27 @@ public class DtxBranch
public synchronized void rollback() throws AMQStoreException
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Performing rollback for DtxBranch " + _xid);
+ }
+
if(_timeoutFuture != null)
{
- _timeoutFuture.cancel(false);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Attempting to cancel previous timeout task future for DtxBranch " + _xid);
+ }
+
+ boolean succeeded = _timeoutFuture.cancel(false);
_timeoutFuture = null;
- }
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Cancelling previous timeout task " + (succeeded ? "succeeded" : "failed")
+ + " for DtxBranch " + _xid);
+ }
+ }
if(_transaction != null)
{
@@ -240,10 +288,26 @@ public class DtxBranch
public void commit() throws AMQStoreException
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Performing commit for DtxBranch " + _xid);
+ }
+
if(_timeoutFuture != null)
{
- _timeoutFuture.cancel(false);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Attempting to cancel previous timeout task future for DtxBranch " + _xid);
+ }
+
+ boolean succeeded = _timeoutFuture.cancel(false);
_timeoutFuture = null;
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Cancelling previous timeout task " + (succeeded ? "succeeded" : "failed")
+ + " for DtxBranch " + _xid);
+ }
}
if(_transaction == null)
@@ -342,7 +406,7 @@ public class DtxBranch
}
catch(AMQStoreException e)
{
- _logger.error("Error while closing XA branch", e);
+ _logger.error("Error while closing DtxBranch " + _xid, e);
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java
index 5c54c1164f..117beb82ef 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java
@@ -37,7 +37,7 @@ public class DtxRegistry
private static final class ComparableXid
{
private final Xid _xid;
-
+
private ComparableXid(Xid xid)
{
_xid = xid;
@@ -58,7 +58,7 @@ public class DtxRegistry
ComparableXid that = (ComparableXid) o;
return compareBytes(_xid.getBranchId(), that._xid.getBranchId())
- && compareBytes(_xid.getGlobalId(), that._xid.getGlobalId());
+ && compareBytes(_xid.getGlobalId(), that._xid.getGlobalId());
}
private static boolean compareBytes(byte[] a, byte[] b)
@@ -94,7 +94,7 @@ public class DtxRegistry
return result;
}
}
-
+
public synchronized DtxBranch getBranch(Xid xid)
{
return _branches.get(new ComparableXid(xid));
@@ -116,7 +116,7 @@ public class DtxRegistry
return (_branches.remove(new ComparableXid(branch.getXid())) != null);
}
- public void commit(Xid id, boolean onePhase)
+ public synchronized void commit(Xid id, boolean onePhase)
throws IncorrectDtxStateException, UnknownDtxBranchException, AMQStoreException, RollbackOnlyDtxException, TimeoutDtxException
{
DtxBranch branch = getBranch(id);
@@ -204,7 +204,7 @@ public class DtxRegistry
}
}
- public void rollback(Xid id)
+ public synchronized void rollback(Xid id)
throws IncorrectDtxStateException,
UnknownDtxBranchException,
AMQStoreException, TimeoutDtxException
@@ -318,6 +318,7 @@ public class DtxRegistry
branch.disassociateSession(session);
}
}
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
index 11401ebd65..3fbcff7e2c 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.txn;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,7 +18,9 @@ package org.apache.qpid.server.txn;
* under the License.
*
*/
+package org.apache.qpid.server.txn;
+import org.apache.qpid.server.store.StoreFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,6 +51,7 @@ public class LocalTransaction implements ServerTransaction
private volatile Transaction _transaction;
private MessageStore _transactionLog;
private long _txnStartTime = 0L;
+ private StoreFuture _asyncTran;
public LocalTransaction(MessageStore transactionLog)
{
@@ -68,11 +70,13 @@ public class LocalTransaction implements ServerTransaction
public void addPostTransactionAction(Action postTransactionAction)
{
+ sync();
_postTransactionActions.add(postTransactionAction);
}
public void dequeue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction)
{
+ sync();
_postTransactionActions.add(postTransactionAction);
if(message.isPersistent() && queue.isDurable())
@@ -98,6 +102,7 @@ public class LocalTransaction implements ServerTransaction
public void dequeue(Collection<QueueEntry> queueEntries, Action postTransactionAction)
{
+ sync();
_postTransactionActions.add(postTransactionAction);
try
@@ -131,10 +136,7 @@ public class LocalTransaction implements ServerTransaction
{
try
{
- for(Action action : _postTransactionActions)
- {
- action.onRollback();
- }
+ doRollbackActions();
}
finally
{
@@ -151,7 +153,7 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ resetDetails();
}
}
@@ -176,6 +178,7 @@ public class LocalTransaction implements ServerTransaction
public void enqueue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction)
{
+ sync();
_postTransactionActions.add(postTransactionAction);
if(message.isPersistent() && queue.isDurable())
@@ -201,6 +204,7 @@ public class LocalTransaction implements ServerTransaction
public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
{
+ sync();
_postTransactionActions.add(postTransactionAction);
if (_txnStartTime == 0L)
@@ -239,11 +243,13 @@ public class LocalTransaction implements ServerTransaction
public void commit()
{
+ sync();
commit(null);
}
public void commit(Runnable immediateAction)
{
+ sync();
try
{
if(_transaction != null)
@@ -256,29 +262,137 @@ public class LocalTransaction implements ServerTransaction
immediateAction.run();
}
- for(int i = 0; i < _postTransactionActions.size(); i++)
+ doPostTransactionActions();
+ }
+ catch (Exception e)
+ {
+ _logger.error("Failed to commit transaction", e);
+
+ doRollbackActions();
+ throw new RuntimeException("Failed to commit transaction", e);
+ }
+ finally
+ {
+ resetDetails();
+ }
+ }
+
+ private void doRollbackActions()
+ {
+ for(Action action : _postTransactionActions)
+ {
+ action.onRollback();
+ }
+ }
+
+ public StoreFuture commitAsync(final Runnable deferred)
+ {
+ sync();
+ try
+ {
+ StoreFuture future = StoreFuture.IMMEDIATE_FUTURE;
+ if(_transaction != null)
{
- _postTransactionActions.get(i).postCommit();
+ future = new StoreFuture()
+ {
+ private volatile boolean _completed = false;
+ private StoreFuture _underlying = _transaction.commitTranAsync();
+
+ @Override
+ public boolean isComplete()
+ {
+ return _completed || checkUnderlyingCompletion();
+ }
+
+ @Override
+ public void waitForCompletion()
+ {
+ if(!_completed)
+ {
+ _underlying.waitForCompletion();
+ checkUnderlyingCompletion();
+ }
+ }
+
+ private synchronized boolean checkUnderlyingCompletion()
+ {
+ if(!_completed && _underlying.isComplete())
+ {
+ completeDeferredWork();
+ _completed = true;
+ }
+ return _completed;
+
+ }
+
+ private void completeDeferredWork()
+ {
+ try
+ {
+ doPostTransactionActions();
+ deferred.run();
+
+ }
+ catch (Exception e)
+ {
+ _logger.error("Failed to commit transaction", e);
+
+ doRollbackActions();
+ throw new RuntimeException("Failed to commit transaction", e);
+ }
+ finally
+ {
+ resetDetails();
+ }
+ }
+
+ };
+ _asyncTran = future;
}
+ else
+ {
+ try
+ {
+ doPostTransactionActions();
+
+ deferred.run();
+ }
+ finally
+ {
+ resetDetails();
+ }
+ }
+
+ return future;
}
catch (Exception e)
{
_logger.error("Failed to commit transaction", e);
-
- for(Action action : _postTransactionActions)
+ try
{
- action.onRollback();
+ doRollbackActions();
+ }
+ finally
+ {
+ resetDetails();
}
throw new RuntimeException("Failed to commit transaction", e);
}
- finally
+
+
+ }
+
+ private void doPostTransactionActions()
+ {
+ for(int i = 0; i < _postTransactionActions.size(); i++)
{
- resetDetails();
+ _postTransactionActions.get(i).postCommit();
}
}
public void rollback()
{
+ sync();
try
{
if(_transaction != null)
@@ -295,10 +409,7 @@ public class LocalTransaction implements ServerTransaction
{
try
{
- for(Action action : _postTransactionActions)
- {
- action.onRollback();
- }
+ doRollbackActions();
}
finally
{
@@ -306,9 +417,19 @@ public class LocalTransaction implements ServerTransaction
}
}
}
-
+
+ public void sync()
+ {
+ if(_asyncTran != null)
+ {
+ _asyncTran.waitForCompletion();
+ _asyncTran = null;
+ }
+ }
+
private void resetDetails()
{
+ _asyncTran = null;
_transaction = null;
_postTransactionActions.clear();
_txnStartTime = 0L;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
index 523bafb8e1..1b0e50fd34 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
@@ -44,9 +44,9 @@ public abstract class HouseKeepingTask implements Runnable
final public void run()
{
- // Don't need to undo this as this is a thread pool thread so will
- // always go through here before we do any real work.
+ String originalThreadName = Thread.currentThread().getName();
Thread.currentThread().setName(_name);
+
CurrentActor.set(new AbstractActor(_rootLogger)
{
@Override
@@ -67,6 +67,9 @@ public abstract class HouseKeepingTask implements Runnable
finally
{
CurrentActor.remove();
+
+ // eagerly revert the thread name to make thread dumps more meaningful if captured after task has finished
+ Thread.currentThread().setName(originalThreadName);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java
index fb50b3e289..55e2539dcf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java
@@ -25,5 +25,7 @@ public enum State
INITIALISING,
ACTIVE,
PASSIVE,
- STOPPED
+ STOPPED,
+ /** Terminal state that signifies the virtual host has experienced an unexpected condition. */
+ ERRORED
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index 489b985222..f810360662 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/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,10 +61,10 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
void close();
- ManagedObject getManagedObject();
-
UUID getBrokerId();
+ UUID getId();
+
void scheduleHouseKeepingTask(long period, HouseKeepingTask task);
long getHouseKeepingTaskCount();
@@ -74,7 +73,7 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
int getHouseKeepingPoolSize();
- void setHouseKeepingPoolSize(int newSize);
+ void setHouseKeepingPoolSize(int newSize);
int getHouseKeepingActiveCount();
@@ -102,4 +101,8 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask);
State getState();
+
+ public void block();
+
+ public void unblock();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
index e956806823..ea2f0f15e4 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
@@ -76,15 +76,12 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
private final VirtualHost _virtualHost;
- private MessageStoreLogSubject _logSubject;
-
- private MessageStore _store;
-
private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>();
- private Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>();
- private Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>();
-
+ private final Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>();
+ private final Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>();
+ private MessageStoreLogSubject _logSubject;
+ private MessageStore _store;
public VirtualHostConfigRecoveryHandler(VirtualHost virtualHost)
{
@@ -100,7 +97,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 +108,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));
@@ -120,12 +128,12 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
catch (AMQException e)
{
- // TODO
- throw new RuntimeException(e);
+ throw new RuntimeException("Error recovering queue uuid " + id + " name " + queueName, e);
}
}
- public ExchangeRecoveryHandler completeQueueRecovery()
+ @Override
+ public BindingRecoveryHandler completeQueueRecovery()
{
return this;
}
@@ -145,19 +153,17 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
catch (AMQException e)
{
- // TODO
- throw new RuntimeException(e);
+ throw new RuntimeException("Error recovering exchange uuid " + id + " name " + exchangeName, e);
}
}
- public BindingRecoveryHandler completeExchangeRecovery()
+ public QueueRecoveryHandler completeExchangeRecovery()
{
return this;
}
public StoredMessageRecoveryHandler begin()
{
- // TODO - log begin
return this;
}
@@ -182,7 +188,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
public void completeMessageRecovery()
{
- //TODO - log end
}
public BridgeRecoveryHandler brokerLink(final UUID id,
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 9b113525d4..d9dc0aa64e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/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,10 @@ 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.model.UUIDGenerator;
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;
@@ -59,37 +66,25 @@ import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.store.Event;
import org.apache.qpid.server.store.EventListener;
+import org.apache.qpid.server.store.HAMessageStore;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.MessageStoreFactory;
import org.apache.qpid.server.store.OperationalLoggingListener;
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
+public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.RegistryChangeListener, EventListener
{
private static final Logger _logger = Logger.getLogger(VirtualHostImpl.class);
private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5;
- private final UUID _id;
+ private final UUID _qmfId;
private final String _name;
+ private final UUID _id;
+
private final long _createTime = System.currentTimeMillis();
private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>();
@@ -104,10 +99,6 @@ public class VirtualHostImpl implements VirtualHost
private final VirtualHostConfiguration _vhostConfig;
- private final VirtualHostMBean _virtualHostMBean;
-
- private final AMQBrokerManagerMBean _brokerMBean;
-
private final QueueRegistry _queueRegistry;
private final ExchangeRegistry _exchangeRegistry;
@@ -122,13 +113,12 @@ public class VirtualHostImpl implements VirtualHost
private final MessageStore _messageStore;
- private State _state = State.INITIALISING;
-
- private boolean _statisticsEnabled = false;
+ private volatile State _state = State.INITIALISING;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>();
+ private boolean _blocked;
public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception
{
@@ -143,20 +133,21 @@ public class VirtualHostImpl implements VirtualHost
}
_appRegistry = appRegistry;
- _brokerConfig = _appRegistry.getBroker();
+ _brokerConfig = _appRegistry.getBrokerConfig();
_vhostConfig = hostConfig;
_name = _vhostConfig.getName();
_dtxRegistry = new DtxRegistry();
- _id = _appRegistry.getConfigStore().createId();
+ _qmfId = _appRegistry.getConfigStore().createId();
+ _id = UUIDGenerator.generateVhostUUID(_name);
CurrentActor.get().message(VirtualHostMessages.CREATED(_name));
- _virtualHostMBean = new VirtualHostMBean();
_securityManager = new SecurityManager(_appRegistry.getSecurityManager());
_securityManager.configureHostPlugins(_vhostConfig);
_connectionRegistry = new ConnectionRegistry();
+ _connectionRegistry.addRegistryChangeListener(this);
_houseKeepingTasks = new ScheduledThreadPoolExecutor(_vhostConfig.getHouseKeepingThreadCount());
@@ -169,15 +160,16 @@ public class VirtualHostImpl implements VirtualHost
_bindingFactory = new BindingFactory(this);
- _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
-
- _messageStore = initialiseMessageStore(hostConfig.getMessageStoreFactoryClass());
+ _messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass());
configureMessageStore(hostConfig);
activateNonHAMessageStore();
initialiseStatistics();
+
+ _messageStore.addEventListener(this, Event.PERSISTENT_MESSAGE_SIZE_OVERFULL);
+ _messageStore.addEventListener(this, Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL);
}
public IConnectionRegistry getConnectionRegistry()
@@ -195,6 +187,12 @@ public class VirtualHostImpl implements VirtualHost
return _id;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return _qmfId;
+ }
+
public VirtualHostConfigType getConfigType()
{
return VirtualHostConfigType.getInstance();
@@ -324,20 +322,19 @@ public class VirtualHostImpl implements VirtualHost
}
- private MessageStore initialiseMessageStore(final String messageStoreFactoryClass) throws Exception
+ private MessageStore initialiseMessageStore(final String messageStoreClass) throws Exception
{
- final Class<?> clazz = Class.forName(messageStoreFactoryClass);
+ final Class<?> clazz = Class.forName(messageStoreClass);
final Object o = clazz.newInstance();
- if (!(o instanceof MessageStoreFactory))
+ if (!(o instanceof MessageStore))
{
- throw new ClassCastException("Message store factory class must implement " + MessageStoreFactory.class +
+ throw new ClassCastException("Message store factory class must implement " + MessageStore.class +
". Class " + clazz + " does not.");
}
- final MessageStoreFactory messageStoreFactory = (MessageStoreFactory) o;
- final MessageStore messageStore = messageStoreFactory.createMessageStore();
- final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, messageStoreFactory.getStoreClassName());
+ final MessageStore messageStore = (MessageStore) o;
+ final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, clazz.getSimpleName());
OperationalLoggingListener.listen(messageStore, storeLogSubject);
messageStore.addEventListener(new BeforeActivationListener(), Event.BEFORE_ACTIVATE);
@@ -361,7 +358,10 @@ public class VirtualHostImpl implements VirtualHost
private void activateNonHAMessageStore() throws Exception
{
- _messageStore.activate();
+ if (!(_messageStore instanceof HAMessageStore))
+ {
+ _messageStore.activate();
+ }
}
private void initialiseModel(VirtualHostConfiguration config) throws ConfigurationException, AMQException
@@ -534,16 +534,6 @@ public class VirtualHostImpl implements VirtualHost
CurrentActor.get().message(VirtualHostMessages.CLOSED());
}
- public ManagedObject getBrokerMBean()
- {
- return _brokerMBean;
- }
-
- public ManagedObject getManagedObject()
- {
- return _virtualHostMBean;
- }
-
public UUID getBrokerId()
{
return _appRegistry.getBrokerId();
@@ -558,54 +548,48 @@ public class VirtualHostImpl implements VirtualHost
{
return _bindingFactory;
}
-
+
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);
}
-
+
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 (AMQConnectionModel connection : _connectionRegistry.getConnections())
{
connection.resetStatistics();
@@ -614,25 +598,12 @@ public class VirtualHostImpl implements VirtualHost
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);
@@ -699,107 +670,155 @@ public class VirtualHostImpl implements VirtualHost
return _dtxRegistry;
}
- @Override
public String toString()
{
return _name;
}
- @Override
public State getState()
{
return _state;
}
-
- /**
- * 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 void block()
{
- public VirtualHostMBean() throws NotCompliantMBeanException
+ synchronized (_connectionRegistry)
{
- super(ManagedVirtualHost.class, ManagedVirtualHost.TYPE);
+ if(!_blocked)
+ {
+ _blocked = true;
+ for(AMQConnectionModel conn : _connectionRegistry.getConnections())
+ {
+ conn.block();
+ }
+ }
}
+ }
- public String getObjectInstanceName()
- {
- return ObjectName.quote(_name);
- }
- public String getName()
+ public void unblock()
+ {
+ synchronized (_connectionRegistry)
{
- return _name;
+ if(_blocked)
+ {
+ _blocked = false;
+ for(AMQConnectionModel conn : _connectionRegistry.getConnections())
+ {
+ conn.unblock();
+ }
+ }
}
+ }
- public VirtualHostImpl getVirtualHost()
+ public void connectionRegistered(final AMQConnectionModel connection)
+ {
+ if(_blocked)
{
- return VirtualHostImpl.this;
+ connection.block();
}
}
- private final class BeforeActivationListener implements EventListener
+ public void connectionUnregistered(final AMQConnectionModel connection)
{
- @Override
- public void event(Event event)
+ }
+
+ public void event(final Event event)
+ {
+ switch(event)
{
- try
- {
- _exchangeRegistry.initialise();
- initialiseModel(_vhostConfig);
- } catch (Exception e)
- {
- throw new RuntimeException("Failed to initialise virtual host after state change", e);
- }
+ case PERSISTENT_MESSAGE_SIZE_OVERFULL:
+ block();
+ break;
+ case PERSISTENT_MESSAGE_SIZE_UNDERFULL:
+ unblock();
+ break;
}
}
- private final class AfterActivationListener implements EventListener
+ private final class BeforeActivationListener implements EventListener
+ {
+ @Override
+ public void event(Event event)
+ {
+ try
+ {
+ _exchangeRegistry.initialise();
+ initialiseModel(_vhostConfig);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to initialise virtual host after state change", e);
+ }
+ }
+ }
+
+ private final class AfterActivationListener implements EventListener
+ {
+ @Override
+ public void event(Event event)
+ {
+ State finalState = State.ERRORED;
+
+ try
+ {
+ initialiseHouseKeeping(_vhostConfig.getHousekeepingCheckPeriod());
+ finalState = State.ACTIVE;
+ }
+ finally
+ {
+ _state = finalState;
+ reportIfError(_state);
+ }
+ }
+ }
+
+ private final class BeforePassivationListener implements EventListener
{
- @Override
public void event(Event event)
{
- initialiseHouseKeeping(_vhostConfig.getHousekeepingCheckPeriod());
+ State finalState = State.ERRORED;
+
try
{
- _brokerMBean.register();
- } catch (JMException e)
+ /* the approach here is not ideal as there is a race condition where a
+ * queue etc could be created while the virtual host is on the way to
+ * the passivated state. However the store state change from MASTER to UNKNOWN
+ * is documented as exceptionally rare..
+ */
+
+ _connectionRegistry.close(IConnectionRegistry.VHOST_PASSIVATE_REPLY_TEXT);
+ removeHouseKeepingTasks();
+
+ _queueRegistry.stopAllAndUnregisterMBeans();
+ _exchangeRegistry.clearAndUnregisterMbeans();
+ _dtxRegistry.close();
+
+ finalState = State.PASSIVE;
+ }
+ finally
{
- throw new RuntimeException("Failed to register virtual host mbean for virtual host " + getName(), e);
+ _state = finalState;
+ reportIfError(_state);
}
-
- _state = State.ACTIVE;
}
+
}
- public class BeforePassivationListener implements EventListener
+ private final class BeforeCloseListener implements EventListener
{
-
@Override
public void event(Event event)
{
- _connectionRegistry.close(IConnectionRegistry.VHOST_PASSIVATE_REPLY_TEXT);
- _brokerMBean.unregister();
- removeHouseKeepingTasks();
-
- _queueRegistry.stopAllAndUnregisterMBeans();
- _exchangeRegistry.clearAndUnregisterMbeans();
- _dtxRegistry.close();
-
- _state = State.PASSIVE;
+ shutdownHouseKeeping();
}
}
- private final class BeforeCloseListener implements EventListener
+ private void reportIfError(State state)
{
- @Override
- public void event(Event event)
+ if (state == State.ERRORED)
{
- _brokerMBean.unregister();
- shutdownHouseKeeping();
+ CurrentActor.get().message(VirtualHostMessages.ERRORED());
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
index ef621a166a..1be472844a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java
+++ b/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/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java
index 2c6705bb3b..bd2e30449a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java
@@ -1,5 +1,6 @@
/*
*
+ * 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
diff --git a/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java b/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java
deleted file mode 100644
index c06ce5e31a..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
deleted file mode 100644
index 5c500771c2..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
+++ /dev/null
@@ -1,195 +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.store.TestableMemoryMessageStoreFactory;
-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.factoryclass", TestableMemoryMessageStoreFactory.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/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java b/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
index bb20e0200b..43824e713f 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
@@ -199,4 +199,31 @@ public class BrokerOptionsTest extends QpidTestCase
_options.setLogWatchFrequency(myFreq);
assertEquals(myFreq, _options.getLogWatchFrequency());
}
+
+ public void testDefaultIncludesPortFor0_10()
+ {
+ assertEquals(Collections.EMPTY_SET, _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ }
+
+ public void testOverriddenIncludesPortFor0_10()
+ {
+ _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1);
+ assertEquals(Collections.singleton(TEST_PORT1), _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ }
+
+ public void testManyOverriddenIncludedPortFor0_10()
+ {
+ _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1);
+ _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT2);
+ final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
+ assertEquals(expectedPorts, _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ }
+
+ public void testDuplicatedOverriddenIncludedPortFor0_10AreSilentlyIgnored()
+ {
+ _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1);
+ _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT2);
+ final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
+ assertEquals(expectedPorts, _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
index 31d5028536..ffd607574e 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
@@ -47,6 +47,11 @@ public class MainTest extends QpidTestCase
{
assertEquals(0, options.getExcludedPorts(pe).size());
}
+
+ for(ProtocolInclusion pe : EnumSet.allOf(ProtocolInclusion.class))
+ {
+ assertEquals(0, options.getIncludedPorts(pe).size());
+ }
}
public void testPortOverriddenSingle()
@@ -162,6 +167,20 @@ public class MainTest extends QpidTestCase
assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h"));
}
+ public void testInclude010()
+ {
+ BrokerOptions options = startDummyMain("-p 5678 --include-0-10 5678");
+
+ assertTrue(options.getPorts().contains(5678));
+ assertEquals(1, options.getPorts().size());
+ assertTrue(options.getIncludedPorts(ProtocolInclusion.v0_10).contains(5678));
+ assertEquals(1, options.getIncludedPorts(ProtocolInclusion.v0_10).size());
+ assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_9_1).size());
+ assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_9).size());
+ assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v0_8).size());
+ assertEquals(0, options.getIncludedPorts(ProtocolInclusion.v1_0).size());
+ }
+
private BrokerOptions startDummyMain(String commandLine)
{
return (new TestMain(commandLine.split("\\s"))).getOptions();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java b/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java
new file mode 100644
index 0000000000..9081dc49d6
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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 static org.mockito.Matchers.any;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class TransactionTimeoutHelperTest extends QpidTestCase
+{
+ private final LogMessage _logMessage = mock(LogMessage.class);
+ private final LogActor _logActor = mock(LogActor.class);
+ private final LogSubject _logSubject = mock(LogSubject.class);
+ private TransactionTimeoutHelper _transactionTimeoutHelper;
+ private RootMessageLogger _rootMessageLogger;
+
+ public void testLogIfNecessary()
+ {
+ _transactionTimeoutHelper.logIfNecessary(99, 100, _logMessage, "");
+ verifyZeroInteractions(_logActor, _logMessage);
+
+ _transactionTimeoutHelper.logIfNecessary(101, 100, _logMessage, "");
+ verify(_logActor).message(_logSubject, _logMessage);
+ }
+
+ public void testLogIfNecessaryWhenOperationalLoggingDisabled()
+ {
+ //disable the operational logging
+ when(_rootMessageLogger.isMessageEnabled(
+ same(_logActor), any(LogSubject.class), any(String.class)))
+ .thenReturn(false);
+
+ //verify the actor is never asked to log a message
+ _transactionTimeoutHelper.logIfNecessary(101, 100, _logMessage, "");
+ verify(_logActor, never()).message(any(LogMessage.class));
+ verify(_logActor, never()).message(any(LogSubject.class), any(LogMessage.class));
+ }
+
+ public void testIsTimedOut()
+ {
+ assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(199,200));
+ assertTrue("Should have timed out", _transactionTimeoutHelper.isTimedOut(201,200));
+ }
+
+ /**
+ * If TransactionTimeout is disabled, the timeout will be 0. This test verifies
+ * that the helper methods respond negatively in this scenario.
+ */
+ public void testTransactionTimeoutDisabled()
+ {
+ assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(201,0));
+
+ _transactionTimeoutHelper.logIfNecessary(99, 0, _logMessage, "");
+ verifyZeroInteractions(_logActor, _logMessage);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ CurrentActor.set(_logActor);
+
+ _rootMessageLogger = mock(RootMessageLogger.class);
+ when(_logActor.getRootMessageLogger()).thenReturn(_rootMessageLogger);
+
+ when(_rootMessageLogger.isMessageEnabled(
+ same(_logActor), any(LogSubject.class), any(String.class)))
+ .thenReturn(true);
+
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java
index c0777d2f8f..00e5cd1222 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java
@@ -25,14 +25,14 @@ import java.util.UUID;
public class MockConnectionConfig implements ConnectionConfig
{
- public MockConnectionConfig(UUID _id, ConnectionConfigType _configType,
+ public MockConnectionConfig(UUID _qmfId, ConnectionConfigType _configType,
ConfiguredObject<ConnectionConfigType, ConnectionConfig> _parent, boolean _durable,
long _createTime, VirtualHostConfig _virtualHost, String _address, Boolean _incoming,
Boolean _systemConnection, Boolean _federationLink, String _authId, String _remoteProcessName,
Integer _remotePID, Integer _remoteParentPID, ConfigStore _configStore, Boolean _shadow)
{
super();
- this._id = _id;
+ this._qmfId = _qmfId;
this._configType = _configType;
this._parent = _parent;
this._durable = _durable;
@@ -50,7 +50,7 @@ public class MockConnectionConfig implements ConnectionConfig
this._shadow = _shadow;
}
- private UUID _id;
+ private UUID _qmfId;
private ConnectionConfigType _configType;
private ConfiguredObject<ConnectionConfigType, ConnectionConfig> _parent;
private boolean _durable;
@@ -68,9 +68,9 @@ public class MockConnectionConfig implements ConnectionConfig
private Boolean _shadow;
@Override
- public UUID getId()
+ public UUID getQMFId()
{
- return _id;
+ return _qmfId;
}
@Override
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
index 36f131a30f..3c5b85cd90 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java
@@ -176,20 +176,29 @@ public class QueueConfigurationTest extends TestCase
assertEquals(1, qConf.getMaximumMessageCount());
}
- public void testGetMinimumAlertRepeatGap() throws ConfigurationException
+ public void testGetMinimumAlertRepeatGap() throws Exception
{
- // Check default value
- QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
- assertEquals(0, qConf.getMinimumAlertRepeatGap());
+ try
+ {
+ ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env));
+ ApplicationRegistry.initialise(registry);
+ // Check default value
+ QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
+ assertEquals(ServerConfiguration.DEFAULT_MINIMUM_ALERT_REPEAT_GAP, qConf.getMinimumAlertRepeatGap());
- // Check explicit value
- VirtualHostConfiguration vhostConfig = overrideConfiguration("minimumAlertRepeatGap", 2);
- qConf = new QueueConfiguration("test", vhostConfig);
- assertEquals(2, qConf.getMinimumAlertRepeatGap());
+ // Check explicit value
+ VirtualHostConfiguration vhostConfig = overrideConfiguration("minimumAlertRepeatGap", 2);
+ qConf = new QueueConfiguration("test", vhostConfig);
+ assertEquals(2, qConf.getMinimumAlertRepeatGap());
- // Check inherited value
- qConf = new QueueConfiguration("test", _fullHostConf);
- assertEquals(1, qConf.getMinimumAlertRepeatGap());
+ // Check inherited value
+ qConf = new QueueConfiguration("test", _fullHostConf);
+ assertEquals(1, qConf.getMinimumAlertRepeatGap());
+ }
+ finally
+ {
+ ApplicationRegistry.remove();
+ }
}
public void testSortQueueConfiguration() throws ConfigurationException
@@ -204,6 +213,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/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index 4caefc2f18..660ff5e7d4 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -25,6 +25,7 @@ import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
import org.apache.qpid.server.util.TestApplicationRegistry;
@@ -251,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
@@ -286,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
@@ -401,7 +394,7 @@ public class ServerConfigurationTest extends QpidTestCase
{
// Check default
_serverConfig.initialise();
- assertEquals(0, _serverConfig.getMinimumAlertRepeatGap());
+ assertEquals(30000l, _serverConfig.getMinimumAlertRepeatGap());
// Check value we set
_config.setProperty("minimumAlertRepeatGap", 10L);
@@ -1588,6 +1581,168 @@ public class ServerConfigurationTest extends QpidTestCase
assertEquals(false, _serverConfig.isAmqp08enabled());
}
+ public void testPortInclude08() throws ConfigurationException
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertEquals(true, _serverConfig.getPortInclude08().isEmpty());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_08, "1");
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_08, "2");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(2, _serverConfig.getPortInclude08().size());
+ assertTrue(_serverConfig.getPortInclude08().contains("1"));
+ assertTrue(_serverConfig.getPortInclude08().contains("2"));
+ }
+
+ public void testPortInclude09() throws ConfigurationException
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertEquals(true, _serverConfig.getPortInclude09().isEmpty());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_09, "3");
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_09, "4");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(2, _serverConfig.getPortInclude09().size());
+ assertTrue(_serverConfig.getPortInclude09().contains("3"));
+ assertTrue(_serverConfig.getPortInclude09().contains("4"));
+ }
+
+ public void testPortInclude091() throws ConfigurationException
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertEquals(true, _serverConfig.getPortInclude091().isEmpty());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_091, "5");
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_091, "6");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(2, _serverConfig.getPortInclude091().size());
+ assertTrue(_serverConfig.getPortInclude091().contains("5"));
+ assertTrue(_serverConfig.getPortInclude091().contains("6"));
+ }
+
+ public void testPortInclude010() throws ConfigurationException
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertEquals(true, _serverConfig.getPortInclude010().isEmpty());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, "7");
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, "8");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(2, _serverConfig.getPortInclude010().size());
+ assertTrue(_serverConfig.getPortInclude010().contains("7"));
+ assertTrue(_serverConfig.getPortInclude010().contains("8"));
+ }
+
+ public void testPortInclude10() throws ConfigurationException
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertEquals(true, _serverConfig.getPortInclude10().isEmpty());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_10, "9");
+ _config.addProperty(ServerConfiguration.CONNECTOR_INCLUDE_10, "10");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(2, _serverConfig.getPortInclude10().size());
+ assertTrue(_serverConfig.getPortInclude10().contains("9"));
+ assertTrue(_serverConfig.getPortInclude10().contains("10"));
+ }
+
+ public void testGetDefaultSupportedProtocolReply() throws Exception
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertNull("unexpected default value", _serverConfig.getDefaultSupportedProtocolReply());
+
+ // Check values we set
+ _config.addProperty(ServerConfiguration.CONNECTOR_AMQP_SUPPORTED_REPLY, "v0_10");
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(AmqpProtocolVersion.v0_10, _serverConfig.getDefaultSupportedProtocolReply());
+ }
+
+ public void testDefaultAuthenticationManager() throws Exception
+ {
+ // Check default
+ _serverConfig.initialise();
+ assertNull("unexpected default value", _serverConfig.getDefaultAuthenticationManager());
+
+ // Check values we set
+ String testAuthManager = "myauthmanager";
+ _config.addProperty("security.default-auth-manager", testAuthManager);
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals(testAuthManager, _serverConfig.getDefaultAuthenticationManager());
+ }
+
+ public void testPortAuthenticationMappingsDefault() throws Exception
+ {
+ _serverConfig.initialise();
+ assertEquals("unexpected default number of port/authmanager mappings", 0, _serverConfig.getPortAuthenticationMappings().size());
+ }
+
+ public void testPortAuthenticationMappingsWithSingleMapping() throws Exception
+ {
+ String testAuthManager = "myauthmanager";
+ _config.addProperty("security.port-mappings.port-mapping.port", 1234);
+ _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager);
+
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+ assertEquals("unexpected number of port/authmanager mappings", 1, _serverConfig.getPortAuthenticationMappings().size());
+ assertEquals("unexpected mapping for port", testAuthManager, _serverConfig.getPortAuthenticationMappings().get(1234));
+ }
+
+ public void testPortAuthenticationMappingsWithManyMapping() throws Exception
+ {
+ String testAuthManager1 = "myauthmanager1";
+ String testAuthManager2 = "myauthmanager2";
+ _config.addProperty("security.port-mappings.port-mapping(-1).port", 1234);
+ _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager1);
+
+ _config.addProperty("security.port-mappings.port-mapping(-1).port", 2345);
+ _config.addProperty("security.port-mappings.port-mapping.auth-manager", testAuthManager2);
+
+ _serverConfig = new ServerConfiguration(_config);
+ _serverConfig.initialise();
+
+ assertEquals("unexpected number of port/authmanager mappings", 2, _serverConfig.getPortAuthenticationMappings().size());
+ assertEquals("unexpected mapping for port", testAuthManager1, _serverConfig.getPortAuthenticationMappings().get(1234));
+ assertEquals("unexpected mapping for port", testAuthManager2, _serverConfig.getPortAuthenticationMappings().get(2345));
+ }
+
+ public void testPortAuthenticationMappingWithMissingAuthManager() throws Exception
+ {
+ _config.addProperty("security.port-mappings.port-mapping(-1).port", 1234);
+ // no auth manager defined for port
+ _serverConfig = new ServerConfiguration(_config);
+ try
+ {
+ _serverConfig.initialise();
+ fail("Exception not thrown");
+ }
+ catch(ConfigurationException ce)
+ {
+ // PASS
+ assertEquals("Incorrect error message",
+ "Validation error: Each port-mapping must have exactly one port and exactly one auth-manager.",
+ ce.getMessage());
+ }
+ }
+
/**
* Convenience method to output required security preamble for broker config
*/
@@ -1605,7 +1760,6 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("\t\t\t\t\t</attribute>\n");
out.write("\t\t\t\t</attributes>\n");
out.write("\t\t\t</principal-database>\n");
- out.write("\t\t\t<jmx-access>/dev/null</jmx-access>\n");
out.write("\t\t</pd-auth-manager>\n");
out.write("\t</security>\n");
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java
index 59cd0cf1db..caf74a89ec 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java
@@ -26,8 +26,8 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
+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.util.InternalBrokerBaseCase;
@@ -77,7 +77,7 @@ public class TopicConfigurationTest extends InternalBrokerBaseCase
public void testSubscriptionWithTopicCreation() throws ConfigurationException, AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(getName()+":stockSubscription"), false, new AMQShortString("testowner"),
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName()+":stockSubscription", false, "testowner",
false, false, getVirtualHost(), null);
getVirtualHost().getQueueRegistry().registerQueue(queue);
@@ -107,7 +107,7 @@ public class TopicConfigurationTest extends InternalBrokerBaseCase
public void testSubscriptionCreation() throws ConfigurationException, AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(getName()+":stockSubscription"), false, new AMQShortString("testowner"),
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID() ,getName()+":stockSubscription", false, "testowner",
false, false, getVirtualHost(), null);
getVirtualHost().getQueueRegistry().registerQueue(queue);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
index c4c93acfb6..50e7f0588b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
@@ -27,7 +27,6 @@ import org.apache.qpid.server.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.store.TestableMemoryMessageStoreFactory;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -162,7 +161,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.queues(-1).queue(-1).name", "r2d2");
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.queues.queue.r2d2.deadLetterQueues", "true");
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.queues(-1).queue(-1).name", "c3p0");
- getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.store.factoryclass", TestableMemoryMessageStoreFactory.class.getName());
+ getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.store.class", TestableMemoryMessageStore.class.getName());
// Start the broker now.
super.createBroker();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index afd8fd9ed2..4befd26ece 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
@@ -83,7 +83,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
protected void unbind(TestQueue queue, String... bindings) throws AMQException
{
String queueName = queue.getName();
- exchange.onUnbind(new Binding(null,queueName, queue, exchange, getHeadersMap(bindings)));
+ exchange.onUnbind(new Binding(null, null, queueName, queue, exchange, getHeadersMap(bindings)));
}
protected int getCount()
@@ -95,7 +95,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
{
TestQueue queue = new TestQueue(new AMQShortString(queueName));
queues.add(queue);
- exchange.onBind(new Binding(null,key, queue, exchange, args));
+ exchange.onBind(new Binding(null, null, key, queue, exchange, args));
return queue;
}
@@ -276,7 +276,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
public TestQueue(AMQShortString name) throws AMQException
{
- super(UUIDGenerator.generateUUID(), name, false, new AMQShortString("test"), true, false,ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"), Collections.EMPTY_MAP);
+ super(UUIDGenerator.generateRandomUUID(), name, false, new AMQShortString("test"), true, false,ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"), Collections.EMPTY_MAP);
ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test").getQueueRegistry().registerQueue(this);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
deleted file mode 100644
index 9034bf9c3a..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
index 4305cdadc6..3988edcb3c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java
+++ b/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;
@@ -143,7 +160,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -154,7 +171,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
matchHeaders.setString("B", "Value of B");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -164,7 +181,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Altered value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -175,7 +192,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -187,7 +204,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -200,7 +217,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
matchHeaders.setString("B", "Value of B");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -214,7 +231,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("B", "Value of B");
matchHeaders.setString("C", "Value of C");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -228,7 +245,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("B", "Altered value of B");
matchHeaders.setString("C", "Value of C");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -239,7 +256,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -251,7 +268,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -264,7 +281,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
matchHeaders.setString("B", "Value of B");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -278,7 +295,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("B", "Value of B");
matchHeaders.setString("C", "Value of C");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -292,7 +309,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("B", "Altered value of B");
matchHeaders.setString("C", "Value of C");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -306,7 +323,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("B", "Altered value of B");
matchHeaders.setString("C", "Value of C");
- Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
index 00c8a18d9f..92274afece 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
@@ -30,6 +30,7 @@ import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -64,8 +65,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testNoRoute() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a*#b"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.*.#.b", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a*#b", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.*.#.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -76,8 +77,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testDirectMatch() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("ab"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.b", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "ab", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -103,8 +104,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testStarMatch() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a*"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.*", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a*", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.*",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -142,8 +143,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashMatch() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a#"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.#", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.#",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -205,8 +206,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMidHash() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.*.#.b", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.*.#.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.d.b");
@@ -235,8 +236,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMatchafterHash() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a#"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.*.#.b.c", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.*.#.b.c",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b");
@@ -281,8 +282,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashAfterHash() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a#"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.*.#.b.c.#.d", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.*.#.b.c.#.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b.c");
@@ -308,8 +309,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashHash() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a#"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.#.*.#.d", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.#.*.#.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b.c");
@@ -334,8 +335,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testSubMatchFails() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.b.c.d", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.b.c.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -364,8 +365,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMoreRouting() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.b", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -379,8 +380,8 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMoreQueue() throws AMQException
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("a"), false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null,"a.b", queue,_exchange, null));
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
+ _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a");
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java
new file mode 100644
index 0000000000..f871baffe6
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.log4j;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Level;
+import org.apache.qpid.util.FileUtils;
+
+import junit.framework.TestCase;
+
+public class LoggingFacadeTest extends TestCase
+{
+ private LoggingFacade _loggingFacade;
+ private String _log4jXmlFile;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _log4jXmlFile = createTestLog4jXml();
+ _loggingFacade = LoggingFacade.configure(_log4jXmlFile);
+ }
+
+ public void testGetAvailableLoggerLevels() throws Exception
+ {
+ List<String> levels = _loggingFacade.getAvailableLoggerLevels();
+ assertTrue(levels.contains("ALL"));
+ assertTrue(levels.contains("TRACE"));
+ assertTrue(levels.contains("DEBUG"));
+ assertTrue(levels.contains("INFO"));
+ assertTrue(levels.contains("WARN"));
+ assertTrue(levels.contains("ERROR"));
+ assertTrue(levels.contains("FATAL"));
+ assertTrue(levels.contains("OFF"));
+ assertEquals(8, levels.size());
+ }
+
+ public void testRetrieveConfigFileRootLoggerLevel() throws Exception
+ {
+ String level = _loggingFacade.retrieveConfigFileRootLoggerLevel();
+ assertEquals(Level.WARN.toString(), level);
+ }
+
+ public void testSetConfigFileRootLoggerLevel() throws Exception
+ {
+ String oldLevel = _loggingFacade.retrieveConfigFileRootLoggerLevel();
+ assertEquals("WARN", oldLevel);
+
+ _loggingFacade.setConfigFileRootLoggerLevel("INFO");
+
+ String level = _loggingFacade.retrieveConfigFileRootLoggerLevel();
+ assertEquals("INFO", level);
+ }
+
+ public void testRetrieveConfigFileLoggerLevels() throws Exception
+ {
+ Map<String, String> levels = _loggingFacade.retrieveConfigFileLoggersLevels();
+ assertEquals(3, levels.size());
+ String abcLevel = levels.get("a.b.c");
+ String abc1Level = levels.get("a.b.c.1");
+ String abc2Level = levels.get("a.b.c.2");
+ assertEquals("INFO", abcLevel);
+ assertEquals("DEBUG", abc1Level);
+ assertEquals("TRACE", abc2Level);
+ }
+
+ public void testSetConfigFileLoggerLevels() throws Exception
+ {
+ final String loggerName = "a.b.c";
+
+ assertConfigFileLoggingLevel(loggerName, "INFO");
+
+ _loggingFacade.setConfigFileLoggerLevel(loggerName, "WARN");
+
+ Map<String, String> levels = _loggingFacade.retrieveConfigFileLoggersLevels();
+ String abcLevel = levels.get(loggerName);
+ assertEquals("WARN", abcLevel);
+ }
+
+ public void testSetConfigFileLoggerLevelsWhereLoggerDoesNotExist() throws Exception
+ {
+ try
+ {
+ _loggingFacade.setConfigFileLoggerLevel("does.not.exist", "WARN");
+ fail("Exception not thrown");
+ }
+ catch (LoggingFacadeException lfe)
+ {
+ // PASS
+ assertEquals("Can't find logger does.not.exist", lfe.getMessage());
+ }
+ }
+
+ public void testRetrieveRuntimeRootLoggerLevel() throws Exception
+ {
+ String level = _loggingFacade.retrieveRuntimeRootLoggerLevel();
+ assertEquals(Level.WARN.toString(), level);
+ }
+
+ public void testSetRuntimeRootLoggerLevel() throws Exception
+ {
+ String oldLevel = _loggingFacade.retrieveRuntimeRootLoggerLevel();
+ assertEquals("WARN", oldLevel);
+
+ _loggingFacade.setRuntimeRootLoggerLevel("INFO");
+
+ String level = _loggingFacade.retrieveRuntimeRootLoggerLevel();
+ assertEquals("INFO", level);
+ }
+
+ public void testRetrieveRuntimeLoggersLevels() throws Exception
+ {
+ Map<String, String> levels = _loggingFacade.retrieveRuntimeLoggersLevels();
+ // Don't assert size as implementation itself uses logging and we'd count its loggers too
+ String abcLevel = levels.get("a.b.c");
+ String abc1Level = levels.get("a.b.c.1");
+ String abc2Level = levels.get("a.b.c.2");
+ assertEquals("INFO", abcLevel);
+ assertEquals("DEBUG", abc1Level);
+ assertEquals("TRACE", abc2Level);
+ }
+
+ public void testSetRuntimeLoggerLevel() throws Exception
+ {
+ final String loggerName = "a.b.c";
+
+ assertRuntimeLoggingLevel(loggerName, "INFO");
+
+ _loggingFacade.setRuntimeLoggerLevel(loggerName, "WARN");
+
+ assertRuntimeLoggingLevel(loggerName, "WARN");
+ }
+
+ public void testSetRuntimeLoggerToInheritFromParent() throws Exception
+ {
+ final String parentLoggerName = "a.b.c";
+ final String childLoggerName = "a.b.c.1";
+
+ assertRuntimeLoggingLevel(parentLoggerName, "INFO");
+ assertRuntimeLoggingLevel(childLoggerName, "DEBUG");
+
+ _loggingFacade.setRuntimeLoggerLevel(childLoggerName, null);
+
+ assertRuntimeLoggingLevel(parentLoggerName, "INFO");
+ assertRuntimeLoggingLevel(childLoggerName, "INFO");
+ }
+
+ public void testSetRuntimeLoggerLevelsWhereLoggerDoesNotExist() throws Exception
+ {
+ final String loggerName = "does.not.exist2";
+
+ Map<String, String> oldLevels = _loggingFacade.retrieveRuntimeLoggersLevels();
+ assertFalse(oldLevels.containsKey(loggerName));
+
+ try
+ {
+ _loggingFacade.setRuntimeLoggerLevel(loggerName, "WARN");
+ fail("Exception not thrown");
+ }
+ catch (LoggingFacadeException lfe)
+ {
+ // PASS
+ assertEquals("Can't find logger " + loggerName, lfe.getMessage());
+ }
+
+ Map<String, String> levels = _loggingFacade.retrieveRuntimeLoggersLevels();
+ assertFalse(levels.containsKey(loggerName));
+ }
+
+ public void testReloadOfChangedLog4JFileUpdatesRuntimeLogLevel() throws Exception
+ {
+ final String loggerName = "a.b.c";
+
+ assertRuntimeLoggingLevel(loggerName, "INFO");
+ assertConfigFileLoggingLevel(loggerName, "INFO");
+
+ _loggingFacade.setConfigFileLoggerLevel(loggerName, "WARN");
+
+ assertRuntimeLoggingLevel(loggerName, "INFO");
+
+ _loggingFacade.reload();
+
+ assertRuntimeLoggingLevel(loggerName, "WARN");
+ }
+
+
+ public void testReloadOfLog4JFileRevertsRuntimeChanges() throws Exception
+ {
+ final String loggerName = "a.b.c";
+
+ assertRuntimeLoggingLevel(loggerName, "INFO");
+ assertConfigFileLoggingLevel(loggerName, "INFO");
+
+ _loggingFacade.setRuntimeLoggerLevel(loggerName, "WARN");
+
+ assertRuntimeLoggingLevel(loggerName, "WARN");
+
+ _loggingFacade.reload();
+
+ assertRuntimeLoggingLevel(loggerName, "INFO");
+ }
+
+ private void assertConfigFileLoggingLevel(final String loggerName, String expectedLevel) throws Exception
+ {
+ Map<String, String> levels = _loggingFacade.retrieveConfigFileLoggersLevels();
+ String actualLevel = levels.get(loggerName);
+ assertEquals(expectedLevel, actualLevel);
+ }
+
+ private void assertRuntimeLoggingLevel(final String loggerName, String expectedLevel) throws Exception
+ {
+ Map<String, String> levels = _loggingFacade.retrieveRuntimeLoggersLevels();
+ String actualLevel = levels.get(loggerName);
+ assertEquals(expectedLevel, actualLevel);
+ }
+
+ private String createTestLog4jXml() throws Exception
+ {
+ File dst = File.createTempFile("log4j." + getName(), "xml");
+ File filename = new File(getClass().getResource("LoggingFacadeTest.log4j.xml").toURI());
+ FileUtils.copy(filename, dst);
+ dst.deleteOnExit();
+ return dst.getAbsolutePath();
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.log4j.xml b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.log4j.xml
new file mode 100644
index 0000000000..62ec877d3d
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.log4j.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ -
+ - 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.
+ -
+ --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null">
+
+ <category additivity="true" name="a.b.c">
+ <priority value="INFO"/>
+ </category>
+
+ <logger additivity="true" name="a.b.c.1">
+ <level value="DEBUG"/>
+ </logger>
+
+ <logger additivity="true" name="a.b.c.2">
+ <level value="TRACE"/>
+ </logger>
+
+ <root>
+ <priority value="WARN"/>
+ </root>
+
+</log4j:configuration>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java
deleted file mode 100644
index f9ad81ae74..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BrokerMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BrokerMessagesTest.java
index e87d292471..6571d20711 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BrokerMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/BrokerMessagesTest.java
@@ -20,10 +20,9 @@
*/
package org.apache.qpid.server.logging.messages;
+import java.text.NumberFormat;
import java.util.List;
-import org.apache.derby.iapi.services.io.FileUtil;
-
/**
* Test BRK log Messages
*/
@@ -139,7 +138,7 @@ public class BrokerMessagesTest extends AbstractTestMessages
_logMessage = BrokerMessages.MAX_MEMORY(oneGiga);
List<Object> log = performLog();
- String[] expected = {"Maximum Memory :", "1,073,741,824", "bytes"};
+ String[] expected = {"Maximum Memory :", NumberFormat.getNumberInstance().format(oneGiga), "bytes"};
validateLogMessage(log, "BRK-1011", expected);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
deleted file mode 100644
index f7d85c11a8..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java
new file mode 100644
index 0000000000..643132d371
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java
@@ -0,0 +1,213 @@
+/*
+ *
+ * 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.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class UUIDGeneratorTest extends QpidTestCase
+{
+ private static final String VIRTUAL_HOST_NAME_1 = "virtualHost1";
+ private static final String VIRTUAL_HOST_NAME_2 = "virtualHost2";
+ private static final String VHOST_ALIAS_1 = "alias1";
+ private static final String VHOST_ALIAS_2 = "alias2";
+ private static final String QUEUE_NAME_1 = "queue1";
+ private static final String QUEUE_NAME_2 = "queue2";
+ private static final String EXCHANGE_NAME_1 = "exchange1";
+ private static final String EXCHANGE_NAME_2 = "exchange2";
+ private static final String BINDING_KEY_1 = "bindingKey1";
+ private static final String BINDING_KEY_2 = "bindingKey2";
+ private static final String PORT_1 = "port1";
+ private static final String PORT_2 = "port2";
+ private static final String CONN_REMOTE_ADDR_1 = "localhost:1234";
+ private static final String CONN_REMOTE_ADDR_2 = "localhost:5678";
+ private static final String CHANNEL_NUMBER_1 = "1";
+ private static final String CHANNEL_NUMBER_2 = "2";
+ private static final String CONSUMER_NAME_1 = "consumer1";
+ private static final String CONSUMER_NAME_2 = "consumer2";
+ private static final String PROVIDER_1 = "provider1";
+ private static final String PROVIDER_2 = "provider2";
+ private static final String USER_1 = "user1";
+ private static final String USER_2 = "user2";
+
+ public void testDifferentObjectTypeReturnDifferentIdFromSameValues() throws Exception
+ {
+ String value = "name";
+ Set<UUID> idSet = new HashSet<UUID>();
+
+ UUID id1 = UUIDGenerator.generateQueueUUID(value, value);
+ idSet.add(id1);
+ UUID id2 = UUIDGenerator.generateExchangeUUID(value, value);
+ idSet.add(id2);
+ UUID id3 = UUIDGenerator.generateBindingUUID(value, value, value, value);
+ idSet.add(id3);
+ UUID id4 = UUIDGenerator.generateConsumerUUID(value, value, value, value, value);
+ idSet.add(id4);
+ UUID id5 = UUIDGenerator.generateUserUUID(value, value);
+ idSet.add(id5);
+ UUID id6 = UUIDGenerator.generateVhostUUID(value);
+ idSet.add(id6);
+ UUID id7 = UUIDGenerator.generateVhostAliasUUID(value, value);
+ idSet.add(id7);
+
+ assertEquals("The produced UUIDs were not all unique", 7, idSet.size());
+ }
+
+ public void testQueueIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID queue1 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_1, VIRTUAL_HOST_NAME_1);
+ UUID queue2 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_1, VIRTUAL_HOST_NAME_1);
+ assertEquals("Queue IDs should be equal", queue1, queue2);
+
+ //check different name gives different ID
+ queue1 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_1, VIRTUAL_HOST_NAME_1);
+ queue2 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_2, VIRTUAL_HOST_NAME_1);
+ assertFalse("Queue IDs should not be equal", queue1.equals(queue2));
+
+ //check different vhost name gives different ID
+ queue1 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_1, VIRTUAL_HOST_NAME_1);
+ queue2 = UUIDGenerator.generateQueueUUID(QUEUE_NAME_1, VIRTUAL_HOST_NAME_2);
+ assertFalse("Queue IDs should not be equal", queue1.equals(queue2));
+ }
+
+ public void testExchangeIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID exchange1 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_1, VIRTUAL_HOST_NAME_1);
+ UUID exchange2 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_1, VIRTUAL_HOST_NAME_1);
+ assertEquals("Exchange IDs should be equal", exchange1, exchange2);
+
+ //check different name gives different ID
+ exchange1 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_1, VIRTUAL_HOST_NAME_1);
+ exchange2 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_2, VIRTUAL_HOST_NAME_1);
+ assertFalse("Exchange IDs should not be equal", exchange1.equals(exchange2));
+
+ //check different vhost name gives different ID
+ exchange1 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_1, VIRTUAL_HOST_NAME_1);
+ exchange2 = UUIDGenerator.generateExchangeUUID(EXCHANGE_NAME_1, VIRTUAL_HOST_NAME_2);
+ assertFalse("Exchange IDs should not be equal", exchange1.equals(exchange2));
+ }
+
+ public void testBindingIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID binding1 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_1, VIRTUAL_HOST_NAME_1);
+ UUID binding2 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_1, VIRTUAL_HOST_NAME_1);
+ assertEquals("Binding IDs should be equal", binding1, binding2);
+
+ //check different name gives different ID
+ binding1 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_1, VIRTUAL_HOST_NAME_1);
+ binding2 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_2, VIRTUAL_HOST_NAME_1);
+ assertFalse("Binding IDs should not be equal", binding1.equals(binding2));
+
+ //check different vhost name gives different ID
+ binding1 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_1, VIRTUAL_HOST_NAME_1);
+ binding2 = UUIDGenerator.generateBindingUUID(EXCHANGE_NAME_1, QUEUE_NAME_1, BINDING_KEY_1, VIRTUAL_HOST_NAME_2);
+ assertFalse("Binding IDs should not be equal", binding1.equals(binding2));
+ }
+
+ public void testVhostIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID vhost1 = UUIDGenerator.generateVhostUUID(VIRTUAL_HOST_NAME_1);
+ UUID vhost2 = UUIDGenerator.generateVhostUUID(VIRTUAL_HOST_NAME_1);
+ assertTrue("Virtualhost IDs should be equal", vhost1.equals(vhost2));
+
+ //check different vhost name gives different ID
+ vhost1 = UUIDGenerator.generateVhostUUID(VIRTUAL_HOST_NAME_1);
+ vhost2 = UUIDGenerator.generateVhostUUID(VIRTUAL_HOST_NAME_2);
+ assertFalse("Virtualhost IDs should not be equal", vhost1.equals(vhost2));
+ }
+
+ public void testVhostAliasIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID alias1 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_1, PORT_1);
+ UUID alias2 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_1, PORT_1);
+ assertTrue("Virtualhost Alias IDs should be equal", alias1.equals(alias2));
+
+ //check different port name gives different ID
+ alias1 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_1, PORT_1);
+ alias2 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_2, PORT_1);
+ assertFalse("Virtualhost Alias IDs should not be equal", alias1.equals(alias2));
+
+ //check different alias name gives different ID
+ alias1 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_1, PORT_1);
+ alias2 = UUIDGenerator.generateVhostAliasUUID(VHOST_ALIAS_1, PORT_2);
+ assertFalse("Virtualhost Alias IDs should not be equal", alias1.equals(alias2));
+ }
+
+ public void testConsumerIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ UUID consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ assertTrue("Consumer IDs should be equal", consumer1.equals(consumer2));
+
+ //check different name gives different ID
+ consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_2);
+ assertFalse("Consumer IDs should not be equal", consumer1.equals(consumer2));
+
+ //check different vhost name gives different ID
+ consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_2, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ assertFalse("Consumer IDs should not be equal", consumer1.equals(consumer2));
+
+ //check different consumer name gives different ID
+ consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_2, CONSUMER_NAME_1);
+ assertFalse("Consumer IDs should not be equal", consumer1.equals(consumer2));
+
+ //check different address name gives different ID
+ consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_2, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ assertFalse("Consumer IDs should not be equal", consumer1.equals(consumer2));
+
+ //check different queue name gives different ID
+ consumer1 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_1, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ consumer2 = UUIDGenerator.generateConsumerUUID(VIRTUAL_HOST_NAME_1, QUEUE_NAME_2, CONN_REMOTE_ADDR_1, CHANNEL_NUMBER_1, CONSUMER_NAME_1);
+ assertFalse("Consumer IDs should not be equal", consumer1.equals(consumer2));
+ }
+
+ public void testUserIdGeneration() throws Exception
+ {
+ //check repeated generation is deterministic
+ UUID user1 = UUIDGenerator.generateUserUUID(PROVIDER_1, USER_1);
+ UUID user2 = UUIDGenerator.generateUserUUID(PROVIDER_1, USER_1);
+ assertTrue("User IDs should be equal", user1.equals(user2));
+
+ //check different name gives different ID
+ user1 = UUIDGenerator.generateUserUUID(PROVIDER_1, USER_1);
+ user2 = UUIDGenerator.generateUserUUID(PROVIDER_1, USER_2);
+ assertFalse("User IDs should not be equal", user1.equals(user2));
+
+ //check different provider gives different ID
+ user1 = UUIDGenerator.generateUserUUID(PROVIDER_1, USER_1);
+ user2 = UUIDGenerator.generateUserUUID(PROVIDER_2, USER_1);
+ assertFalse("User IDs should not be equal", user1.equals(user2));
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java b/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java
index 267545c656..20abdd48cd 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java
@@ -73,11 +73,11 @@ public class OsgiSystemPackageUtilTest extends QpidTestCase
_map.put("org.apache.qpid.xyz", "1.0.0");
_map.put("org.abc", "1.2.3");
- _util = new OsgiSystemPackageUtil(new Version("0.17"), _map);
+ _util = new OsgiSystemPackageUtil(new Version("0.19"), _map);
final String systemPackageString = _util.getFormattedSystemPackageString();
- assertEquals("org.abc; version=1.2.3, org.apache.qpid.xyz; version=0.17.0", systemPackageString);
+ assertEquals("org.abc; version=1.2.3, org.apache.qpid.xyz; version=0.19.0", systemPackageString);
}
public void testWithQpidPackageWithoutQpidReleaseNumberSet() throws Exception
diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
deleted file mode 100644
index fe9bcc57a6..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
index 01a2178911..c3d58f3bdc 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java
@@ -1,4 +1,3 @@
-package org.apache.qpid.server.queue;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +18,7 @@ package org.apache.qpid.server.queue;
* under the License.
*
*/
+package org.apache.qpid.server.queue;
import junit.framework.AssertionFailedError;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
deleted file mode 100644
index 25d35aab16..0000000000
--- a/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/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
index e123a968a4..186be4dff7 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.queue;
-import java.util.UUID;
-
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.AMQException;
@@ -35,9 +33,9 @@ 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.model.UUIDGenerator;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.store.TestableMemoryMessageStoreFactory;
import org.apache.qpid.server.util.TestApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -56,7 +54,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
XMLConfiguration configXml = new XMLConfiguration();
configXml.addProperty("virtualhosts.virtualhost(-1).name", getName());
- configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.factoryclass", TestableMemoryMessageStoreFactory.class.getName());
+ configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName());
ServerConfiguration configuration = new ServerConfiguration(configXml);
@@ -100,8 +98,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
fieldTable.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 5);
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testPriorityQueue"), false, new AMQShortString("owner"), false,
- false, _virtualHost, fieldTable);
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "testPriorityQueue", false, "owner", false,
+ false, _virtualHost, FieldTable.convertToMap(fieldTable));
assertEquals("Queue not a priorty queue", AMQPriorityQueue.class, queue.getClass());
verifyQueueRegistered("testPriorityQueue");
@@ -111,13 +109,13 @@ public class AMQQueueFactoryTest extends QpidTestCase
public void testSimpleQueueRegistration() throws Exception
{
- AMQShortString queueName = new AMQShortString("testSimpleQueueRegistration");
+ String queueName = getName();
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false,
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", false,
false, _virtualHost, null);
assertEquals("Queue not a simple queue", SimpleAMQQueue.class, queue.getClass());
- verifyQueueRegistered("testSimpleQueueRegistration");
+ verifyQueueRegistered(queueName);
//verify that no alternate exchange or DLQ were produced
QueueRegistry qReg = _virtualHost.getQueueRegistry();
@@ -138,7 +136,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
- AMQShortString queueName = new AMQShortString("testDeadLetterQueueEnabled");
+ String queueName = "testDeadLetterQueueEnabled";
AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
@@ -148,8 +146,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertNull("The DLQ should not yet exist", qReg.getQueue(dlQueueName));
assertNull("The alternate exchange should not yet exist", exReg.getExchange(dlExchangeName));
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false, false,
- _virtualHost, fieldTable);
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", false, false,
+ _virtualHost, FieldTable.convertToMap(fieldTable));
Exchange altExchange = queue.getAlternateExchange();
assertNotNull("Queue should have an alternate exchange as DLQ is enabled", altExchange);
@@ -179,7 +177,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("deadLetterQueues","true");
ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("maximumDeliveryCount","5");
- AMQShortString queueName = new AMQShortString("testDeadLetterQueueEnabled");
+ String queueName = "testDeadLetterQueueEnabled";
AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
@@ -189,7 +187,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertNull("The DLQ should not yet exist", qReg.getQueue(dlQueueName));
assertNull("The alternate exchange should not yet exist", exReg.getExchange(dlExchangeName));
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false, false,
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", false, false,
_virtualHost, null);
assertEquals("Unexpected maximum delivery count", 5, queue.getMaximumDeliveryCount());
@@ -221,7 +219,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, false);
- AMQShortString queueName = new AMQShortString("testDeadLetterQueueDisabled");
+ String queueName = "testDeadLetterQueueDisabled";
AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
@@ -231,8 +229,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertNull("The DLQ should not yet exist", qReg.getQueue(dlQueueName));
assertNull("The alternate exchange should not exist", exReg.getExchange(dlExchangeName));
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false, false,
- _virtualHost, fieldTable);
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", false, false,
+ _virtualHost, FieldTable.convertToMap(fieldTable));
assertNull("Queue should not have an alternate exchange as DLQ is disabled", queue.getAlternateExchange());
assertNull("The alternate exchange should still not exist", exReg.getExchange(dlExchangeName));
@@ -254,7 +252,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
- AMQShortString queueName = new AMQShortString("testDeadLetterQueueNotCreatedForAutodeleteQueues");
+ String queueName = "testDeadLetterQueueNotCreatedForAutodeleteQueues";
AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
@@ -265,8 +263,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertNull("The alternate exchange should not exist", exReg.getExchange(dlExchangeName));
//create an autodelete queue
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), true, false,
- _virtualHost, fieldTable);
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner", true, false,
+ _virtualHost, FieldTable.convertToMap(fieldTable));
assertTrue("Queue should be autodelete", queue.isAutoDelete());
//ensure that the autodelete property overrides the request to enable DLQ
@@ -287,10 +285,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
final FieldTable fieldTable = new FieldTable();
fieldTable.setInteger(AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT, 5);
- final AMQShortString queueName = new AMQShortString("testMaximumDeliveryCount");
-
- final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false, false,
- _virtualHost, fieldTable);
+ final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "testMaximumDeliveryCount", false, "owner", false, false,
+ _virtualHost, FieldTable.convertToMap(fieldTable));
assertNotNull("The queue was not registered as expected ", queue);
assertEquals("Maximum delivery count not as expected", 5, queue.getMaximumDeliveryCount());
@@ -304,10 +300,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
*/
public void testMaximumDeliveryCountDefault() throws Exception
{
-
- final AMQShortString queueName = new AMQShortString("testMaximumDeliveryCount");
-
- final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, false, new AMQShortString("owner"), false, false,
+ final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "testMaximumDeliveryCount", false, "owner", false, false,
_virtualHost, null);
assertNotNull("The queue was not registered as expected ", queue);
@@ -323,7 +316,7 @@ public class AMQQueueFactoryTest extends QpidTestCase
{
try
{
- AMQQueueFactory.createAMQQueueImpl(null, false, new AMQShortString("owner"), true, false, _virtualHost, null);
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), null, false, "owner", true, false, _virtualHost, null);
fail("queue with null name can not be created!");
}
catch (Exception e)
@@ -350,8 +343,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
- AMQQueueFactory.createAMQQueueImpl(new AMQShortString(queueName), false, new AMQShortString("owner"),
- false, false, _virtualHost, fieldTable);
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner",
+ false, false, _virtualHost, FieldTable.convertToMap(fieldTable));
fail("queue with DLQ name having more than 255 characters can not be created!");
}
catch (Exception e)
@@ -386,8 +379,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
- AMQQueueFactory.createAMQQueueImpl(new AMQShortString(queueName), false, new AMQShortString("owner"),
- false, false, _virtualHost, fieldTable);
+ AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner",
+ false, false, _virtualHost, FieldTable.convertToMap(fieldTable));
fail("queue with DLE name having more than 255 characters can not be created!");
}
catch (Exception e)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
deleted file mode 100644
index 45933e7064..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ /dev/null
@@ -1,553 +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.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;
-
-import javax.management.JMException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 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"));
- assertEquals("Unexpected JMSTimestamp within header", FastDateFormat.getInstance(AMQQueueMBean.JMSTIMESTAMP_DATETIME_FORMAT).format(msg2Timestamp),
- row2Headers.get("JMSTimestamp"));
- assertEquals("Unexpected JMSExpiration within header", FastDateFormat.getInstance(AMQQueueMBean.JMSTIMESTAMP_DATETIME_FORMAT).format(msg2Expiration),
- 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/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
index 409b9fd92e..190d5c777b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
@@ -32,6 +32,7 @@ import org.apache.qpid.server.flow.LimitlessCreditManager;
import org.apache.qpid.server.flow.Pre0_10CreditManager;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -76,7 +77,7 @@ public class AckTest extends InternalBrokerBaseCase
_protocolSession.addChannel(_channel);
- _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("myQ"), false, new AMQShortString("guest"), true, false,
+ _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "myQ", false, "guest", true, false,
_virtualHost, null);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/ConflationQueueListTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/ConflationQueueListTest.java
new file mode 100644
index 0000000000..a94548f1c3
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/ConflationQueueListTest.java
@@ -0,0 +1,211 @@
+/*
+ * 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.Mockito.mock;
+import static org.mockito.Mockito.when;
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.message.AMQMessage;
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.AMQMessageReference;
+import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+public class ConflationQueueListTest extends TestCase
+{
+ private static final String CONFLATION_KEY = "CONFLATION_KEY";
+
+ private static final String TEST_KEY_VALUE = "testKeyValue";
+ private static final String TEST_KEY_VALUE1 = "testKeyValue1";
+ private static final String TEST_KEY_VALUE2 = "testKeyValue2";
+
+ private ConflationQueueList _list;
+ private AMQQueue _queue = createTestQueue();
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _list = new ConflationQueueList(_queue, CONFLATION_KEY);
+ }
+
+ public void testListHasNoEntries()
+ {
+ int numberOfEntries = countEntries(_list);
+ assertEquals(0, numberOfEntries);
+ }
+
+ public void testAddMessageWithoutConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message = createTestServerMessage(null);
+
+ _list.add(message);
+ int numberOfEntries = countEntries(_list);
+ assertEquals(1, numberOfEntries);
+ }
+
+ public void testAddAndDiscardMessageWithoutConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message = createTestServerMessage(null);
+
+ QueueEntry addedEntry = _list.add(message);
+ addedEntry.discard();
+
+ int numberOfEntries = countEntries(_list);
+ assertEquals(0, numberOfEntries);
+ }
+
+ public void testAddMessageWithConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message = createTestServerMessage(TEST_KEY_VALUE);
+
+ _list.add(message);
+ int numberOfEntries = countEntries(_list);
+ assertEquals(1, numberOfEntries);
+ }
+
+ public void testAddAndRemoveMessageWithConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message = createTestServerMessage(TEST_KEY_VALUE);
+
+ QueueEntry addedEntry = _list.add(message);
+ addedEntry.discard();
+
+ int numberOfEntries = countEntries(_list);
+ assertEquals(0, numberOfEntries);
+ }
+
+ public void testAddTwoMessagesWithDifferentConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message1 = createTestServerMessage(TEST_KEY_VALUE1);
+ ServerMessage<MessageMetaData> message2 = createTestServerMessage(TEST_KEY_VALUE2);
+
+ _list.add(message1);
+ _list.add(message2);
+
+ int numberOfEntries = countEntries(_list);
+ assertEquals(2, numberOfEntries);
+ }
+
+ public void testAddTwoMessagesWithSameConflationKeyValue()
+ {
+ ServerMessage<MessageMetaData> message1 = createTestServerMessage(TEST_KEY_VALUE);
+ ServerMessage<MessageMetaData> message2 = createTestServerMessage(TEST_KEY_VALUE);
+
+ _list.add(message1);
+ _list.add(message2);
+
+ int numberOfEntries = countEntries(_list);
+ assertEquals(1, numberOfEntries);
+ }
+
+ public void testSupersededEntryIsDiscardedOnRelease()
+ {
+ ServerMessage<MessageMetaData> message1 = createTestServerMessage(TEST_KEY_VALUE);
+ ServerMessage<MessageMetaData> message2 = createTestServerMessage(TEST_KEY_VALUE);
+
+ QueueEntry entry1 = _list.add(message1);
+ entry1.acquire(); // simulate an in-progress delivery to consumer
+
+ _list.add(message2);
+ assertFalse(entry1.isDeleted());
+
+ assertEquals(2, countEntries(_list));
+
+ entry1.release(); // simulate consumer rollback/recover
+
+ assertEquals(1, countEntries(_list));
+ assertTrue(entry1.isDeleted());
+ }
+
+ public void testConflationMapMaintained()
+ {
+ assertEquals(0, _list.getLatestValuesMap().size());
+
+ ServerMessage<MessageMetaData> message = createTestServerMessage(TEST_KEY_VALUE);
+
+ QueueEntry addedEntry = _list.add(message);
+
+ assertEquals(1, countEntries(_list));
+ assertEquals(1, _list.getLatestValuesMap().size());
+
+ addedEntry.discard();
+
+ assertEquals(0, countEntries(_list));
+ assertEquals(0, _list.getLatestValuesMap().size());
+ }
+
+ public void testConflationMapMaintainedWithDifferentConflationKeyValue()
+ {
+
+ assertEquals(0, _list.getLatestValuesMap().size());
+
+ ServerMessage<MessageMetaData> message1 = createTestServerMessage(TEST_KEY_VALUE1);
+ ServerMessage<MessageMetaData> message2 = createTestServerMessage(TEST_KEY_VALUE2);
+
+ QueueEntry addedEntry1 = _list.add(message1);
+ QueueEntry addedEntry2 = _list.add(message2);
+
+ assertEquals(2, countEntries(_list));
+ assertEquals(2, _list.getLatestValuesMap().size());
+
+ addedEntry1.discard();
+ addedEntry2.discard();
+
+ assertEquals(0, countEntries(_list));
+ assertEquals(0, _list.getLatestValuesMap().size());
+ }
+
+ private int countEntries(ConflationQueueList list)
+ {
+ QueueEntryIterator<SimpleQueueEntryImpl> iterator = list.iterator();
+ int count = 0;
+ while(iterator.advance())
+ {
+ count++;
+ }
+ return count;
+ }
+
+ private ServerMessage<MessageMetaData> createTestServerMessage(String conflationKeyValue)
+ {
+ AMQMessage mockMessage = mock(AMQMessage.class);
+
+ AMQMessageHeader messageHeader = mock(AMQMessageHeader.class);
+ when(messageHeader.getHeader(CONFLATION_KEY)).thenReturn(conflationKeyValue);
+ when(mockMessage.getMessageHeader()).thenReturn(messageHeader);
+
+ AMQMessageReference messageReference = new AMQMessageReference(mockMessage);
+ when(mockMessage.newReference()).thenReturn(messageReference);
+
+ return mockMessage;
+ }
+
+ private AMQQueue createTestQueue()
+ {
+ AMQQueue queue = mock(AMQQueue.class);
+ VirtualHost virtualHost = mock(VirtualHost.class);
+ when(queue.getVirtualHost()).thenReturn(virtualHost);
+
+ return queue;
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java b/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
index afaa417415..bcb8d54636 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java
+++ b/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;
@@ -171,6 +186,12 @@ public class MockAMQQueue implements AMQQueue
return null;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return null;
+ }
+
public QueueConfigType getConfigType()
{
return null;
@@ -219,12 +240,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 +319,7 @@ public class MockAMQQueue implements AMQQueue
}
public int delete() throws AMQException
- {
+ {
_deleted = true;
return getMessageCount();
}
@@ -356,21 +392,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 +399,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageSize(long value)
{
-
+
}
public long getMaximumMessageCount()
@@ -388,7 +409,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageCount(long value)
{
-
+
}
public long getMaximumQueueDepth()
@@ -398,7 +419,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumQueueDepth(long value)
{
-
+
}
public long getMaximumMessageAge()
@@ -408,7 +429,7 @@ public class MockAMQQueue implements AMQQueue
public void setMaximumMessageAge(long maximumMessageAge)
{
-
+
}
public long getMinimumAlertRepeatGap()
@@ -418,7 +439,7 @@ public class MockAMQQueue implements AMQQueue
public void deleteMessageFromTop()
{
-
+
}
public long clearQueue()
@@ -429,7 +450,7 @@ public class MockAMQQueue implements AMQQueue
public void checkMessageStatus() throws AMQException
{
-
+
}
public Set<NotificationCheck> getNotificationChecks()
@@ -439,22 +460,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 +490,7 @@ public class MockAMQQueue implements AMQQueue
public void setAlternateExchange(Exchange exchange)
{
-
+
}
public Map<String, Object> getArguments()
@@ -481,11 +502,6 @@ public class MockAMQQueue implements AMQQueue
{
}
- public ManagedObject getManagedObject()
- {
- return null;
- }
-
public int compareTo(AMQQueue o)
{
return 0;
@@ -503,7 +519,7 @@ public class MockAMQQueue implements AMQQueue
public void setCapacity(long capacity)
{
-
+
}
public long getFlowResumeCapacity()
@@ -513,7 +529,7 @@ public class MockAMQQueue implements AMQQueue
public void setFlowResumeCapacity(long flowResumeCapacity)
{
-
+
}
public void configure(ConfigurationPlugin config)
@@ -546,12 +562,6 @@ public class MockAMQQueue implements AMQQueue
_exclusiveOwner = exclusiveOwner;
}
-
- public String getResourceName()
- {
- return _name.toString();
- }
-
public boolean isOverfull()
{
return false;
@@ -582,7 +592,7 @@ public class MockAMQQueue implements AMQQueue
return 0;
}
- public void decrementUnackedMsgCount()
+ public void decrementUnackedMsgCount(QueueEntry queueEntry)
{
}
@@ -599,7 +609,6 @@ public class MockAMQQueue implements AMQQueue
public void setExclusive(boolean exclusive)
{
-
}
public int getMaximumDeliveryCount()
@@ -611,11 +620,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/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/NotificationCheckTest.java
new file mode 100644
index 0000000000..df2de7f0e0
--- /dev/null
+++ b/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/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 52ad4a7c5b..2cd423d4c9 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/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;
@@ -43,7 +50,6 @@ import org.apache.qpid.server.queue.SimpleAMQQueue.QueueEntryFilter;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.store.TestableMemoryMessageStoreFactory;
import org.apache.qpid.server.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
@@ -80,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()
@@ -108,11 +113,11 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
PropertiesConfiguration env = new PropertiesConfiguration();
final VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(getClass().getName(), env);
- vhostConfig.setMessageStoreFactoryClass(TestableMemoryMessageStoreFactory.class.getName());
+ vhostConfig.setMessageStoreClass(TestableMemoryMessageStore.class.getName());
_virtualHost = new VirtualHostImpl(ApplicationRegistry.getInstance(), vhostConfig);
applicationRegistry.getVirtualHostRegistry().registerVirtualHost(_virtualHost);
- _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_qname, false, _owner, false, false, _virtualHost, _arguments);
+ _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), _qname.asString(), false, _owner.asString(), false, false, _virtualHost, FieldTable.convertToMap(_arguments));
_exchange = (DirectExchange)_virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.DIRECT_EXCHANGE_NAME);
}
@@ -128,7 +133,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
{
_queue.stop();
try {
- _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(null, false, _owner, false, false, _virtualHost, _arguments );
+ _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), null, false, _owner.asString(), false, false, _virtualHost, FieldTable.convertToMap(_arguments));
assertNull("Queue was created", _queue);
}
catch (IllegalArgumentException e)
@@ -138,7 +143,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
try {
- _queue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), _qname, false, _owner, false,false, null, Collections.EMPTY_MAP);
+ _queue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), _qname, false, _owner, false,false, null, Collections.EMPTY_MAP);
assertNull("Queue was created", _queue);
}
catch (IllegalArgumentException e)
@@ -147,8 +152,8 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
e.getMessage().contains("Host"));
}
- _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_qname, false, _owner, false,
- false, _virtualHost, _arguments);
+ _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), _qname.asString(), false, _owner.asString(), false,
+ false, _virtualHost, FieldTable.convertToMap(_arguments));
assertNotNull("Queue was not created", _queue);
}
@@ -480,7 +485,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void testAutoDeleteQueue() throws Exception
{
_queue.stop();
- _queue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), _qname, false, null, true, false, _virtualHost, Collections.EMPTY_MAP);
+ _queue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), _qname, false, null, true, false, _virtualHost, Collections.EMPTY_MAP);
_queue.setDeleteOnNoConsumers(true);
_queue.registerSubscription(_subscription, false);
AMQMessage message = createMessage(new Long(25));
@@ -692,7 +697,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void testProcessQueueWithUniqueSelectors() throws Exception
{
TestSimpleQueueEntryListFactory factory = new TestSimpleQueueEntryListFactory();
- SimpleAMQQueue testQueue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), "testQueue", false,"testOwner",
+ SimpleAMQQueue testQueue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), "testQueue", false,"testOwner",
false, false, _virtualHost, factory, null)
{
@Override
@@ -840,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
@@ -1029,7 +921,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
int dequeueMessageIndex = 1;
// create queue with overridden method deliverAsync
- SimpleAMQQueue testQueue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), new AMQShortString("test"),
+ SimpleAMQQueue testQueue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), new AMQShortString("test"),
false, new AMQShortString("testOwner"), false, false, _virtualHost, null)
{
@Override
@@ -1097,10 +989,10 @@ 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,
+ SimpleAMQQueue queue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), new AMQShortString("test"), false,
new AMQShortString("testOwner"), false, false, _virtualHost, new QueueEntryListFactory()
{
public QueueEntryList createQueueEntryList(AMQQueue queue)
@@ -1178,7 +1070,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void testActiveConsumerCount() throws Exception
{
- final SimpleAMQQueue queue = new SimpleAMQQueue(UUIDGenerator.generateUUID(), new AMQShortString("testActiveConsumerCount"), false,
+ final SimpleAMQQueue queue = new SimpleAMQQueue(UUIDGenerator.generateRandomUUID(), new AMQShortString("testActiveConsumerCount"), false,
new AMQShortString("testOwner"), false, false, _virtualHost, new SimpleQueueEntryList.Factory(), null);
//verify adding an active subscription increases the count
@@ -1232,29 +1124,37 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
assertEquals("Unexpected active consumer count", 1, queue.getActiveConsumerCount());
}
- /**
- * A helper method to create a queue with given name
- *
- * @param name
- * queue name
- * @return queue
- */
- private SimpleAMQQueue createQueue(String name)
+ public void testNotificationFiredOnEnqueue() throws Exception
{
- SimpleAMQQueue queue = null;
- try
- {
- AMQShortString queueName = new AMQShortString(name);
- AMQShortString ownerName = new AMQShortString(name + "Owner");
- queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(queueName, false, ownerName, false, false,
- _virtualHost, _arguments);
- }
- catch (AMQException e)
- {
- fail("Failure to create a queue:" + e.getMessage());
- }
- assertNotNull("Queue was not created", queue);
- return queue;
+ 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"));
}
/**
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java
index 39ddd1d500..6b82cd361a 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java
@@ -21,8 +21,8 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -37,9 +37,8 @@ public class SimpleAMQQueueThreadPoolTest extends InternalBrokerBaseCase
try
{
- SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false,
- new AMQShortString("owner"),
- false, false, test, null);
+ SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "test", false,
+ "owner", false, false, test, null);
assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown());
diff --git a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java b/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
index 9ff8f0a531..9af950d385 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
@@ -49,7 +49,7 @@ public class ApplicationRegistryShutdownTest extends InternalBrokerBaseCase
/**
- * QPID-1399 : Ensure that the Authentiction manager unregisters any SASL providers created during
+ * QPID-1399 : Ensure that the Authentication manager unregisters any SASL providers created during
* ApplicationRegistry initialisation.
*
*/
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java
new file mode 100644
index 0000000000..9dcd22c088
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.manager;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
+
+public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase
+{
+
+ private AuthenticationManager _manager = null;
+
+ public void setUp() throws Exception
+ {
+ _manager = AnonymousAuthenticationManager.INSTANCE;
+ }
+
+
+ public void tearDown() throws Exception
+ {
+ if(_manager != null)
+ {
+ _manager = null;
+ }
+ }
+
+ private ConfigurationPlugin getPlainDatabaseConfig() throws ConfigurationException
+ {
+ final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration();
+
+ XMLConfiguration xmlconfig = new XMLConfiguration();
+ xmlconfig.addProperty("pd-auth-manager.principal-database.class", PlainPasswordFilePrincipalDatabase.class.getName());
+
+ // Create a CompositeConfiguration as this is what the broker uses
+ CompositeConfiguration composite = new CompositeConfiguration();
+ composite.addConfiguration(xmlconfig);
+ config.setConfiguration("security", xmlconfig);
+ return config;
+ }
+
+
+ public void testConfiguration() throws Exception
+ {
+ AuthenticationManager authenticationManager =
+ AnonymousAuthenticationManager.FACTORY.newInstance(getPlainDatabaseConfig());
+
+ assertNull("AnonymousAuthenticationManager unexpectedly created when not in config", authenticationManager);
+ }
+
+ public void testGetMechanisms() throws Exception
+ {
+ assertEquals("ANONYMOUS", _manager.getMechanisms());
+ }
+
+ public void testCreateSaslServer() throws Exception
+ {
+ SaslServer server = _manager.createSaslServer("ANONYMOUS", "example.example.com", null);
+
+ assertEquals("Sasl Server mechanism name is not as expected", "ANONYMOUS", server.getMechanismName());
+
+ try
+ {
+ server = _manager.createSaslServer("PLAIN", "example.example.com", null);
+ fail("Expected creating SaslServer with incorrect mechanism to throw an exception");
+ }
+ catch (SaslException e)
+ {
+ // pass
+ }
+ }
+
+ public void testAuthenticate() throws Exception
+ {
+ SaslServer saslServer = _manager.createSaslServer("ANONYMOUS", "example.example.com", null);
+ AuthenticationResult result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertNotNull("Subject should not be null", result.getSubject());
+ }
+
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java
new file mode 100644
index 0000000000..efb8df3a38
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java
@@ -0,0 +1,304 @@
+/*
+ * 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.manager;
+
+import static org.mockito.Mockito.*;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+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;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.plugins.Plugin;
+import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration;
+import org.mockito.Mockito;
+
+import junit.framework.TestCase;
+
+public class AuthenticationManagerRegistryTest extends TestCase
+{
+ private static final Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> EMPTY_PLUGINMAP = Collections.emptyMap();
+
+ private PluginManager _pluginManager = Mockito.mock(PluginManager.class);
+ private ServerConfiguration _serverConfiguration = Mockito.mock(ServerConfiguration.class);
+ private SecurityConfiguration _securityConfiguration = Mockito.mock(SecurityConfiguration.class);
+
+ private List<AuthenticationManager> _allCreatedAuthManagers = new ArrayList<AuthenticationManager>();
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ // Setup server configuration to return mock security config.
+ when(_serverConfiguration.getConfiguration(SecurityConfiguration.class.getName())).thenReturn(_securityConfiguration);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ verifyAllCreatedAuthManagersClosed();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testNoAuthenticationManagerFactoryPluginsFound() throws Exception
+ {
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(EMPTY_PLUGINMAP);
+ try
+ {
+ new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ // PASS
+ assertEquals("No authentication manager factory plugins found. Check the desired authentication manager plugin has been placed in the plugins directory.",
+ ce.getMessage());
+ }
+ }
+
+ public void testSameAuthenticationManagerSpecifiedTwice() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory, myAuthManagerFactory);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+
+ try
+ {
+ new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ // PASS
+ assertEquals("Cannot configure more than one authentication manager of type " + myAuthManagerFactory.getPluginClass().getSimpleName() + ". Remove configuration for one of the authentication managers.",
+ ce.getMessage());
+ }
+ }
+
+ public void testMultipleAuthenticationManagersSpecifiedButNoDefaultSpecified() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class);
+
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+ when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(null);
+
+ try
+ {
+ new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ // PASS
+ assertEquals("If more than one authentication manager is configured a default MUST be specified.",
+ ce.getMessage());
+ }
+ }
+
+ public void testDefaultAuthenticationManagerNotKnown() throws Exception
+ {
+ String myDefaultAuthManagerSimpleClassName = "UnknownAuthenticationManager";
+
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class);
+
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+ when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(myDefaultAuthManagerSimpleClassName);
+
+ try
+ {
+ new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ // PASS
+ assertTrue("Unexpected message " + ce.getMessage(),
+ ce.getMessage().startsWith("No authentication managers configured of type " + myDefaultAuthManagerSimpleClassName + " which is specified as the default"));
+ }
+ }
+
+ public void testPortMappedToUnknownAuthenticationManager() throws Exception
+ {
+ String myDefaultAuthManagerSimpleClassName = "UnknownAuthenticationManager";
+ int portNumber = 1234;
+
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+ when(_serverConfiguration.getPortAuthenticationMappings()).thenReturn(Collections.singletonMap(portNumber, myDefaultAuthManagerSimpleClassName));
+
+ try
+ {
+ new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+ fail("Exception not thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ // PASS
+ assertEquals("Unknown authentication manager class " + myDefaultAuthManagerSimpleClassName + " configured for port " + portNumber, ce.getMessage());
+ }
+ }
+
+ public void testGetAuthenticationManagerForInetSocketAddress() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+
+ AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+
+ AuthenticationManager authenticationManager = registry.getAuthenticationManager(new InetSocketAddress(1234));
+ assertEquals("TestAuthenticationManager1", authenticationManager.getMechanisms());
+
+ registry.close();
+ }
+
+ public void testGetAuthenticationManagerForNonInetSocketAddress() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1);
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+
+ AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+
+ AuthenticationManager authenticationManager = registry.getAuthenticationManager(mock(SocketAddress.class));
+ assertEquals("TestAuthenticationManager1", authenticationManager.getMechanisms());
+
+ registry.close();
+ }
+
+ public void testGetAuthenticationManagerWithMultipleAuthenticationManager() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class);
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2);
+
+ String defaultAuthManger = myAuthManagerFactory1.getPluginName();
+ int unmappedPortNumber = 1234;
+ int mappedPortNumber = 1235;
+ String mappedAuthManager = myAuthManagerFactory2.getPluginName();
+
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+ when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(defaultAuthManger);
+ when(_serverConfiguration.getPortAuthenticationMappings()).thenReturn(Collections.singletonMap(mappedPortNumber, mappedAuthManager));
+
+ AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+
+ AuthenticationManager authenticationManager1 = registry.getAuthenticationManager(new InetSocketAddress(unmappedPortNumber));
+ assertEquals("TestAuthenticationManager1", authenticationManager1.getMechanisms());
+
+ AuthenticationManager authenticationManager2 = registry.getAuthenticationManager(new InetSocketAddress(mappedPortNumber));
+ assertEquals("TestAuthenticationManager2", authenticationManager2.getMechanisms());
+
+ registry.close();
+ }
+
+ public void testAuthenticationManagersAreClosed() throws Exception
+ {
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory1 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager1.class);
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory2 = newMockFactoryProducingMockAuthManagerImplementing(TestAuthenticationManager2.class);
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = createPluginMap(myAuthManagerFactory1, myAuthManagerFactory2);
+
+ String defaultAuthManger = myAuthManagerFactory1.getPluginName();
+ when(_pluginManager.getAuthenticationManagerPlugins()).thenReturn(pluginMap);
+ when(_serverConfiguration.getDefaultAuthenticationManager()).thenReturn(defaultAuthManger);
+
+ AuthenticationManagerRegistry registry = new AuthenticationManagerRegistry(_serverConfiguration, _pluginManager);
+
+ registry.close();
+ }
+
+ private AuthenticationManagerPluginFactory<? extends Plugin> newMockFactoryProducingMockAuthManagerImplementing(Class<? extends AuthenticationManager> authManagerClazz)
+ throws ConfigurationException
+ {
+ AuthenticationManager myAuthManager = mock(authManagerClazz);
+ when(myAuthManager.getMechanisms()).thenReturn(authManagerClazz.getSimpleName()); // used to verify the getAuthenticationManagerFor returns expected impl.
+
+ AuthenticationManagerPluginFactory myAuthManagerFactory = mock(AuthenticationManagerPluginFactory.class);
+ when(myAuthManagerFactory.getPluginClass()).thenReturn(myAuthManager.getClass());
+ when(myAuthManagerFactory.getPluginName()).thenReturn(myAuthManager.getClass().getSimpleName());
+ when(myAuthManagerFactory.newInstance(_securityConfiguration)).thenReturn(myAuthManager);
+
+ _allCreatedAuthManagers.add(myAuthManager);
+ return myAuthManagerFactory;
+ }
+
+ private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> createPluginMap(
+ AuthenticationManagerPluginFactory<? extends Plugin> myAuthManagerFactory)
+ {
+ return createPluginMap(myAuthManagerFactory, null);
+ }
+
+ private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> createPluginMap(
+ AuthenticationManagerPluginFactory<? extends Plugin> authManagerFactory1,
+ AuthenticationManagerPluginFactory<? extends Plugin> authManagerFactory2)
+ {
+ Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> pluginMap = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>();
+ pluginMap.put("config.path.unused1", authManagerFactory1);
+ if (authManagerFactory2 != null)
+ {
+ pluginMap.put("config.path.unused2", authManagerFactory2);
+ }
+ return pluginMap;
+ }
+
+ private void verifyAllCreatedAuthManagersClosed()
+ {
+ for (Iterator<AuthenticationManager> iterator = _allCreatedAuthManagers.iterator(); iterator.hasNext();)
+ {
+ AuthenticationManager authenticationManager = (AuthenticationManager) iterator.next();
+ verify(authenticationManager).close();
+ }
+ }
+
+ private interface TestAuthenticationManager1 extends AuthenticationManager
+ {
+ }
+
+ private interface TestAuthenticationManager2 extends AuthenticationManager
+ {
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
new file mode 100644
index 0000000000..c1a55ef2ad
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.manager;
+
+import javax.security.auth.x500.X500Principal;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
+
+public class ExternalAuthenticationManagerTest extends InternalBrokerBaseCase
+{
+
+ private AuthenticationManager _manager = null;
+
+ public void setUp() throws Exception
+ {
+ _manager = ExternalAuthenticationManager.INSTANCE;
+ }
+
+
+ public void tearDown() throws Exception
+ {
+ if(_manager != null)
+ {
+ _manager = null;
+ }
+ }
+
+ private ConfigurationPlugin getPlainDatabaseConfig() throws ConfigurationException
+ {
+ final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration();
+
+ XMLConfiguration xmlconfig = new XMLConfiguration();
+ xmlconfig.addProperty("pd-auth-manager.principal-database.class", PlainPasswordFilePrincipalDatabase.class.getName());
+
+ // Create a CompositeConfiguration as this is what the broker uses
+ CompositeConfiguration composite = new CompositeConfiguration();
+ composite.addConfiguration(xmlconfig);
+ config.setConfiguration("security", xmlconfig);
+ return config;
+ }
+
+
+ public void testConfiguration() throws Exception
+ {
+ AuthenticationManager authenticationManager =
+ ExternalAuthenticationManager.FACTORY.newInstance(getPlainDatabaseConfig());
+
+ assertNull("ExternalAuthenticationManager unexpectedly created when not in config", authenticationManager);
+ }
+
+ public void testGetMechanisms() throws Exception
+ {
+ assertEquals("EXTERNAL", _manager.getMechanisms());
+ }
+
+ public void testCreateSaslServer() throws Exception
+ {
+ SaslServer server = _manager.createSaslServer("EXTERNAL", "example.example.com", null);
+
+ assertEquals("Sasl Server mechanism name is not as expected", "EXTERNAL", server.getMechanismName());
+
+ try
+ {
+ server = _manager.createSaslServer("PLAIN", "example.example.com", null);
+ fail("Expected creating SaslServer with incorrect mechanism to throw an exception");
+ }
+ catch (SaslException e)
+ {
+ // pass
+ }
+ }
+
+ public void testAuthenticate() throws Exception
+ {
+ X500Principal principal = new X500Principal("CN=person, DC=example, DC=com");
+ SaslServer saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", principal);
+
+ AuthenticationResult result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be successful",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ result.getStatus());
+ assertEquals("Expected principal to be unchanged",
+ principal,
+ result.getSubject().getPrincipals().iterator().next());
+
+ saslServer = _manager.createSaslServer("EXTERNAL", "example.example.com", null);
+ result = _manager.authenticate(saslServer, new byte[0]);
+ assertNotNull(result);
+ assertEquals("Expected authentication to be unsuccessful",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ result.getStatus());
+
+ }
+
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
index 1a42fe3886..47c189e4fa 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
@@ -167,7 +167,7 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
*/
public void testSaslMechanismCreation() throws Exception
{
- SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost");
+ SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost", null);
assertNotNull(server);
// Merely tests the creation of the mechanism. Mechanisms themselves are tested
// by their own tests.
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
index bef03057ec..c0c55de92a 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
@@ -20,23 +20,19 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.security.Principal;
import junit.framework.TestCase;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-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;
-import org.apache.qpid.server.util.TestApplicationRegistry;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import java.net.InetSocketAddress;
import java.util.Collections;
/**
@@ -52,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};
}
@@ -76,14 +72,14 @@ public class RMIPasswordAuthenticatorTest extends TestCase
newSubject.equals(expectedSubject));
}
-
+
/**
* Tests a unsuccessful authentication.
*/
public void testUsernameOrPasswordInvalid()
{
_rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null));
-
+
try
{
_rmipa.authenticate(_credentials);
@@ -122,17 +118,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
*/
public void testNullAuthenticationManager() throws Exception
{
- ServerConfiguration serverConfig = new ServerConfiguration(new XMLConfiguration());
- TestApplicationRegistry reg = new TestApplicationRegistry(serverConfig)
- {
- @Override
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
- {
- return null;
- }
- };
- ApplicationRegistry.initialise(reg);
-
+ _rmipa.setAuthenticationManager(null);
try
{
_rmipa.authenticate(_credentials);
@@ -143,10 +129,6 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
}
- finally
- {
- ApplicationRegistry.remove();
- }
}
/**
@@ -185,7 +167,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.SHOULD_HAVE_2_ELEMENTS, se.getMessage());
}
-
+
// Test handling of null credentials
try
{
@@ -199,7 +181,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.CREDENTIALS_REQUIRED, se.getMessage());
}
-
+
try
{
//send a null password
@@ -212,7 +194,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.SHOULD_BE_NON_NULL, se.getMessage());
}
-
+
try
{
//send a null username
@@ -251,7 +233,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
throw new UnsupportedOperationException();
}
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
{
throw new UnsupportedOperationException();
}
@@ -276,10 +258,6 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
- public CallbackHandler getHandler(String mechanism)
- {
- return null;
- }
};
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java
index a1cbb2cbc8..cd8d91d835 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java
+++ b/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;
@@ -27,7 +47,6 @@ import org.apache.qpid.server.exchange.Exchange;
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.logging.subjects.TestBlankSubject;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.queue.AMQQueue;
@@ -41,7 +60,7 @@ import org.apache.qpid.server.store.ConfigurationRecoveryHandler.ExchangeRecover
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.QueueRecoveryHandler;
import org.apache.qpid.server.store.MessageStoreRecoveryHandler.StoredMessageRecoveryHandler;
import org.apache.qpid.server.store.Transaction.Record;
-import org.apache.qpid.server.store.derby.DerbyMessageStoreFactory;
+import org.apache.qpid.server.store.derby.DerbyMessageStore;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.util.FileUtils;
@@ -75,11 +94,11 @@ public class DurableConfigurationStoreTest extends QpidTestCase
{
super.setUp();
- _queueId = UUIDGenerator.generateUUID();
- _exchangeId = UUIDGenerator.generateUUID();
+ _queueId = UUIDGenerator.generateRandomUUID();
+ _exchangeId = UUIDGenerator.generateRandomUUID();
_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);
@@ -94,9 +113,9 @@ public class DurableConfigurationStoreTest extends QpidTestCase
_dtxRecordRecoveryHandler = mock(TransactionLogRecoveryHandler.DtxRecordRecoveryHandler.class);
when(_messageStoreRecoveryHandler.begin()).thenReturn(_storedMessageRecoveryHandler);
- when(_recoveryHandler.begin(isA(MessageStore.class))).thenReturn(_queueRecoveryHandler);
- when(_queueRecoveryHandler.completeQueueRecovery()).thenReturn(_exchangeRecoveryHandler);
- when(_exchangeRecoveryHandler.completeExchangeRecovery()).thenReturn(_bindingRecoveryHandler);
+ when(_recoveryHandler.begin(isA(MessageStore.class))).thenReturn(_exchangeRecoveryHandler);
+ when(_exchangeRecoveryHandler.completeExchangeRecovery()).thenReturn(_queueRecoveryHandler);
+ when(_queueRecoveryHandler.completeQueueRecovery()).thenReturn(_bindingRecoveryHandler);
when(_bindingRecoveryHandler.completeBindingRecovery()).thenReturn(_linkRecoveryHandler);
when(_logRecoveryHandler.begin(any(MessageStore.class))).thenReturn(_queueEntryRecoveryHandler);
when(_queueEntryRecoveryHandler.completeQueueEntryRecovery()).thenReturn(_dtxRecordRecoveryHandler);
@@ -142,8 +161,8 @@ public class DurableConfigurationStoreTest extends QpidTestCase
public void testBindQueue() throws Exception
{
AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false);
- Binding binding = new Binding(UUIDGenerator.generateUUID(), ROUTING_KEY, queue, _exchange,
- FieldTable.convertToMap(_bindingArgs));
+ Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue,
+ _exchange, FieldTable.convertToMap(_bindingArgs));
_store.bindQueue(binding);
reopenStore();
@@ -156,8 +175,8 @@ public class DurableConfigurationStoreTest extends QpidTestCase
public void testUnbindQueue() throws Exception
{
AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false);
- Binding binding = new Binding(UUIDGenerator.generateUUID(), ROUTING_KEY, queue, _exchange,
- FieldTable.convertToMap(_bindingArgs));
+ Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue,
+ _exchange, FieldTable.convertToMap(_bindingArgs));
_store.bindQueue(binding);
_store.unbindQueue(binding);
@@ -173,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
@@ -187,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);
@@ -205,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
@@ -222,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;
}
@@ -262,14 +325,14 @@ public class DurableConfigurationStoreTest extends QpidTestCase
protected MessageStore createStore() throws Exception
{
- String storeFactoryClass = System.getProperty(MS_FACTORY_CLASS_NAME_KEY);
- if (storeFactoryClass == null)
+ String storeClass = System.getProperty(MESSAGE_STORE_CLASS_NAME_KEY);
+ if (storeClass == null)
{
- storeFactoryClass = DerbyMessageStoreFactory.class.getName();
+ storeClass = DerbyMessageStore.class.getName();
}
CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
- MessageStoreFactory factory = (MessageStoreFactory) Class.forName(storeFactoryClass).newInstance();
- return factory.createMessageStore();
+ MessageStore messageStore = (MessageStore) Class.forName(storeClass).newInstance();
+ return messageStore;
}
public void testRecordXid() throws Exception
@@ -297,7 +360,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase
private Record getTestRecord(long messageNumber)
{
- UUID queueId1 = UUIDGenerator.generateUUID();
+ UUID queueId1 = UUIDGenerator.generateRandomUUID();
TransactionLogResource queue1 = mock(TransactionLogResource.class);
when(queue1.getId()).thenReturn(queueId1);
EnqueableMessage message1 = mock(EnqueableMessage.class);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java
new file mode 100644
index 0000000000..f1976ecee3
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreQuotaEventsTestBase.java
@@ -0,0 +1,178 @@
+/*
+ *
+ * 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 java.io.File;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.util.FileUtils;
+
+public abstract class MessageStoreQuotaEventsTestBase extends QpidTestCase implements EventListener, TransactionLogResource
+{
+ private static final Logger _logger = Logger.getLogger(MessageStoreQuotaEventsTestBase.class);
+
+ protected static final byte[] MESSAGE_DATA = new byte[32 * 1024];
+
+ private MessageStore _store;
+ private File _storeLocation;
+
+ private List<Event> _events;
+ private UUID _transactionResource;
+
+ protected abstract MessageStore createStore() throws Exception;
+
+ protected abstract void applyStoreSpecificConfiguration(XMLConfiguration config);
+
+ protected abstract int getNumberOfMessagesToFillStore();
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ _storeLocation = new File(new File(TMP_FOLDER), getTestName());
+ FileUtils.delete(_storeLocation, true);
+
+ XMLConfiguration config = new XMLConfiguration();
+ config.addProperty("environment-path", _storeLocation.getAbsolutePath());
+ applyStoreSpecificConfiguration(config);
+
+ _store = createStore();
+ _store.configureConfigStore("test", null, config);
+
+ _transactionResource = UUID.randomUUID();
+ _events = new ArrayList<Event>();
+ _store.addEventListener(this, Event.PERSISTENT_MESSAGE_SIZE_OVERFULL, Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ FileUtils.delete(_storeLocation, true);
+ }
+
+ public void testOverflow() throws Exception
+ {
+ Transaction transaction = _store.newTransaction();
+
+ List<EnqueableMessage> messages = new ArrayList<EnqueableMessage>();
+ for (int i = 0; i < getNumberOfMessagesToFillStore(); i++)
+ {
+ EnqueableMessage m = addMessage(i);
+ messages.add(m);
+ transaction.enqueueMessage(this, m);
+ }
+ transaction.commitTran();
+
+ assertEvent(1, Event.PERSISTENT_MESSAGE_SIZE_OVERFULL);
+
+ for (EnqueableMessage m : messages)
+ {
+ m.getStoredMessage().remove();
+ }
+
+ assertEvent(2, Event.PERSISTENT_MESSAGE_SIZE_UNDERFULL);
+ }
+
+ protected EnqueableMessage addMessage(long id)
+ {
+ MessagePublishInfo pubInfoBody = new MessagePublishInfoImpl(new AMQShortString(getName()), false, false,
+ new AMQShortString(getName()));
+ BasicContentHeaderProperties props = new BasicContentHeaderProperties();
+ props.setDeliveryMode(Integer.valueOf(BasicContentHeaderProperties.PERSISTENT).byteValue());
+ props.setContentType(getTestName());
+
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+ int classForBasic = methodRegistry.createBasicQosOkBody().getClazz();
+ ContentHeaderBody contentHeaderBody = new ContentHeaderBody(classForBasic, 1, props, MESSAGE_DATA.length);
+
+ MessageMetaData metaData = new MessageMetaData(pubInfoBody, contentHeaderBody, 1);
+ StoredMessage<MessageMetaData> handle = _store.addMessage(metaData);
+ handle.addContent(0, ByteBuffer.wrap(MESSAGE_DATA));
+ TestMessage message = new TestMessage(id, handle);
+ return message;
+ }
+
+ @Override
+ public void event(Event event)
+ {
+ _logger.debug("Test event listener received event " + event);
+ _events.add(event);
+ }
+
+ private void assertEvent(int expectedNumberOfEvents, Event... expectedEvents)
+ {
+ assertEquals("Unexpected number of events received ", expectedNumberOfEvents, _events.size());
+ for (Event event : expectedEvents)
+ {
+ assertTrue("Expected event is not found:" + event, _events.contains(event));
+ }
+ }
+
+ @Override
+ public UUID getId()
+ {
+ return _transactionResource;
+ }
+
+ private static class TestMessage implements EnqueableMessage
+ {
+ private final StoredMessage<?> _handle;
+ private final long _messageId;
+
+ public TestMessage(long messageId, StoredMessage<?> handle)
+ {
+ _messageId = messageId;
+ _handle = handle;
+ }
+
+ public long getMessageNumber()
+ {
+ return _messageId;
+ }
+
+ public boolean isPersistent()
+ {
+ return true;
+ }
+
+ public StoredMessage<?> getStoredMessage()
+ {
+ return _handle;
+ }
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
index 3fb0776083..a1536565ad 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java
@@ -59,7 +59,6 @@ import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
/**
* This tests the MessageStores by using the available interfaces.
@@ -100,10 +99,10 @@ 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.factoryclass", getTestProfileMessageStoreFactoryClassName());
+ _config.addProperty("store.class", getTestProfileMessageStoreClassName());
_config.addProperty("store.environment-path", storePath);
cleanup(new File(storePath));
@@ -268,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);
}
/**
@@ -702,8 +695,8 @@ public class MessageStoreTest extends InternalBrokerBaseCase
//Ideally we would be able to use the QueueDeclareHandler here.
try
{
- queue = AMQQueueFactory.createAMQQueueImpl(queueName, durable, queueOwner, false, exclusive,
- getVirtualHost(), queueArguments);
+ queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName.asString(), durable, queueOwner.asString(), false, exclusive,
+ getVirtualHost(), FieldTable.convertToMap(queueArguments));
validateQueueProperties(queue, usePriority, durable, exclusive, lastValueQueue);
@@ -741,7 +734,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
try
{
- exchange = type.newInstance(UUIDGenerator.generateUUID(), getVirtualHost(), name, durable, 0, false);
+ exchange = type.newInstance(UUIDGenerator.generateRandomUUID(), getVirtualHost(), name, durable, 0, false);
}
catch (AMQException e)
{
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
index 42746f9119..c309dad5eb 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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 java.util.ArrayList;
@@ -12,22 +28,6 @@ import org.apache.qpid.server.logging.messages.ConfigStoreMessages;
import org.apache.qpid.server.logging.messages.MessageStoreMessages;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
-/**
- * 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 OperationalLoggingListenerTest extends TestCase
{
@@ -73,11 +73,11 @@ public class OperationalLoggingListenerTest extends TestCase
}
- messageStore.attainState(State.CONFIGURING);
+ messageStore.attainState(State.INITIALISING);
assertEquals("Unexpected number of operational log messages on configuring", 1, messages.size());
assertEquals(messages.remove(0).toString(), ConfigStoreMessages.CREATED().toString());
- messageStore.attainState(State.CONFIGURED);
+ messageStore.attainState(State.INITIALISED);
assertEquals("Unexpected number of operational log messages on CONFIGURED", setStoreLocation ? 3 : 2, messages.size());
assertEquals(messages.remove(0).toString(), MessageStoreMessages.CREATED().toString());
assertEquals(messages.remove(0).toString(), TransactionLogMessages.CREATED().toString());
@@ -86,7 +86,7 @@ public class OperationalLoggingListenerTest extends TestCase
assertEquals(messages.remove(0).toString(), MessageStoreMessages.STORE_LOCATION(STORE_LOCATION).toString());
}
- messageStore.attainState(State.RECOVERING);
+ messageStore.attainState(State.ACTIVATING);
assertEquals("Unexpected number of operational log messages on RECOVERING", 1, messages.size());
assertEquals(messages.remove(0).toString(), MessageStoreMessages.RECOVERY_START().toString());
@@ -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/java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java
index 97c88ca1d3..18efb976eb 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java
@@ -45,8 +45,8 @@ public class StateManagerTest extends TestCase implements EventListener
{
assertEquals(State.INITIAL, _manager.getState());
- _manager.stateTransition(State.INITIAL, State.CONFIGURING);
- assertEquals(State.CONFIGURING, _manager.getState());
+ _manager.attainState(State.INITIALISING);
+ assertEquals(State.INITIALISING, _manager.getState());
}
public void testStateTransitionDisallowed()
@@ -55,7 +55,7 @@ public class StateManagerTest extends TestCase implements EventListener
try
{
- _manager.stateTransition(State.ACTIVE, State.CLOSING);
+ _manager.attainState(State.CLOSING);
fail("Exception not thrown");
}
catch (IllegalStateException e)
@@ -98,22 +98,29 @@ public class StateManagerTest extends TestCase implements EventListener
public void testValidStateTransitions()
{
assertEquals(State.INITIAL, _manager.getState());
- performValidTransition(StateManager.CONFIGURE);
- performValidTransition(StateManager.CONFIGURE_COMPLETE);
- performValidTransition(StateManager.RECOVER);
+ performValidTransition(StateManager.INITIALISE);
+ performValidTransition(StateManager.INITALISE_COMPLETE);
performValidTransition(StateManager.ACTIVATE);
+ performValidTransition(StateManager.ACTIVATE_COMPLETE);
performValidTransition(StateManager.QUIESCE);
performValidTransition(StateManager.QUIESCE_COMPLETE);
performValidTransition(StateManager.RESTART);
- performValidTransition(StateManager.ACTIVATE);
+ performValidTransition(StateManager.ACTIVATE_COMPLETE);
performValidTransition(StateManager.CLOSE_ACTIVE);
performValidTransition(StateManager.CLOSE_COMPLETE);
+
+ _manager = new StateManager(this);
+ assertEquals(State.INITIAL, _manager.getState());
+ performValidTransition(StateManager.INITIALISE);
+ performValidTransition(StateManager.INITALISE_COMPLETE);
+ performValidTransition(StateManager.CLOSE_INITIALISED);
+ performValidTransition(StateManager.CLOSE_COMPLETE);
_manager = new StateManager(this);
- performValidTransition(StateManager.CONFIGURE);
- performValidTransition(StateManager.CONFIGURE_COMPLETE);
- performValidTransition(StateManager.RECOVER);
+ performValidTransition(StateManager.INITIALISE);
+ performValidTransition(StateManager.INITALISE_COMPLETE);
performValidTransition(StateManager.ACTIVATE);
+ performValidTransition(StateManager.ACTIVATE_COMPLETE);
performValidTransition(StateManager.QUIESCE);
performValidTransition(StateManager.QUIESCE_COMPLETE);
performValidTransition(StateManager.CLOSE_QUIESCED);
@@ -132,54 +139,50 @@ public class StateManagerTest extends TestCase implements EventListener
{
assertEquals(State.INITIAL, _manager.getState());
-
- performInvalidTransitions(StateManager.CONFIGURE, State.CONFIGURED);
- performInvalidTransitions(StateManager.CONFIGURE_COMPLETE, State.RECOVERING);
- performInvalidTransitions(StateManager.RECOVER, State.ACTIVE);
- performInvalidTransitions(StateManager.ACTIVATE, State.QUIESCING, State.CLOSING);
+ performInvalidTransitions(StateManager.INITIALISE, State.INITIALISED);
+ performInvalidTransitions(StateManager.INITALISE_COMPLETE, State.ACTIVATING, State.CLOSING);
+ performInvalidTransitions(StateManager.ACTIVATE, State.ACTIVE);
+ performInvalidTransitions(StateManager.ACTIVATE_COMPLETE, State.QUIESCING, State.CLOSING, State.INITIALISED);
performInvalidTransitions(StateManager.QUIESCE, State.QUIESCED);
- performInvalidTransitions(StateManager.QUIESCE_COMPLETE, State.RECOVERING, State.CLOSING);
+ performInvalidTransitions(StateManager.QUIESCE_COMPLETE, State.ACTIVATING, State.CLOSING);
performInvalidTransitions(StateManager.CLOSE_QUIESCED, State.CLOSED);
performInvalidTransitions(StateManager.CLOSE_COMPLETE);
-
-
-
}
- private void performInvalidTransitions(StateManager.Transition preTransition, State... validTransitions)
+ private void performInvalidTransitions(StateManager.Transition preTransition, State... validEndStates)
{
if(preTransition != null)
{
performValidTransition(preTransition);
}
- EnumSet<State> nextStates = EnumSet.allOf(State.class);
+ EnumSet<State> endStates = EnumSet.allOf(State.class);
- if(validTransitions != null)
+ if(validEndStates != null)
{
- for(State state: validTransitions)
+ for(State state: validEndStates)
{
- nextStates.remove(state);
+ endStates.remove(state);
}
}
- for(State nextState : nextStates)
+ for(State invalidEndState : endStates)
{
- performInvalidStateTransition(nextState);
+ performInvalidStateTransition(invalidEndState);
}
}
- private void performInvalidStateTransition(State state)
+ private void performInvalidStateTransition(State invalidEndState)
{
try
{
_event = null;
State startState = _manager.getState();
- _manager.attainState(state);
- fail("Invalid state transition performed: " + startState + " to " + state);
+ _manager.attainState(invalidEndState);
+ fail("Invalid state transition performed: " + startState + " to " + invalidEndState);
}
catch(IllegalStateException e)
{
@@ -188,6 +191,7 @@ public class StateManagerTest extends TestCase implements EventListener
assertNull("No event should have be fired", _event);
}
+ @Override
public void event(Event event)
{
_event = event;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java
new file mode 100644
index 0000000000..5d316fca43
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/derby/DerbyMessageStoreQuotaEventsTest.java
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.derby;
+
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.MessageStoreQuotaEventsTestBase;
+
+public class DerbyMessageStoreQuotaEventsTest extends MessageStoreQuotaEventsTestBase
+{
+ private static final Logger _logger = Logger.getLogger(DerbyMessageStoreQuotaEventsTest.class);
+
+ private static final int NUMBER_OF_MESSAGES_TO_OVERFILL_STORE = 10;
+
+ /**
+ * Estimated using an assumption that a physical disk space occupied by a
+ * message is 3 times bigger then a message size
+ */
+ private static final int OVERFULL_SIZE = (int) (MESSAGE_DATA.length * 3 * NUMBER_OF_MESSAGES_TO_OVERFILL_STORE * 0.8);
+
+ private static final int UNDERFULL_SIZE = (int) (OVERFULL_SIZE * 0.8);
+
+ @Override
+ protected int getNumberOfMessagesToFillStore()
+ {
+ return NUMBER_OF_MESSAGES_TO_OVERFILL_STORE;
+ }
+
+ @Override
+ protected void applyStoreSpecificConfiguration(XMLConfiguration config)
+ {
+ _logger.debug("Applying store specific config. overfull-sze=" + OVERFULL_SIZE + ", underfull-size=" + UNDERFULL_SIZE);
+
+ config.addProperty("overfull-size", OVERFULL_SIZE);
+ config.addProperty("underfull-size", UNDERFULL_SIZE);
+ }
+
+ @Override
+ protected MessageStore createStore() throws Exception
+ {
+ return new DerbyMessageStore();
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
index 5ba9c0c015..8c5d2684ff 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
+++ b/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;
@@ -42,7 +48,7 @@ public class MockSubscription implements Subscription
private AMQShortString tag = new AMQShortString("mocktag");
private AMQQueue queue = null;
private StateListener _listener = null;
- private AMQQueue.Context _queueContext = null;
+ private volatile AMQQueue.Context _queueContext = null;
private State _state = State.ACTIVE;
private ArrayList<QueueEntry> messages = new ArrayList<QueueEntry>();
private final Lock _stateChangeLock = new 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 getQMFId()
+ {
+ 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;
+ }
+
+ @Override
+ public int getConsumerCount()
+ {
+ 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 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/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java
deleted file mode 100644
index dcb3692cf5..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/transport/ServerConnectionMBeanTest.java
+++ /dev/null
@@ -1,230 +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.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(), ""));
- _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/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java
new file mode 100644
index 0000000000..1aa91fa98a
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.txn;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+
+import org.apache.qpid.server.message.EnqueableMessage;
+import org.apache.qpid.server.queue.BaseQueue;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.StoreFuture;
+import org.apache.qpid.server.store.Transaction;
+import org.apache.qpid.server.txn.AsyncAutoCommitTransaction.FutureRecorder;
+import org.apache.qpid.server.txn.ServerTransaction.Action;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AsyncAutoCommitTransactionTest extends QpidTestCase
+{
+ private static final String STRICT_ORDER_SYSTEM_PROPERTY = AsyncAutoCommitTransaction.QPID_STRICT_ORDER_WITH_MIXED_DELIVERY_MODE;
+
+ private FutureRecorder _futureRecorder = mock(FutureRecorder.class);
+ private EnqueableMessage _message = mock(EnqueableMessage.class);
+ private BaseQueue _queue = mock(BaseQueue.class);
+ private MessageStore _messageStore = mock(MessageStore.class);
+ private Transaction _storeTransaction = mock(Transaction.class);
+ private Action _postTransactionAction = mock(Action.class);
+ private StoreFuture _future = mock(StoreFuture.class);
+
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ when(_messageStore.newTransaction()).thenReturn(_storeTransaction);
+ when(_storeTransaction.commitTranAsync()).thenReturn(_future);
+ when(_queue.isDurable()).thenReturn(true);
+ }
+
+ public void testEnqueuePersistentMessagePostCommitNotCalledWhenFutureAlreadyComplete() throws Exception
+ {
+ setTestSystemProperty(STRICT_ORDER_SYSTEM_PROPERTY, "false");
+
+ when(_message.isPersistent()).thenReturn(true);
+ when(_future.isComplete()).thenReturn(true);
+
+ AsyncAutoCommitTransaction asyncAutoCommitTransaction =
+ new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
+
+ asyncAutoCommitTransaction.enqueue(_queue, _message, _postTransactionAction);
+
+ verify(_storeTransaction).enqueueMessage(_queue, _message);
+ verify(_futureRecorder).recordFuture(_future, _postTransactionAction);
+ verifyZeroInteractions(_postTransactionAction);
+ }
+
+ public void testEnqueuePersistentMessageOnMultiplQueuesPostCommitNotCalled() throws Exception
+ {
+ setTestSystemProperty(STRICT_ORDER_SYSTEM_PROPERTY, "false");
+
+ when(_message.isPersistent()).thenReturn(true);
+ when(_future.isComplete()).thenReturn(true);
+
+ AsyncAutoCommitTransaction asyncAutoCommitTransaction =
+ new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
+
+ asyncAutoCommitTransaction.enqueue(Collections.singletonList(_queue), _message, _postTransactionAction, System.currentTimeMillis());
+
+ verify(_storeTransaction).enqueueMessage(_queue, _message);
+ verify(_futureRecorder).recordFuture(_future, _postTransactionAction);
+ verifyZeroInteractions(_postTransactionAction);
+ }
+
+ public void testEnqueuePersistentMessagePostCommitNotCalledWhenFutureNotYetComplete() throws Exception
+ {
+ setTestSystemProperty(STRICT_ORDER_SYSTEM_PROPERTY, "false");
+
+ when(_message.isPersistent()).thenReturn(true);
+ when(_future.isComplete()).thenReturn(false);
+
+ AsyncAutoCommitTransaction asyncAutoCommitTransaction =
+ new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
+
+ asyncAutoCommitTransaction.enqueue(_queue, _message, _postTransactionAction);
+
+ verify(_storeTransaction).enqueueMessage(_queue, _message);
+ verify(_futureRecorder).recordFuture(_future, _postTransactionAction);
+ verifyZeroInteractions(_postTransactionAction);
+ }
+
+ public void testEnqueueTransientMessagePostCommitIsCalledWhenNotBehavingStrictly() throws Exception
+ {
+ setTestSystemProperty(STRICT_ORDER_SYSTEM_PROPERTY, "false");
+
+ when(_message.isPersistent()).thenReturn(false);
+
+ AsyncAutoCommitTransaction asyncAutoCommitTransaction =
+ new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
+
+ asyncAutoCommitTransaction.enqueue(_queue, _message, _postTransactionAction);
+
+ verifyZeroInteractions(_storeTransaction);
+ verify(_postTransactionAction).postCommit();
+ verifyZeroInteractions(_futureRecorder);
+ }
+
+ public void testEnqueueTransientMessagePostCommitIsCalledWhenBehavingStrictly() throws Exception
+ {
+ setTestSystemProperty(STRICT_ORDER_SYSTEM_PROPERTY, "true");
+
+ when(_message.isPersistent()).thenReturn(false);
+
+ AsyncAutoCommitTransaction asyncAutoCommitTransaction =
+ new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
+
+ asyncAutoCommitTransaction.enqueue(_queue, _message, _postTransactionAction);
+
+ verifyZeroInteractions(_storeTransaction);
+ verify(_futureRecorder).recordFuture(StoreFuture.IMMEDIATE_FUTURE, _postTransactionAction);
+ verifyZeroInteractions(_postTransactionAction);
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java b/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
index af49238998..0221f3d509 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
+++ b/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/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
index 8a34e92985..d7a9078412 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
@@ -20,8 +20,7 @@
*/
package org.apache.qpid.server.util;
-import java.util.UUID;
-
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.AMQException;
@@ -38,6 +37,7 @@ import org.apache.qpid.server.exchange.Exchange;
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.model.UUIDGenerator;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -45,7 +45,6 @@ import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
-import org.apache.qpid.server.store.TestableMemoryMessageStoreFactory;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -68,10 +67,10 @@ public class InternalBrokerBaseCase extends QpidTestCase
super.setUp();
_configXml.addProperty("virtualhosts.virtualhost.name", "test");
- _configXml.addProperty("virtualhosts.virtualhost.test.store.factoryclass", TestableMemoryMessageStoreFactory.class.getName());
+ _configXml.addProperty("virtualhosts.virtualhost.test.store.class", TestableMemoryMessageStore.class.getName());
_configXml.addProperty("virtualhosts.virtualhost(-1).name", getName());
- _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.factoryclass", TestableMemoryMessageStoreFactory.class.getName());
+ _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName());
createBroker();
}
@@ -85,7 +84,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
configure();
- _registry = new TestApplicationRegistry(_configuration);
+ _registry = createApplicationRegistry();
ApplicationRegistry.initialise(_registry);
_registry.getVirtualHostRegistry().setDefaultVirtualHostName(getName());
_virtualHost = _registry.getVirtualHostRegistry().getVirtualHost(getName());
@@ -93,7 +92,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
QUEUE_NAME = new AMQShortString("test");
// Create a queue on the test Vhost.. this will aid in diagnosing duff tests
// as the ExpiredMessage Task will log with the test Name.
- _queue = AMQQueueFactory.createAMQQueueImpl(QUEUE_NAME, false, new AMQShortString("testowner"),
+ _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), QUEUE_NAME.asString(), false, "testowner",
false, false, _virtualHost, null);
Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
@@ -102,7 +101,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
_virtualHost = _registry.getVirtualHostRegistry().getVirtualHost("test");
_messageStore = _virtualHost.getMessageStore();
- _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(getName()), false, new AMQShortString("testowner"),
+ _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName(), false, "testowner",
false, false, _virtualHost, null);
_virtualHost.getQueueRegistry().registerQueue(_queue);
@@ -119,6 +118,11 @@ public class InternalBrokerBaseCase extends QpidTestCase
_session.addChannel(_channel);
}
+ protected IApplicationRegistry createApplicationRegistry() throws ConfigurationException
+ {
+ return new TestApplicationRegistry(_configuration);
+ }
+
protected void configure()
{
// Allow other tests to override configuration
@@ -250,7 +254,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
channel.publishContentHeader(_headerBody);
}
-
+ channel.sync();
}
public void acknowledge(AMQChannel channel, long deliveryTag)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index 7aa5ed23fe..a64ab620ab 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -20,6 +20,9 @@
*/
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;
@@ -28,9 +31,11 @@ import org.apache.qpid.server.logging.NullRootMessageLogger;
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.plugins.PluginManager;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import java.util.Properties;
@@ -51,11 +56,10 @@ public class TestApplicationRegistry extends ApplicationRegistry
super.initialise();
}
- /**
- * @see org.apache.qpid.server.registry.ApplicationRegistry#createAuthenticationManager()
- */
@Override
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(
+ ServerConfiguration _configuration, PluginManager _pluginManager)
+ throws ConfigurationException
{
final Properties users = new Properties();
users.put("guest","guest");
@@ -63,7 +67,7 @@ public class TestApplicationRegistry extends ApplicationRegistry
final PropertiesPrincipalDatabase ppd = new PropertiesPrincipalDatabase(users);
- AuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager()
+ final AuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager()
{
/**
@@ -83,12 +87,35 @@ public class TestApplicationRegistry extends ApplicationRegistry
super.initialise();
}
};
-
pdam.initialise();
- return pdam;
- }
+ return new IAuthenticationManagerRegistry()
+ {
+ @Override
+ public void close()
+ {
+ pdam.close();
+ }
+
+ @Override
+ public AuthenticationManager getAuthenticationManager(
+ SocketAddress address)
+ {
+ return pdam;
+ }
+ @Override
+ public Map<String, AuthenticationManager> getAvailableAuthenticationManagers()
+ {
+ return Collections.singletonMap(pdam.getClass().getName(), pdam);
+ }
+
+ @Override
+ public void addRegistryChangeListener(RegistryChangeListener listener)
+ {
+ }
+ };
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java
index 0794154e47..8b4a52bb79 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java
@@ -64,4 +64,50 @@ public class HouseKeepingTaskTest extends QpidTestCase
//clean up the test actor
CurrentActor.remove();
}
+
+ public void testThreadNameIsSetForDurationOfTask() throws Exception
+ {
+ //create and set a test actor
+ LogActor testActor = new TestLogActor(new NullRootMessageLogger());
+ CurrentActor.set(testActor);
+
+ String originalThreadName = Thread.currentThread().getName();
+
+ String vhostName = "HouseKeepingTaskTestVhost";
+
+ String expectedThreadNameDuringExecution = vhostName + ":" + "ThreadNameRememberingTask";
+
+ ThreadNameRememberingTask testTask = new ThreadNameRememberingTask(new MockVirtualHost(vhostName));
+
+ testTask.run();
+
+ assertEquals("Thread name should have been set during execution", expectedThreadNameDuringExecution, testTask.getThreadNameDuringExecution());
+ assertEquals("Thread name should have been reverted after task has run", originalThreadName, Thread.currentThread().getName());
+
+ //clean up the test actor
+ CurrentActor.remove();
+ }
+
+
+ private static final class ThreadNameRememberingTask extends HouseKeepingTask
+ {
+ private String _threadNameDuringExecution;
+
+ private ThreadNameRememberingTask(VirtualHost vhost)
+ {
+ super(vhost);
+ }
+
+ @Override
+ public void execute()
+ {
+ _threadNameDuringExecution = Thread.currentThread().getName(); // store current thread name so we can assert it later
+ throw new RuntimeException("deliberate exception to check that thread name still gets reverted");
+ }
+
+ public String getThreadNameDuringExecution()
+ {
+ return _threadNameDuringExecution;
+ }
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
index 91174c5d10..290c465785 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
+++ b/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;
@@ -222,6 +216,12 @@ public class MockVirtualHost implements VirtualHost
return null;
}
+ @Override
+ public UUID getQMFId()
+ {
+ return null;
+ }
+
public ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> getParent()
{
return null;
@@ -257,11 +257,6 @@ public class MockVirtualHost implements VirtualHost
}
- public boolean isStatisticsEnabled()
- {
- return false;
- }
-
public void registerMessageDelivered(long messageSize)
{
@@ -277,14 +272,16 @@ public class MockVirtualHost implements VirtualHost
}
- public void setStatisticsEnabled(boolean enabled)
+ public State getState()
{
+ return State.ACTIVE;
+ }
+ public void block()
+ {
}
- @Override
- public State getState()
+ public void unblock()
{
- return State.ACTIVE;
}
} \ No newline at end of file
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java
index 87eb0f9d16..b8ba76e43d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java
@@ -27,7 +27,7 @@ import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.MemoryMessageStoreFactory;
+import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.util.TestApplicationRegistry;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -192,7 +192,7 @@ public class VirtualHostImplTest extends QpidTestCase
writer.write(" <name>" + vhostName + "</name>");
writer.write(" <" + vhostName + ">");
writer.write(" <store>");
- writer.write(" <factoryclass>" + MemoryMessageStoreFactory.class.getName() + "</factoryclass>");
+ writer.write(" <class>" + MemoryMessageStore.class.getName() + "</class>");
writer.write(" </store>");
if(exchangeName != null && !dontDeclare)
{
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java
index fdd163b323..aa8448b99d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java
@@ -146,7 +146,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new DirectExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new DirectExchange(), null));
policy.performPolicy(queue);
@@ -165,7 +165,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new TopicExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
queue.setAutoDelete(false);
@@ -186,7 +186,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
final MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new TopicExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
setQueueToAutoDelete(queue);
@@ -207,7 +207,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new TopicExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
policy.performPolicy(queue);
@@ -233,7 +233,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new TopicExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
policy.performPolicy(queue);
@@ -253,7 +253,7 @@ public class TopicDeletePolicyTest extends InternalBrokerBaseCase
MockAMQQueue queue = createOwnedQueue();
- queue.addBinding(new Binding(null, "bindingKey", queue, new TopicExchange(), null));
+ queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
policy.performPolicy(queue);