summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/.gitignore1
-rw-r--r--java/amqp-1-0-client-jms/build.xml3
-rw-r--r--java/amqp-1-0-client-jms/example/build.xml (renamed from java/systests/etc/config-systests-bdb-settings.xml)14
-rw-r--r--java/amqp-1-0-client-jms/resources/LICENSE204
-rw-r--r--java/amqp-1-0-client-jms/resources/NOTICE5
-rw-r--r--java/amqp-1-0-client-jms/resources/README.txt7
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java79
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java172
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DecodedDestination.java47
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java6
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java183
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java5
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java20
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java151
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java2
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java20
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java2
-rw-r--r--java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java3
-rw-r--r--java/amqp-1-0-client/build.xml3
-rw-r--r--java/amqp-1-0-client/example/build.xml (renamed from java/systests/etc/config-systests-derby-mem-settings.xml)14
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java)0
-rw-r--r--java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java (renamed from java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java)0
-rw-r--r--java/amqp-1-0-client/resources/LICENSE204
-rw-r--r--java/amqp-1-0-client/resources/NOTICE5
-rw-r--r--java/amqp-1-0-client/resources/README.txt7
-rw-r--r--java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java115
-rw-r--r--java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java77
-rw-r--r--java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java35
-rw-r--r--java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java331
-rw-r--r--java/amqp-1-0-common/resources/LICENSE204
-rw-r--r--java/amqp-1-0-common/resources/NOTICE5
-rw-r--r--java/amqp-1-0-common/resources/README.txt7
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java27
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java8
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java23
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java13
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java4
-rw-r--r--java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java24
-rwxr-xr-xjava/bdbstore/bin/backup.sh5
-rw-r--r--java/bdbstore/build.xml17
-rw-r--r--java/bdbstore/jmx/MANIFEST.MF20
-rw-r--r--java/bdbstore/jmx/build.xml6
-rw-r--r--java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java3
-rw-r--r--java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java11
-rw-r--r--java/bdbstore/jmx/src/main/resources/META-INF/services/org.apache.qpid.server.jmx.MBeanProvider18
-rw-r--r--java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java36
-rw-r--r--java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java12
-rw-r--r--java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java3
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java169
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStore.java4
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreFactory.java41
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java4
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java)40
-rw-r--r--java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CommitThreadWrapper.java31
-rw-r--r--java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory20
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java2
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreTest.java74
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java2
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgradeTestPreparer.java62
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java127
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java6
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java36
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageStoreCreatorTest.java44
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java39
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java47
-rw-r--r--java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java63
-rw-r--r--java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdbbin1361990 -> 1366145 bytes
-rw-r--r--java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdbbin1361990 -> 1366145 bytes
-rw-r--r--java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdbbin1333643 -> 1336563 bytes
-rw-r--r--java/broker-plugins/access-control/MANIFEST.MF41
-rw-r--r--java/broker-plugins/access-control/build.xml6
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java7
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java102
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java102
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java114
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java88
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java12
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java184
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java44
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java113
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java (renamed from java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java)25
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java26
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java33
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java156
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java177
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java117
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties2
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java41
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java83
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java (renamed from java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java)96
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java59
-rw-r--r--java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory19
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java66
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java87
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java95
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java79
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java (renamed from java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java)117
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java53
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java99
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java115
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java69
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java (renamed from java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java)127
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java92
-rw-r--r--java/broker-plugins/firewall/MANIFEST.MF34
-rw-r--r--java/broker-plugins/firewall/build.xml34
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java136
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java137
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java41
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java103
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java322
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java294
-rw-r--r--java/broker-plugins/management-http/MANIFEST.MF70
-rw-r--r--java/broker-plugins/management-http/build.xml51
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java416
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java)34
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java248
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java73
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java77
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java2
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java5
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java208
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java118
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java447
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java15
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java65
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java8
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java41
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java38
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java95
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java9
-rw-r--r--java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java103
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html37
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html (renamed from java/systests/etc/config-systests-derby-mem.xml)19
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html38
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html (renamed from java/systests/etc/config-systests-bdb.xml)17
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/index.html (renamed from java/broker-plugins/management-http/src/main/java/resources/management.html)6
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js59
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js7
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js2
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js109
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js4
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js8
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js204
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js108
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js251
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js6
-rw-r--r--java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html (renamed from java/systests/etc/config-systests-derby-settings.xml)11
-rw-r--r--java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory19
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java61
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java245
-rw-r--r--java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java74
-rw-r--r--java/broker-plugins/management-jmx/MANIFEST.MF66
-rw-r--r--java/broker-plugins/management-jmx/build.xml20
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java68
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java136
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java76
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java407
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java343
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java49
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java193
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java101
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java95
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java26
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java100
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java56
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java53
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java66
-rw-r--r--java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java5
-rw-r--r--java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory19
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java60
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java170
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java101
-rw-r--r--java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java6
-rwxr-xr-xjava/broker/bin/qpid-server4
-rw-r--r--java/broker/bin/qpid-server.bat4
-rw-r--r--java/broker/build.xml30
-rw-r--r--java/broker/etc/broker_example.acl94
-rw-r--r--java/broker/etc/config.xml106
-rw-r--r--java/broker/etc/groups29
-rw-r--r--java/broker/etc/log4j.xml23
-rwxr-xr-xjava/broker/src/main/java/broker.bnd2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java586
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java156
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java105
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java98
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java205
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java256
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java157
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java95
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java76
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java98
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java120
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java102
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java2086
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java61
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java193
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Broker.java376
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java156
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Main.java255
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java74
-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.java69
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java114
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java170
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java71
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java145
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java102
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java201
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java203
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java98
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java)13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java)7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java146
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java60
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java115
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java)25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java137
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java86
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java123
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java45
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java)12
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java1031
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java90
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java137
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java140
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java137
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java132
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java78
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java270
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java99
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java197
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java111
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java)169
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java86
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java163
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java55
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java139
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java112
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java)33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java)36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java)34
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java711
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java327
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java205
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java)25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java78
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java74
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java324
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java101
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java1
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java53
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java1
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java)32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java (renamed from java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java)47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java41
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java53
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java913
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java692
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java62
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java62
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacade.java (renamed from java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java)22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java8
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java14
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Broker.java124
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java1
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Group.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java55
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Model.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Port.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java97
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/Transport.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java65
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/User.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java271
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java198
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java152
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java251
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java199
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java77
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java807
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java550
-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/KeyStoreAdapter.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java)30
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java169
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java222
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java43
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java332
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java117
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java31
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java (renamed from java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java)5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java72
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java91
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties135
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java403
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java99
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java3
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java92
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java12
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java149
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java104
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java39
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java103
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java624
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java195
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java94
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java57
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java122
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java)14
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java12
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java235
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java75
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java137
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java206
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java43
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java86
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java127
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java75
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java76
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java)32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java71
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java92
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java40
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java15
-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/Base64MD5PasswordFileAuthenticationManagerFactory.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java92
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java40
-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.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java39
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java249
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java254
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java69
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java88
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java1
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java287
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java147
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java)23
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java)32
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java)13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java89
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java33
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java14
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java)27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java)15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/State.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java350
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java41
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java40
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java37
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java55
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java76
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java153
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java15
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java9
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java20
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java77
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java361
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java22
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java173
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java213
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java105
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java174
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties23
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java141
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java29
-rw-r--r--java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory19
-rw-r--r--java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory24
-rw-r--r--java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType22
-rw-r--r--java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory19
-rw-r--r--java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory20
-rw-r--r--java/broker/src/main/resources/initial-store.json58
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java103
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java181
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/MainTest.java170
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java203
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java71
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java144
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java51
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java171
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/QueueConfigurationTest.java157
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java1766
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java131
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java155
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/AbstractConfigurationTest.java (renamed from java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginTest.java)14
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java405
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java62
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java97
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java111
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java117
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java108
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java124
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java392
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java216
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java341
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java83
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java296
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java54
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java226
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersBindingTest.java28
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java16
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java53
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java5
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java150
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java26
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java86
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java66
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java35
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java7
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java94
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java40
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java12
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java13
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacadeTest.java (renamed from java/broker/src/test/java/org/apache/qpid/server/logging/log4j/LoggingFacadeTest.java)14
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java13
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java23
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java21
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java47
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java17
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java1
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java26
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java16
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java16
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java15
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java24
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java189
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/UUIDGeneratorTest.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java85
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java212
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java129
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java94
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java55
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java28
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java42
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java50
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java28
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java68
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java28
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java97
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java34
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java74
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java27
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java104
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java138
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java147
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java54
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java112
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java (renamed from java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java)15
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java (renamed from java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java)55
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java)25
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java47
-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/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java111
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java58
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java111
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java364
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java48
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java183
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java456
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java77
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java197
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java80
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalTest.java (renamed from java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java)14
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java119
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java10
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreCreatorTest.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java)29
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java51
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java13
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java17
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java79
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java56
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java48
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/AsyncAutoCommitTransactionTest.java2
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java8
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java127
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java6
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java209
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java372
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java121
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java69
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualHostImplTest.java107
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java347
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java105
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java186
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java89
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java294
-rw-r--r--java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm19
-rw-r--r--java/build.deps22
-rw-r--r--java/build.xml6
-rw-r--r--java/client/build.xml2
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/Drain.java2
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/ListReceiver.java101
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/ListSender.java86
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/Spout.java1
-rwxr-xr-xjava/client/src/main/java/client.bnd2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java9
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnection.java50
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java36
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java50
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQDestination.java101
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession.java225
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java408
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java177
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQTopic.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java19
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java23
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java22
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java100
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java44
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java30
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/HeartbeatListener.java37
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java2
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java24
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java21
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessage.java935
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessageFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java)49
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java9
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java5
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java1
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java203
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java90
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/messaging/address/Node.java85
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java152
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java9
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java125
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java64
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java10
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java7
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java18
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java17
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/ListMessage.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java)41
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java14
-rw-r--r--java/client/src/main/java/org/apache/qpid/jms/Session.java3
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/AMQConnectionUnitTest.java67
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java15
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java6
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/message/AMQPEncodedListMessageUnitTest.java153
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/messaging/address/AddressHelperTest.java146
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/security/DynamicSaslRegistrarTest.java140
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java42
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java128
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java120
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java14
-rw-r--r--java/common.xml11
-rwxr-xr-xjava/common/bin/qpid-run8
-rw-r--r--java/common/build.xml21
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpClass.java197
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java29
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpConstant.java191
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java152
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpDomain.java89
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java128
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java62
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpField.java269
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java452
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java77
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpMethod.java351
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java)22
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpModel.java132
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java96
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java76
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java29
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpParseException.java (renamed from java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java)15
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java30
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java30
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpVersion.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java)61
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java79
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java (renamed from java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java)8
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java26
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java120
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/CppGenerator.java1716
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java382
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/GenerateMethod.java27
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/Generator.java857
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/JavaGenerator.java1826
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/LanguageConverter.java (renamed from java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java)37
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/Main.java301
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java)6
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/NodeAware.java47
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/Printable.java28
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java103
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/SingleVersionField.java68
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java154
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java71
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java30
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/Utils.java159
-rw-r--r--java/common/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java26
-rw-r--r--java/common/protocol-version.xml70
-rwxr-xr-xjava/common/src/main/java/common.bnd2
-rw-r--r--java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java15
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java19
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/FieldTable.java1
-rw-r--r--java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java27
-rw-r--r--java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java5
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/Connection.java88
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java8
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java5
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/Session.java22
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java4
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java4
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java5
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/Ticker.java29
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/TransportActivity.java33
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/io/IdleTimeoutTicker.java87
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java31
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java51
-rw-r--r--java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java100
-rw-r--r--java/common/src/main/java/org/apache/qpid/url/BindingURL.java3
-rw-r--r--java/common/src/main/java/org/apache/qpid/util/FileUtils.java13
-rw-r--r--java/common/src/main/java/org/apache/qpid/util/NetMatcher.java300
-rw-r--r--java/common/src/test/java/org/apache/qpid/framing/FieldTableTest.java (renamed from java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java)106
-rw-r--r--java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java10
-rw-r--r--java/common/src/test/java/org/apache/qpid/test/utils/TestFileUtils.java90
-rw-r--r--java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java7
-rw-r--r--java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java12
-rw-r--r--java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java5
-rw-r--r--java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java257
-rw-r--r--java/ivy.nexus.xml42
-rw-r--r--java/ivy.retrieve.xml3
-rw-r--r--java/ivysettings.retrieve.xml2
-rw-r--r--java/jca/README-JBOSS-EAP6.txt183
-rw-r--r--java/jca/README-JBOSS.txt26
-rw-r--r--java/jca/build.xml25
-rw-r--r--java/jca/rar/src/main/resources/META-INF/jboss-ra.xml (renamed from java/jca/src/main/resources/META-INF/jboss-ra.xml)0
-rwxr-xr-xjava/jca/rar/src/main/resources/META-INF/ra.xml (renamed from java/jca/src/main/resources/META-INF/ra.xml)0
-rw-r--r--java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java73
-rw-r--r--java/management/common/src/main/java/management-common.bnd2
-rw-r--r--java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java41
-rw-r--r--java/management/example/src/main/java/org/apache/qpid/example/jmxexample/AddQueue.java41
-rw-r--r--java/module.xml208
-rw-r--r--java/perftests/build.xml2
-rw-r--r--java/perftests/etc/chartdefs/1001-MessageSize-Transient-ByteSec.chartdef (renamed from java/perftests/etc/chartdefs/1001-MessageSize-Transient.chartdef)7
-rw-r--r--java/perftests/etc/chartdefs/1002-MessageSize-Persistent-ByteSec.chartdef (renamed from java/perftests/etc/chartdefs/1002-MessageSize-Persistent.chartdef)7
-rw-r--r--java/perftests/etc/chartdefs/1003-MessageSize-Transient-MsgSec.chartdef37
-rw-r--r--java/perftests/etc/chartdefs/1004-MessageSize-Persistent-MsgSec.chartdef37
-rw-r--r--java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers-AutoAck.chartdef (renamed from java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers.chartdef)19
-rw-r--r--java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers-AutoAck.chartdef (renamed from java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers.chartdef)19
-rw-r--r--java/perftests/etc/chartdefs/1015-VaryingNumberOfProducers-SessionTrans.chartdef47
-rw-r--r--java/perftests/etc/chartdefs/1016-VaryingNumberOfConsumers-SessionTrans.chartdef47
-rw-r--r--java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef13
-rw-r--r--java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef10
-rw-r--r--java/perftests/etc/chartdefs/1030-BatchSize-Equal.chartdef37
-rw-r--r--java/perftests/etc/chartdefs/1031-BatchSize-Unequal.chartdef53
-rw-r--r--java/perftests/etc/chartdefs/1040-QueueTypes.chartdef10
-rw-r--r--java/perftests/etc/chartdefs/1050-VaryingNumberOfProducerSessionsSingleConnection.chartdef49
-rw-r--r--java/perftests/etc/chartdefs/1300-QueueConsumersWithNonOverlappingSelectors-Transient.chartdef37
-rw-r--r--java/perftests/etc/chartdefs/1301-QueueConsumersWithNonOverlappingSelectors-Persistent.chartdef43
-rw-r--r--java/perftests/etc/chartdefs/1302-QueueConsumersWithOverlappingSelectors-Transient.chartdef36
-rw-r--r--java/perftests/etc/chartdefs/1303-QueueConsumersWithOverlappingSelectors-Persistent.chartdef42
-rw-r--r--java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef11
-rw-r--r--java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef11
-rw-r--r--java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef13
-rw-r--r--java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef13
-rw-r--r--java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2011-Latency-QueuesWithNonOverlappingSelectors-Transient.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2012-Latency-QueuesWithOverlappingSelectors-Transient.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2021-Latency-QueuesWithNonOverlappingSelectors-Persistent.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2022-Latency-QueuesWithOverlappingSelectors-Persistent.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef7
-rw-r--r--java/perftests/etc/chartdefs/2041-Latency-QueueTypes.chartdef6
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1001-Large-Messages-Transient.chartdef29
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1002-Large-Messages-Persistent.chartdef29
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1011-MultipleProducersAndConsumers-Persistent.chartdef30
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1030-Batch-Size-Small.chartdef (renamed from java/perftests/etc/chartdefs/1030-BatchSize.chartdef)19
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1031-Batch-Size-Large.chartdef30
-rw-r--r--java/perftests/etc/chartdefs/timeseries/1040-SortedQueue.chartdef30
-rw-r--r--java/perftests/etc/perftests-jndi.properties4
-rwxr-xr-xjava/perftests/etc/run-perftests.sh37
-rw-r--r--java/perftests/etc/testdefs/BatchSize.js102
-rw-r--r--java/perftests/etc/testdefs/BatchSize.json84
-rw-r--r--java/perftests/etc/testdefs/BatchSizeConsumerVaries.js102
-rw-r--r--java/perftests/etc/testdefs/BatchSizeProducerVaries.js102
-rw-r--r--java/perftests/etc/testdefs/QueueConsumersWithNonOverlappingSelectors.js120
-rw-r--r--java/perftests/etc/testdefs/QueueConsumersWithOverlappingSelectors.js131
-rw-r--r--java/perftests/etc/testdefs/Topic-AckModes.js9
-rw-r--r--java/perftests/etc/testdefs/Topic-NumberOfConsumers.js4
-rw-r--r--java/perftests/etc/testdefs/Topic-NumberOfTopics.js4
-rw-r--r--java/perftests/etc/testdefs/Topic-Persistence.js8
-rw-r--r--java/perftests/etc/testdefs/VaryingNumberOfParticipants.json272
-rw-r--r--java/perftests/etc/testdefs/VaryingNumberOfProducerSessionsSingleConnection.js95
-rwxr-xr-xjava/perftests/etc/visualisation-timeseries.sh33
-rwxr-xr-xjava/perftests/etc/visualisation.sh35
-rw-r--r--java/perftests/example/brokerconfig/log4j.xml2
-rw-r--r--java/perftests/example/perftests-jndi.properties3
-rwxr-xr-xjava/perftests/example/run.sh2
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java6
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/ConfigFileHelper.java11
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java84
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/ResultsFileWriter.java112
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java17
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java10
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java56
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java36
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java21
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java6
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java4
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java2
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/db/ResultsDbWriter.java467
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java64
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java4
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/jms/NoOpQueueCreator.java5
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java101
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java5
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java4
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java11
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java11
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java42
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java54
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java4
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java2
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java11
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java24
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormatter.java (renamed from java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormater.java)6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelperTest.java8
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/ResultsFileWriterTest.java85
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java15
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java25
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java34
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java8
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithNoLimitsTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithTimeLimitTest.java6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java44
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java10
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest-test-config.js22
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java9
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest-test-config.js22
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest.java7
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ParticipantConfigTest.java2
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/db/ResultsDbWriterTest.java158
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java11
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/ResultsTestFixture.java (renamed from java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormaterTest.java)64
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java5
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java30
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/SeriesStatisticsTest.java4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java45
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormatterTest.java62
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv4
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java42
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java6
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java13
-rw-r--r--java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties3
-rw-r--r--java/perftests/visualisation-jfc/build.xml4
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java2
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java67
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChart3DBuilder.java2
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java2
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilder.java72
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryDataSetBasedChartBuilder.java60
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryStrokeAndPaintApplier.java41
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java4
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactory.java66
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChart3DBuilder.java2
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java2
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesPainter.java63
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesStrokeAndPaintApplier.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java)15
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarChartBuilder.java (renamed from java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarCharBuilder.java)63
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesHolder.java70
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesLineChartBuilder.java59
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/XYDataSetBasedChartBuilder.java70
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java12
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java6
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java27
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java7
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/DatasetHolder.java (renamed from java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilderCallback.java)15
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilder.java (renamed from java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilder.java)72
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGenerator.java81
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilder.java15
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRow.java98
-rw-r--r--java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/writer/ChartWriter.java44
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilderTest.java125
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java13
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartProductionTest.java130
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactoryTest.java (renamed from java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java)38
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesBuilderCallbackTest.java72
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java13
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java32
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilderTest.java (renamed from java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilderTest.java)35
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGeneratorTest.java85
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRowTest.java64
-rw-r--r--java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/ChartWriterTest.java35
-rwxr-xr-xjava/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/expected-chart-summary.html14
-rw-r--r--java/systests/build.xml4
-rw-r--r--java/systests/etc/config-systests-derby.xml29
-rw-r--r--java/systests/etc/config-systests-firewall-2.xml83
-rw-r--r--java/systests/etc/config-systests-firewall-3.xml85
-rw-r--r--java/systests/etc/config-systests-firewall-settings.xml30
-rw-r--r--java/systests/etc/config-systests-firewall.xml30
-rw-r--r--java/systests/etc/config-systests-settings.xml103
-rw-r--r--java/systests/etc/config-systests.json64
-rw-r--r--java/systests/etc/groups-systests29
-rw-r--r--java/systests/etc/virtualhosts-systests-bdb-settings.xml26
-rw-r--r--java/systests/etc/virtualhosts-systests-derby-mem-settings.xml25
-rw-r--r--java/systests/etc/virtualhosts-systests-derby-settings.xml25
-rw-r--r--java/systests/etc/virtualhosts-systests-settings.xml125
-rw-r--r--java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java12
-rw-r--r--java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java116
-rw-r--r--java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java51
-rw-r--r--java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java285
-rw-r--r--java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java291
-rw-r--r--java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java120
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java8
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java124
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java75
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java237
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java39
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java42
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java52
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java98
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java8
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java15
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java2
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java5
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java23
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java34
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java44
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java184
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java38
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java283
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java89
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java31
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java6
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java223
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java109
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java146
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java240
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java85
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java)4
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java)0
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java)14
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java)0
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java)35
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java)84
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java)94
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java)23
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java (renamed from java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java)8
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java)35
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java)6
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java121
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java)37
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java)57
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java)26
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java)18
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java)16
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java160
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java109
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java)6
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java)50
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java)31
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java84
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java)26
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java452
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java435
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java)45
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java)61
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java (renamed from java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java)276
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java197
-rw-r--r--java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java200
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java20
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java200
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java25
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java3
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java6
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java101
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java168
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java13
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java236
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java399
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java4
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java2
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java2
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java28
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java19
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java79
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java61
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java26
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java62
-rwxr-xr-x[-rw-r--r--]java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java502
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java295
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java219
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java30
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java54
-rw-r--r--java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java39
-rwxr-xr-xjava/test-profiles/CPPExcludes24
-rw-r--r--java/test-profiles/Excludes1
-rwxr-xr-xjava/test-profiles/Java010Excludes6
-rw-r--r--java/test-profiles/JavaTransientExcludes2
-rw-r--r--java/test-profiles/cpp.ssl.excludes2
-rw-r--r--java/test-profiles/java-bdb-spawn.0-10.testprofile6
-rw-r--r--java/test-profiles/java-bdb-spawn.0-8.testprofile6
-rw-r--r--java/test-profiles/java-bdb-spawn.0-9-1.testprofile6
-rw-r--r--java/test-profiles/java-bdb-spawn.0-9.testprofile6
-rw-r--r--java/test-profiles/java-bdb.0-10.testprofile6
-rw-r--r--java/test-profiles/java-bdb.0-8.testprofile6
-rw-r--r--java/test-profiles/java-bdb.0-9-1.testprofile6
-rw-r--r--java/test-profiles/java-bdb.0-9.testprofile6
-rw-r--r--java/test-profiles/java-dby-mem.0-10.testprofile8
-rw-r--r--java/test-profiles/java-dby-mem.0-8.testprofile8
-rw-r--r--java/test-profiles/java-dby-mem.0-9-1.testprofile8
-rw-r--r--java/test-profiles/java-dby-mem.0-9.testprofile8
-rw-r--r--java/test-profiles/java-dby-spawn.0-10.testprofile6
-rw-r--r--java/test-profiles/java-dby-spawn.0-8.testprofile6
-rw-r--r--java/test-profiles/java-dby-spawn.0-9-1.testprofile6
-rw-r--r--java/test-profiles/java-dby-spawn.0-9.testprofile6
-rw-r--r--java/test-profiles/java-dby.0-10.testprofile6
-rw-r--r--java/test-profiles/java-dby.0-8.testprofile6
-rw-r--r--java/test-profiles/java-dby.0-9-1.testprofile6
-rw-r--r--java/test-profiles/java-dby.0-9.testprofile6
-rw-r--r--java/test-profiles/java-mms-spawn.0-10.testprofile5
-rw-r--r--java/test-profiles/java-mms-spawn.0-8.testprofile5
-rw-r--r--java/test-profiles/java-mms-spawn.0-9-1.testprofile5
-rw-r--r--java/test-profiles/java-mms-spawn.0-9.testprofile5
-rw-r--r--java/test-profiles/java-mms.0-10.testprofile5
-rw-r--r--java/test-profiles/java-mms.0-8.testprofile5
-rw-r--r--java/test-profiles/java-mms.0-9-1.testprofile5
-rw-r--r--java/test-profiles/java-mms.0-9.testprofile5
-rw-r--r--java/test-profiles/testprofile.defaults13
1043 files changed, 48382 insertions, 36887 deletions
diff --git a/java/.gitignore b/java/.gitignore
index 417b51f12d..d995501f21 100644
--- a/java/.gitignore
+++ b/java/.gitignore
@@ -18,3 +18,4 @@
#
*.swp
eclipse-projects/*
+derby.log
diff --git a/java/amqp-1-0-client-jms/build.xml b/java/amqp-1-0-client-jms/build.xml
index cfc6e0babe..d501be1d8d 100644
--- a/java/amqp-1-0-client-jms/build.xml
+++ b/java/amqp-1-0-client-jms/build.xml
@@ -24,6 +24,9 @@
<property name="module.depends" value="amqp-1-0-common amqp-1-0-client"/>
<property name="module.genpom.args" value="-Sgeronimo-jms_1.1_spec=provided"/>
+ <property name="example.src.dir" value="${project.root}/amqp-1-0-client-jms/example/src/main/java" />
+ <property name="example.jar.file" value="${build.lib}/qpid-amqp-1-0-client-jms-example-${project.version}.jar" />
+
<target name="release-bin-copy-readme">
<copy todir="${module.release}" overwrite="true" failonerror="true">
diff --git a/java/systests/etc/config-systests-bdb-settings.xml b/java/amqp-1-0-client-jms/example/build.xml
index 4fa69d0abc..cb9ab0994c 100644
--- a/java/systests/etc/config-systests-bdb-settings.xml
+++ b/java/amqp-1-0-client-jms/example/build.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -8,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
@@ -19,8 +18,11 @@
- under the License.
-
-->
-<broker>
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-bdb.xml</virtualhosts>
-</broker>
+<project name="AMQ 1.0 JMS Client Example" default="build">
+
+ <property name="module.depends" value="amqp-1-0-client-jms amqp-1-0-client amqp-1-0-common"/>
+ <property name="module.test.depends" value=""/>
+ <import file="../../module.xml"/>
+</project>
diff --git a/java/amqp-1-0-client-jms/resources/LICENSE b/java/amqp-1-0-client-jms/resources/LICENSE
new file mode 100644
index 0000000000..de4b130f35
--- /dev/null
+++ b/java/amqp-1-0-client-jms/resources/LICENSE
@@ -0,0 +1,204 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
diff --git a/java/amqp-1-0-client-jms/resources/NOTICE b/java/amqp-1-0-client-jms/resources/NOTICE
new file mode 100644
index 0000000000..8d1c3f3122
--- /dev/null
+++ b/java/amqp-1-0-client-jms/resources/NOTICE
@@ -0,0 +1,5 @@
+Apache Qpid
+Copyright 2006-2012 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
diff --git a/java/amqp-1-0-client-jms/resources/README.txt b/java/amqp-1-0-client-jms/resources/README.txt
new file mode 100644
index 0000000000..35d25050fe
--- /dev/null
+++ b/java/amqp-1-0-client-jms/resources/README.txt
@@ -0,0 +1,7 @@
+
+Documentation
+--------------
+All of our user documentation can be accessed at:
+
+http://qpid.apache.org/documentation.html
+
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
index d9e6dfe36d..4856a7c491 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java
@@ -20,8 +20,12 @@
*/
package org.apache.qpid.amqp_1_0.jms.impl;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.net.URLStreamHandler;
import javax.jms.JMSException;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
@@ -39,6 +43,8 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
private String _remoteHost;
private boolean _ssl;
+ private String _queuePrefix;
+ private String _topicPrefix;
public ConnectionFactoryImpl(final String host,
final int port,
@@ -86,36 +92,70 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
public ConnectionImpl createConnection() throws JMSException
{
- return new ConnectionImpl(_host, _port, _username, _password, _clientId, _remoteHost, _ssl);
+ return createConnection(_username, _password);
}
public ConnectionImpl createConnection(final String username, final String password) throws JMSException
{
- return new ConnectionImpl(_host, _port, username, password, _clientId, _remoteHost, _ssl);
+ ConnectionImpl connection = new ConnectionImpl(_host, _port, username, password, _clientId, _remoteHost, _ssl);
+ connection.setQueuePrefix(_queuePrefix);
+ connection.setTopicPrefix(_topicPrefix);
+ return connection;
}
public static ConnectionFactoryImpl createFromURL(final String urlString) throws MalformedURLException
{
- URL url = new URL(urlString);
+ URL url = new URL(null, urlString, new URLStreamHandler()
+ {
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ });
+ String protocol = url.getProtocol();
+ if(protocol == null || "".equals(protocol))
+ {
+ protocol = "amqp";
+ }
+ else if(!protocol.equals("amqp") && !protocol.equals("amqps"))
+ {
+ throw new MalformedURLException("Protocol '"+protocol+"' unknown. Must be one of 'amqp' or 'amqps'.");
+ }
String host = url.getHost();
int port = url.getPort();
+
+ boolean ssl = false;
+
if(port == -1)
{
- port = 5672;
+ if("amqps".equals(protocol))
+ {
+ port = 5671;
+ ssl = true;
+ }
+ else
+ {
+ port = 5672;
+ }
}
+ else if("amqps".equals(protocol))
+ {
+ ssl = true;
+ }
+
String userInfo = url.getUserInfo();
String username = null;
String password = null;
String clientId = null;
String remoteHost = null;
- boolean ssl = false;
if(userInfo != null)
{
String[] components = userInfo.split(":",2);
- username = components[0];
+ username = URLDecoder.decode(components[0]);
if(components.length == 2)
{
- password = components[1];
+ password = URLDecoder.decode(components[1]);
}
}
String query = url.getQuery();
@@ -139,6 +179,11 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
}
}
+ if(remoteHost == null)
+ {
+ remoteHost = host;
+ }
+
return new ConnectionFactoryImpl(host, port, username, password, clientId, remoteHost, ssl);
}
@@ -170,4 +215,24 @@ public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnection
connection.setTopicConnection(true);
return connection;
}
+
+ public String getTopicPrefix()
+ {
+ return _topicPrefix;
+ }
+
+ public void setTopicPrefix(String topicPrefix)
+ {
+ _topicPrefix = topicPrefix;
+ }
+
+ public String getQueuePrefix()
+ {
+ return _queuePrefix;
+ }
+
+ public void setQueuePrefix(String queuePrefix)
+ {
+ _queuePrefix = queuePrefix;
+ }
}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
index 587b12b51a..be1c2d6514 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java
@@ -25,9 +25,8 @@ import org.apache.qpid.amqp_1_0.transport.Container;
import javax.jms.*;
import javax.jms.IllegalStateException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import javax.jms.Queue;
+import java.util.*;
public class ConnectionImpl implements Connection, QueueConnection, TopicConnection
{
@@ -43,16 +42,26 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
private boolean _isQueueConnection;
private boolean _isTopicConnection;
private final Collection<CloseTask> _closeTasks = new ArrayList<CloseTask>();
+ private final String _host;
+ private final int _port;
+ private final String _username;
+ private final String _password;
+ private final String _remoteHost;
+ private final boolean _ssl;
+ private String _clientId;
+ private String _queuePrefix;
+ private String _topicPrefix;
private static enum State
{
+ UNCONNECTED,
STOPPED,
STARTED,
CLOSED
}
- private volatile State _state = State.STOPPED;
+ private volatile State _state = State.UNCONNECTED;
public ConnectionImpl(String host, int port, String username, String password, String clientId) throws JMSException
{
@@ -66,20 +75,52 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
public ConnectionImpl(String host, int port, String username, String password, String clientId, String remoteHost, boolean ssl) throws JMSException
{
- Container container = clientId == null ? new Container() : new Container(clientId);
- // TODO - authentication, containerId, clientId, ssl?, etc
- try
+ _host = host;
+ _port = port;
+ _username = username;
+ _password = password;
+ _clientId = clientId;
+ _remoteHost = remoteHost;
+ _ssl = ssl;
+ }
+
+ private void connect() throws JMSException
+ {
+ synchronized(_lock)
{
- _conn = new org.apache.qpid.amqp_1_0.client.Connection(host, port, username, password, container, remoteHost, ssl);
- // TODO - retrieve negotiated AMQP version
- _connectionMetaData = new ConnectionMetaDataImpl(1,0,0);
+ // already connected?
+ if( _state == State.UNCONNECTED )
+ {
+ _state = State.STOPPED;
+
+ Container container = _clientId == null ? new Container() : new Container(_clientId);
+ // TODO - authentication, containerId, clientId, ssl?, etc
+ try
+ {
+ _conn = new org.apache.qpid.amqp_1_0.client.Connection(_host,
+ _port, _username, _password, container, _remoteHost, _ssl);
+ // TODO - retrieve negotiated AMQP version
+ _connectionMetaData = new ConnectionMetaDataImpl(1,0,0);
+ }
+ catch (org.apache.qpid.amqp_1_0.client.Connection.ConnectionException e)
+ {
+ JMSException jmsEx = new JMSException(e.getMessage());
+ jmsEx.setLinkedException(e);
+ jmsEx.initCause(e);
+ throw jmsEx;
+ }
+ }
}
- catch (org.apache.qpid.amqp_1_0.client.Connection.ConnectionException e)
+ }
+
+ private void checkNotConnected(String msg) throws IllegalStateException
+ {
+ synchronized(_lock)
{
- JMSException jmsEx = new JMSException(e.getMessage());
- jmsEx.setLinkedException(e);
- jmsEx.initCause(e);
- throw jmsEx;
+ if( _state != State.UNCONNECTED )
+ {
+ throw new IllegalStateException(msg);
+ }
}
}
@@ -111,7 +152,7 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
{
throw new IllegalStateException("Cannot create a session on a closed connection");
}
-
+ connect();
SessionImpl session = new SessionImpl(this, acknowledgeMode);
session.setQueueSession(_isQueueConnection);
session.setTopicSession(_isTopicConnection);
@@ -125,14 +166,19 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
public String getClientID() throws JMSException
{
checkClosed();
- return _conn.getEndpoint().getContainer().getId();
+ return _clientId;
}
- public void setClientID(final String s) throws JMSException
+ public void setClientID(final String value) throws JMSException
{
- throw new IllegalStateException("Cannot set client-id to \""
- + s
- + "\"; client-id must be set on connection creation");
+ checkNotConnected("Cannot set client-id to \""
+ + value
+ + "\"; client-id must be set before the connection is used");
+ if( _clientId !=null )
+ {
+ throw new IllegalStateException("client-id has already been set");
+ }
+ _clientId = value;
}
public ConnectionMetaData getMetaData() throws JMSException
@@ -158,6 +204,7 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
synchronized(_lock)
{
checkClosed();
+ connect();
if(_state == State.STOPPED)
{
// TODO
@@ -187,6 +234,7 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
{
session.stop();
}
+ case UNCONNECTED:
_state = State.STOPPED;
break;
case CLOSED:
@@ -235,7 +283,9 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
{
task.onClose();
}
- _conn.close();
+ if(_conn != null && _state != State.UNCONNECTED ) {
+ _conn.close();
+ }
_state = State.CLOSED;
}
@@ -282,6 +332,10 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
final int i) throws JMSException
{
checkClosed();
+ if (_isQueueConnection)
+ {
+ throw new IllegalStateException("QueueConnection cannot be used to create Pub/Sub based resources.");
+ }
return null; //TODO
}
@@ -326,4 +380,78 @@ public class ConnectionImpl implements Connection, QueueConnection, TopicConnect
{
_isTopicConnection = topicConnection;
}
+
+ public String getTopicPrefix()
+ {
+ return _topicPrefix;
+ }
+
+ public void setTopicPrefix(String topicPrefix)
+ {
+ _topicPrefix = topicPrefix;
+ }
+
+ public String getQueuePrefix()
+ {
+ return _queuePrefix;
+ }
+
+ public void setQueuePrefix(String queueprefix)
+ {
+ _queuePrefix = queueprefix;
+ }
+
+ DecodedDestination toDecodedDestination(DestinationImpl dest)
+ {
+ String address = dest.getAddress();
+ Set<String> kind = null;
+ Class clazz = dest.getClass();
+ if( clazz==QueueImpl.class )
+ {
+ kind = MessageImpl.JMS_QUEUE_ATTRIBUTES;
+ if( _queuePrefix!=null )
+ {
+ // Avoid double prefixing..
+ if( !address.startsWith(_queuePrefix) )
+ {
+ address = _queuePrefix+address;
+ }
+ }
+ }
+ else if( clazz==TopicImpl.class )
+ {
+ kind = MessageImpl.JMS_TOPIC_ATTRIBUTES;
+ if( _topicPrefix!=null )
+ {
+ // Avoid double prefixing..
+ if( !address.startsWith(_topicPrefix) )
+ {
+ address = _topicPrefix+address;
+ }
+ }
+ }
+ else if( clazz==TemporaryQueueImpl.class )
+ {
+ kind = MessageImpl.JMS_TEMP_QUEUE_ATTRIBUTES;
+ }
+ else if( clazz==TemporaryTopicImpl.class )
+ {
+ kind = MessageImpl.JMS_TEMP_TOPIC_ATTRIBUTES;
+ }
+ return new DecodedDestination(address, kind);
+ }
+
+ DecodedDestination toDecodedDestination(String address, Set<String> kind)
+ {
+ if( (kind == null || kind.equals(MessageImpl.JMS_QUEUE_ATTRIBUTES)) && _queuePrefix!=null && address.startsWith(_queuePrefix))
+ {
+ return new DecodedDestination(address.substring(_queuePrefix.length()), MessageImpl.JMS_QUEUE_ATTRIBUTES);
+ }
+ if( (kind == null || kind.equals(MessageImpl.JMS_TOPIC_ATTRIBUTES)) && _topicPrefix!=null && address.startsWith(_topicPrefix))
+ {
+ return new DecodedDestination(address.substring(_topicPrefix.length()), MessageImpl.JMS_TOPIC_ATTRIBUTES);
+ }
+ return new DecodedDestination(address, kind);
+ }
+
}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DecodedDestination.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DecodedDestination.java
new file mode 100644
index 0000000000..74e98c2163
--- /dev/null
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DecodedDestination.java
@@ -0,0 +1,47 @@
+/*
+ * 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.amqp_1_0.jms.impl;
+
+import java.util.Set;
+
+/**
+* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
+*/
+class DecodedDestination
+{
+ private final String _address;
+ private final Set<String> _attributes;
+
+ DecodedDestination(String address, Set<String> kind)
+ {
+ _address = address;
+ _attributes = kind;
+ }
+
+ public String getAddress()
+ {
+ return _address;
+ }
+
+ public Set<String> getAttributes()
+ {
+ return _attributes;
+ }
+}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
index e0402cd0a7..3c15c74d6f 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java
@@ -127,7 +127,7 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
{
try
{
- return _session.getClientSession(). createReceiver(_destination.getAddress(), AcknowledgeMode.ALO,
+ return _session.getClientSession(). createReceiver(_session.toAddress(_destination), AcknowledgeMode.ALO,
_linkName, _durable, getFilters(), null);
}
catch (AmqpErrorException e)
@@ -316,9 +316,9 @@ public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, Topi
_lastUnackedMessage = deliveryTag;
}
- void preReceiveAction(final org.apache.qpid.amqp_1_0.client.Message msg) throws IllegalStateException
+ void preReceiveAction(final org.apache.qpid.amqp_1_0.client.Message msg)
{
- final int acknowledgeMode = _session.getAcknowledgeMode();
+ int acknowledgeMode = _session.getAckModeEnum().ordinal();
if(acknowledgeMode == Session.AUTO_ACKNOWLEDGE
|| acknowledgeMode == Session.DUPS_OK_ACKNOWLEDGE
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java
index f1056b94fd..fba50c5477 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java
@@ -50,14 +50,24 @@ public abstract class MessageImpl implements Message
static final Set<Class> _supportedClasses =
new HashSet<Class>(Arrays.asList(Boolean.class, Byte.class, Short.class, Integer.class, Long.class,
Float.class, Double.class, Character.class, String.class, byte[].class));
- private static final Symbol JMS_TYPE = Symbol.valueOf("x-opt-jms-type");
+ static final Symbol JMS_TYPE = Symbol.valueOf("x-opt-jms-type");
+ static final Symbol TO_TYPE = Symbol.valueOf("x-opt-to-type");
+ static final Symbol REPLY_TO_TYPE = Symbol.valueOf("x-opt-reply-type");
+
+ static final String QUEUE_ATTRIBUTE = "queue";
+ static final String TOPIC_ATTRIBUTE = "topic";
+ static final String TEMPORARY_ATTRIBUTE = "temporary";
+
+ static final Set<String> JMS_QUEUE_ATTRIBUTES = set(QUEUE_ATTRIBUTE);
+ static final Set<String> JMS_TOPIC_ATTRIBUTES = set(TOPIC_ATTRIBUTE);
+ static final Set<String> JMS_TEMP_QUEUE_ATTRIBUTES = set(QUEUE_ATTRIBUTE, TEMPORARY_ATTRIBUTE);
+ static final Set<String> JMS_TEMP_TOPIC_ATTRIBUTES = set(TOPIC_ATTRIBUTE, TEMPORARY_ATTRIBUTE);
private Header _header;
private Properties _properties;
private ApplicationProperties _applicationProperties;
private Footer _footer;
- public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
- private SessionImpl _sessionImpl;
+ private final SessionImpl _sessionImpl;
private boolean _readOnly;
private MessageAnnotations _messageAnnotations;
@@ -171,45 +181,53 @@ public abstract class MessageImpl implements Message
public DestinationImpl getJMSReplyTo() throws JMSException
{
- return DestinationImpl.valueOf(getReplyTo());
+ return toDestination(getReplyTo(), splitCommaSeparateSet((String) getMessageAnnotation(REPLY_TO_TYPE)));
}
public void setJMSReplyTo(Destination destination) throws NonAMQPDestinationException
{
- if(destination == null)
+ if( destination==null )
{
setReplyTo(null);
- }
- else if (destination instanceof org.apache.qpid.amqp_1_0.jms.Destination)
- {
- setReplyTo(((org.apache.qpid.amqp_1_0.jms.Destination)destination).getAddress());
+ messageAnnotationMap().remove(REPLY_TO_TYPE);
}
else
{
- throw new NonAMQPDestinationException(destination);
+ DecodedDestination dd = toDecodedDestination(destination);
+ setReplyTo(dd.getAddress());
+ messageAnnotationMap().put(REPLY_TO_TYPE, join(",", dd.getAttributes()));
}
}
public DestinationImpl getJMSDestination() throws JMSException
{
- return _isFromQueue ? QueueImpl.valueOf(getTo())
- : _isFromTopic ? TopicImpl.valueOf(getTo())
- : DestinationImpl.valueOf(getTo());
+ Set<String> type = splitCommaSeparateSet((String) getMessageAnnotation(TO_TYPE));
+ if( type==null )
+ {
+ if( _isFromQueue )
+ {
+ type = JMS_QUEUE_ATTRIBUTES;
+ }
+ else if( _isFromTopic )
+ {
+ type = JMS_TOPIC_ATTRIBUTES;
+ }
+ }
+ return toDestination(getTo(), type);
}
public void setJMSDestination(Destination destination) throws NonAMQPDestinationException
{
- if(destination == null)
+ if( destination==null )
{
setTo(null);
- }
- else if (destination instanceof org.apache.qpid.amqp_1_0.jms.Destination)
- {
- setTo(((org.apache.qpid.amqp_1_0.jms.Destination)destination).getAddress());
+ messageAnnotationMap().remove(TO_TYPE);
}
else
{
- throw new NonAMQPDestinationException(destination);
+ DecodedDestination dd = toDecodedDestination(destination);
+ setTo(dd.getAddress());
+ messageAnnotationMap().put(TO_TYPE, join(",", dd.getAttributes()));
}
}
@@ -264,22 +282,13 @@ public abstract class MessageImpl implements Message
public String getJMSType() throws JMSException
{
- Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue();
- final Object attrValue = messageAttrs == null ? null : messageAttrs.get(JMS_TYPE);
-
+ final Object attrValue = getMessageAnnotation(JMS_TYPE);
return attrValue instanceof String ? attrValue.toString() : null;
}
public void setJMSType(String s) throws JMSException
{
- Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue();
- if(messageAttrs == null)
- {
- messageAttrs = new HashMap();
- _messageAnnotations = new MessageAnnotations(messageAttrs);
- }
-
- messageAttrs.put(JMS_TYPE, s);
+ messageAnnotationMap().put(JMS_TYPE, s);
}
public long getJMSExpiration() throws JMSException
@@ -1206,4 +1215,118 @@ public abstract class MessageImpl implements Message
}
abstract Collection<Section> getSections();
+
+ DecodedDestination toDecodedDestination(Destination destination) throws NonAMQPDestinationException
+ {
+ if(destination == null)
+ {
+ return null;
+ }
+ if (destination instanceof DestinationImpl)
+ {
+ return _sessionImpl.getConnection().toDecodedDestination((DestinationImpl) destination);
+ }
+ throw new NonAMQPDestinationException(destination);
+ }
+
+ DestinationImpl toDestination(String address, Set<String> kind)
+ {
+ if( address == null )
+ {
+ return null;
+ }
+
+ // If destination prefixes are in play, we have to strip the the prefix, and we might
+ // be able to infer the kind, if we don't know it yet.
+ DecodedDestination decoded = _sessionImpl.getConnection().toDecodedDestination(address, kind);
+ address = decoded.getAddress();
+ kind = decoded.getAttributes();
+
+ if( kind == null )
+ {
+ return DestinationImpl.valueOf(address);
+ }
+ if( kind.contains(QUEUE_ATTRIBUTE) )
+ {
+ if( kind.contains(TEMPORARY_ATTRIBUTE) )
+ {
+ return new TemporaryQueueImpl(address, null, _sessionImpl);
+ }
+ else
+ {
+ return QueueImpl.valueOf(address);
+ }
+ }
+ else if ( kind.contains(TOPIC_ATTRIBUTE) )
+ {
+ if( kind.contains(TEMPORARY_ATTRIBUTE) )
+ {
+ return new TemporaryTopicImpl(address, null, _sessionImpl);
+ }
+ else
+ {
+ return TopicImpl.valueOf(address);
+ }
+ }
+
+ return DestinationImpl.valueOf(address);
+ }
+
+ private Object getMessageAnnotation(Symbol key)
+ {
+ Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue();
+ return messageAttrs == null ? null : messageAttrs.get(key);
+ }
+
+ private Map messageAnnotationMap()
+ {
+ Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue();
+ if(messageAttrs == null)
+ {
+ messageAttrs = new HashMap();
+ _messageAnnotations = new MessageAnnotations(messageAttrs);
+ }
+ return messageAttrs;
+ }
+
+ Set<String> splitCommaSeparateSet(String value)
+ {
+ if( value == null )
+ {
+ return null;
+ }
+ HashSet<String> rc = new HashSet<String>();
+ for( String x: value.split("\\s*,\\s*") )
+ {
+ rc.add(x);
+ }
+ return rc;
+ }
+
+ private static Set<String> set(String ...args)
+ {
+ HashSet<String> s = new HashSet<String>();
+ for (String arg : args)
+ {
+ s.add(arg);
+ }
+ return Collections.unmodifiableSet(s);
+ }
+
+ static final String join(String sep, Iterable items)
+ {
+ StringBuilder result = new StringBuilder();
+
+ for (Object o : items)
+ {
+ if (result.length() > 0)
+ {
+ result.append(sep);
+ }
+ result.append(o.toString());
+ }
+
+ return result.toString();
+ }
+
}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
index 5bb8845eb7..badc20472b 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java
@@ -20,7 +20,6 @@ package org.apache.qpid.amqp_1_0.jms.impl;
import org.apache.qpid.amqp_1_0.client.Sender;
import org.apache.qpid.amqp_1_0.jms.MessageProducer;
-import org.apache.qpid.amqp_1_0.jms.Queue;
import org.apache.qpid.amqp_1_0.jms.QueueSender;
import org.apache.qpid.amqp_1_0.jms.TemporaryDestination;
import org.apache.qpid.amqp_1_0.jms.TopicPublisher;
@@ -61,7 +60,7 @@ public class MessageProducerImpl implements MessageProducer, QueueSender, TopicP
{
try
{
- _sender = _session.getClientSession().createSender(_destination.getAddress());
+ _sender = _session.getClientSession().createSender(_session.toAddress(_destination));
}
catch (Sender.SenderCreationException e)
{
@@ -297,7 +296,7 @@ public class MessageProducerImpl implements MessageProducer, QueueSender, TopicP
try
{
_destination = (DestinationImpl) destination;
- _sender = _session.getClientSession().createSender(_destination.getAddress());
+ _sender = _session.getClientSession().createSender(_session.toAddress(_destination));
send(message, deliveryMode, priority, ttl);
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java
index 2a52b0557a..95c1497d07 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java
@@ -40,7 +40,25 @@ public class ObjectMessageImpl extends MessageImpl implements ObjectMessage
{
static final Symbol CONTENT_TYPE = Symbol.valueOf("application/x-java-serialized-object");
- private Data _objectData;
+ static final Data NULL_OBJECT_DATA;
+ static
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try
+ {
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(null);
+ oos.flush();
+ oos.close();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ NULL_OBJECT_DATA = new Data(new Binary(baos.toByteArray()));
+ }
+
+ private Data _objectData = NULL_OBJECT_DATA;
protected ObjectMessageImpl(Header header,
MessageAnnotations messageAnnotations,
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java
index 527e82eaed..8fab315b10 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java
@@ -18,9 +18,7 @@
*/
package org.apache.qpid.amqp_1_0.jms.impl;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Map;
+import java.util.*;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
import org.apache.qpid.amqp_1_0.client.AcknowledgeMode;
@@ -29,6 +27,7 @@ import org.apache.qpid.amqp_1_0.client.Receiver;
import org.apache.qpid.amqp_1_0.jms.QueueBrowser;
import org.apache.qpid.amqp_1_0.type.AmqpErrorException;
import org.apache.qpid.amqp_1_0.type.Symbol;
+import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
import org.apache.qpid.amqp_1_0.type.messaging.Filter;
import org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter;
import org.apache.qpid.amqp_1_0.type.messaging.StdDistMode;
@@ -39,49 +38,27 @@ public class QueueBrowserImpl implements QueueBrowser
private static final String JMS_SELECTOR = "jms-selector";
private QueueImpl _queue;
private String _selector;
- private Receiver _receiver;
- private Message _nextElement;
- private MessageEnumeration _enumeration;
+ private final SessionImpl _session;
+ private Map<Symbol, Filter> _filters;
+ private HashSet<MessageEnumeration> _enumerations = new HashSet<MessageEnumeration>();
+ private boolean _closed;
QueueBrowserImpl(final QueueImpl queue, final String selector, SessionImpl session) throws JMSException
{
_queue = queue;
_selector = selector;
+ _session = session;
- Map<Symbol, Filter> filters;
if(selector == null || selector.trim().equals(""))
{
- filters = null;
+ _filters = null;
}
else
{
- filters = Collections.singletonMap(Symbol.valueOf(JMS_SELECTOR),(Filter) new JMSSelectorFilter(_selector));
- }
-
-
- try
- {
- _receiver = session.getClientSession().createReceiver(queue.getAddress(),
- StdDistMode.COPY,
- AcknowledgeMode.AMO,null,
- false,
- filters, null);
- _nextElement = _receiver.receive(0L);
- _enumeration = new MessageEnumeration();
- }
- catch(AmqpErrorException e)
- {
- org.apache.qpid.amqp_1_0.type.transport.Error error = e.getError();
- if(AmqpError.INVALID_FIELD.equals(error.getCondition()))
- {
- throw new InvalidSelectorException(e.getMessage());
- }
- else
- {
- throw new JMSException(e.getMessage(), error.getCondition().getValue().toString());
- }
-
+ _filters = Collections.singletonMap(Symbol.valueOf(JMS_SELECTOR),(Filter) new JMSSelectorFilter(_selector));
+ // We do this just to have the server validate the filter..
+ new MessageEnumeration().close();
}
}
@@ -97,42 +74,124 @@ public class QueueBrowserImpl implements QueueBrowser
public Enumeration getEnumeration() throws JMSException
{
- if(_enumeration == null)
+ if(_closed)
{
throw new IllegalStateException("Browser has been closed");
}
- return _enumeration;
+ return new MessageEnumeration();
}
public void close() throws JMSException
{
- _receiver.close();
- _enumeration = null;
+ _closed = true;
+ for(MessageEnumeration me : new ArrayList<MessageEnumeration>(_enumerations))
+ {
+ me.close();
+ }
}
- private final class MessageEnumeration implements Enumeration<Message>
+ private final class MessageEnumeration implements Enumeration<MessageImpl>
{
+ private Receiver _receiver;
+ private MessageImpl _nextElement;
+ private boolean _needNext = true;
+
+ MessageEnumeration() throws JMSException
+ {
+ try
+ {
+ _receiver = _session.getClientSession().createReceiver(_session.toAddress(_queue),
+ StdDistMode.COPY,
+ AcknowledgeMode.AMO, null,
+ false,
+ _filters, null);
+ _receiver.setCredit(UnsignedInteger.valueOf(100), true);
+ }
+ catch(AmqpErrorException e)
+ {
+ org.apache.qpid.amqp_1_0.type.transport.Error error = e.getError();
+ if(AmqpError.INVALID_FIELD.equals(error.getCondition()))
+ {
+ throw new InvalidSelectorException(e.getMessage());
+ }
+ else
+ {
+ throw new JMSException(e.getMessage(), error.getCondition().getValue().toString());
+ }
+
+ }
+ _enumerations.add(this);
+
+ }
+
+ public void close()
+ {
+ _enumerations.remove(this);
+ _receiver.close();
+ _receiver = null;
+ }
@Override
public boolean hasMoreElements()
{
+ if( _receiver == null )
+ {
+ return false;
+ }
+ if( _needNext )
+ {
+ _needNext = false;
+ _nextElement = createJMSMessage(_receiver.receive(0L));
+ if( _nextElement == null )
+ {
+ // Drain to verify there really are no more messages.
+ _receiver.drain();
+ _receiver.drainWait();
+ _nextElement = createJMSMessage(_receiver.receive(0L));
+ if( _nextElement == null )
+ {
+ close();
+ }
+ else
+ {
+ // there are still more messages, open up the credit window again..
+ _receiver.clearDrain();
+ }
+ }
+ }
return _nextElement != null;
}
@Override
- public Message nextElement()
+ public MessageImpl nextElement()
{
-
- Message message = _nextElement;
- if(message == null)
+ if( hasMoreElements() )
{
- message = _receiver.receive(0l);
+ MessageImpl message = _nextElement;
+ _nextElement = null;
+ _needNext = true;
+ return message;
}
- if(message != null)
+ else
{
- _nextElement = _receiver.receive(0l);
+ throw new NoSuchElementException();
}
+ }
+ }
+
+ MessageImpl createJMSMessage(final Message msg)
+ {
+ if(msg != null)
+ {
+ final MessageImpl message = _session.getMessageFactory().createMessage(_queue, msg);
+ message.setFromQueue(true);
+ message.setFromTopic(false);
return message;
}
+ else
+ {
+ return null;
+ }
}
+
}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java
index d46ed7183f..67b597f5cf 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java
@@ -41,7 +41,7 @@ public class QueueReceiverImpl extends MessageConsumerImpl implements QueueRecei
{
try
{
- return getSession().getClientSession().createMovingReceiver(getDestination().getAddress());
+ return getSession().getClientSession().createMovingReceiver(getSession().toAddress(getDestination()));
}
catch (AmqpErrorException e)
{
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
index e321245a0e..58b7d4f625 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java
@@ -766,7 +766,7 @@ public class SessionImpl implements Session, QueueSession, TopicSession
{
while(!_closed)
{
- while(!_started || (_recoveredMessage == null && _messageConsumerList.isEmpty()))
+ while(!_closed && (!_started || (_recoveredMessage == null && _messageConsumerList.isEmpty())))
{
try
{
@@ -777,7 +777,7 @@ public class SessionImpl implements Session, QueueSession, TopicSession
return;
}
}
- while(_started && (_recoveredMessage != null || !_messageConsumerList.isEmpty()))
+ while(!_closed && (_started && (_recoveredMessage != null || !_messageConsumerList.isEmpty())))
{
Message msg;
@@ -804,6 +804,10 @@ public class SessionImpl implements Session, QueueSession, TopicSession
if(message != null)
{
+ if(_acknowledgeMode == AcknowledgeMode.CLIENT_ACKNOWLEDGE)
+ {
+ consumer.setLastUnackedMessage(msg.getDeliveryTag());
+ }
_currentConsumer = consumer;
_currentMessage = msg;
try
@@ -816,11 +820,11 @@ public class SessionImpl implements Session, QueueSession, TopicSession
_currentMessage = null;
}
- if((_recoveredMessage == null) && (_acknowledgeMode == AcknowledgeMode.AUTO_ACKNOWLEDGE
- || _acknowledgeMode == AcknowledgeMode.DUPS_OK_ACKNOWLEDGE))
+ if(_recoveredMessage == null)
{
- consumer.acknowledge(msg);
+ consumer.preReceiveAction(msg);
}
+
}
}
@@ -895,4 +899,10 @@ public class SessionImpl implements Session, QueueSession, TopicSession
{
_isTopicSession = topicSession;
}
+
+ String toAddress(DestinationImpl dest)
+ {
+ return _connection.toDecodedDestination(dest).getAddress();
+ }
+
}
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java
index 52d8c412ec..f267794796 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java
@@ -66,7 +66,7 @@ public class TopicSubscriberImpl extends MessageConsumerImpl implements TopicSub
{
try
{
- String address = getDestination().getAddress();
+ String address = getSession().toAddress(getDestination());
Receiver receiver = getSession().getClientSession().createReceiver(address,
StdDistMode.COPY, AcknowledgeMode.ALO,
getLinkName(), isDurable(), getFilters(),
diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java
index 31030a7d30..091ab41304 100644
--- a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java
+++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java
@@ -57,6 +57,9 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor
Map data = new ConcurrentHashMap();
String file = null;
+ String fileName = (environment.containsKey(Context.PROVIDER_URL))
+ ? (String)environment.get(Context.PROVIDER_URL) : System.getProperty(Context.PROVIDER_URL);
+
try
{
diff --git a/java/amqp-1-0-client/build.xml b/java/amqp-1-0-client/build.xml
index 031809a380..cd7654ed15 100644
--- a/java/amqp-1-0-client/build.xml
+++ b/java/amqp-1-0-client/build.xml
@@ -23,6 +23,9 @@
<property name="module.genpom" value="true"/>
<property name="module.depends" value="amqp-1-0-common"/>
+ <property name="example.src.dir" value="${project.root}/amqp-1-0-client/example/src/main/java" />
+ <property name="example.jar.file" value="${build.lib}/qpid-amqp-1-0-client-example-${project.version}.jar" />
+
<import file="../module.xml"/>
diff --git a/java/systests/etc/config-systests-derby-mem-settings.xml b/java/amqp-1-0-client/example/build.xml
index 69369d9ac9..89bba729dd 100644
--- a/java/systests/etc/config-systests-derby-mem-settings.xml
+++ b/java/amqp-1-0-client/example/build.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -8,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
@@ -19,8 +18,11 @@
- under the License.
-
-->
-<broker>
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-derby-mem.xml</virtualhosts>
-</broker>
+<project name="AMQ 1.0 Client Example" default="build">
+
+ <property name="module.depends" value="amqp-1-0-client amqp-1-0-common"/>
+ <property name="module.test.depends" value=""/>
+ <import file="../../module.xml"/>
+</project>
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java
index 3bb26744c4..3bb26744c4 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java
index b58ce6bfe5..b58ce6bfe5 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java
index 65d27b21f8..65d27b21f8 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java
index 4d98655ad2..4d98655ad2 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java
index 46e6ba537f..46e6ba537f 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java
index 0da9dc3fb7..0da9dc3fb7 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java
index 6e1d15376c..6e1d15376c 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
index 8d9de4893f..8d9de4893f 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java
index 6f6575e083..6f6575e083 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java
index 6fe2a6d510..6fe2a6d510 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java
+++ b/java/amqp-1-0-client/example/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java
diff --git a/java/amqp-1-0-client/resources/LICENSE b/java/amqp-1-0-client/resources/LICENSE
new file mode 100644
index 0000000000..de4b130f35
--- /dev/null
+++ b/java/amqp-1-0-client/resources/LICENSE
@@ -0,0 +1,204 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
diff --git a/java/amqp-1-0-client/resources/NOTICE b/java/amqp-1-0-client/resources/NOTICE
new file mode 100644
index 0000000000..8d1c3f3122
--- /dev/null
+++ b/java/amqp-1-0-client/resources/NOTICE
@@ -0,0 +1,5 @@
+Apache Qpid
+Copyright 2006-2012 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
diff --git a/java/amqp-1-0-client/resources/README.txt b/java/amqp-1-0-client/resources/README.txt
new file mode 100644
index 0000000000..35d25050fe
--- /dev/null
+++ b/java/amqp-1-0-client/resources/README.txt
@@ -0,0 +1,7 @@
+
+Documentation
+--------------
+All of our user documentation can be accessed at:
+
+http://qpid.apache.org/documentation.html
+
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
index e3d56fae09..e501662dbb 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
+++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java
@@ -20,6 +20,15 @@
*/
package org.apache.qpid.amqp_1_0.client;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLSocketFactory;
import org.apache.qpid.amqp_1_0.framing.ConnectionHandler;
import org.apache.qpid.amqp_1_0.transport.AMQPTransport;
import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint;
@@ -30,17 +39,6 @@ import org.apache.qpid.amqp_1_0.type.FrameBody;
import org.apache.qpid.amqp_1_0.type.SaslFrameBody;
import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.security.Principal;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
public class Connection
{
private static final Logger RAW_LOGGER = Logger.getLogger("RAW");
@@ -224,7 +222,6 @@ public class Connection
}
- //ConnectionHandler.OutputHandler outputHandler = new ConnectionHandler.OutputHandler(outputStream, out, _conn.getDescribedTypeRegistry());
ConnectionHandler.BytesOutputHandler outputHandler = new ConnectionHandler.BytesOutputHandler(outputStream, src, _conn);
Thread outputThread = new Thread(outputHandler);
outputThread.setDaemon(true);
@@ -236,8 +233,6 @@ public class Connection
final ConnectionHandler handler = new ConnectionHandler(_conn);
final InputStream inputStream = s.getInputStream();
- //final AMQPTransport transport = new AMQPTransport(new AMQPFrameTransport(_conn));
-
Thread inputThread = new Thread(new Runnable()
{
@@ -246,7 +241,6 @@ public class Connection
try
{
doRead(handler, inputStream);
-// doRead(transport, inputStream);
}
finally
{
@@ -268,85 +262,6 @@ public class Connection
inputThread.setDaemon(true);
inputThread.start();
-/*
- Thread outputThread = new Thread(new Runnable()
- {
-
- private int _lastWrite;
-
- public void run()
- {
- try
- {
-// doRead(handler, inputStream);
- final Object lock = new Object();
- transport.setOutputStateChangeListener(new StateChangeListener()
- {
-
- public void onStateChange(final boolean active)
- {
- synchronized (lock)
- {
- lock.notifyAll();
- }
- }
- });
-
- synchronized(lock)
- {
- while(transport.isOpenForOutput())
- {
- _lastWrite = 0;
- transport.getNextBytes(new BytesProcessor()
- {
-
- public void processBytes(final ByteBuffer buf)
- {
- _lastWrite = buf.remaining();
- try
- {
- outputStream.write(buf.array(),
- buf.arrayOffset() + buf.position(),
- buf.limit() - buf.position());
- }
- catch (IOException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- });
- if(_lastWrite == 0 && transport.isOpenForOutput())
- {
- try
- {
- lock.wait(1000);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
- }
- finally
- {
- if(_conn.closedForInput() && _conn.closedForOutput())
- {
- try
- {
- s.close();
- }
- catch (IOException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
- });
-*/
-
_conn.open();
}
@@ -394,7 +309,7 @@ public class Connection
}
catch (IOException e)
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ e.printStackTrace();
}
}
@@ -419,7 +334,7 @@ public class Connection
{
int read;
boolean done = false;
- while(!done && (read = inputStream.read(buf)) != -1)
+ while(!handler.isDone() && (read = inputStream.read(buf)) != -1)
{
ByteBuffer bbuf = ByteBuffer.wrap(buf, 0, read);
Binary b = new Binary(buf,0,read);
@@ -428,12 +343,6 @@ public class Connection
{
RAW_LOGGER.fine("RECV [" + _conn.getRemoteAddress() + "] : " + b.toString());
}
- /*System.err.println(b);
- System.err.println("XXX: " + bbuf.hasRemaining() + "; " + handler.isDone());
- if(handler.isDone())
- {
- System.err.println(handler.getClass().getName() + "IS DONE!");
- } */
while(bbuf.hasRemaining() && !handler.isDone())
{
handler.parse(bbuf);
@@ -444,7 +353,7 @@ public class Connection
}
catch (IOException e)
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ e.printStackTrace();
}
}
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java
deleted file mode 100644
index 07ae54b54f..0000000000
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java
+++ /dev/null
@@ -1,77 +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.amqp_1_0.client;
-
-import org.apache.qpid.amqp_1_0.codec.ValueHandler;
-import org.apache.qpid.amqp_1_0.type.AmqpErrorException;
-import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-public class ReadBytes
-{
-
- public static void main(String[] args) throws IOException, AmqpErrorException
- {
-
- if(args.length == 0)
- {
- readBytes(System.in);
- }
- else
- {
- for(String fileName : args)
- {
- System.out.println("=========================== " + fileName + " ===========================");
- final FileInputStream fis = new FileInputStream(fileName);
- readBytes(fis);
- fis.close();
- }
- }
-
- }
-
- private static void readBytes(final InputStream inputStream) throws IOException, AmqpErrorException
- {
- byte[] bytes = new byte[4096];
-
- ValueHandler valueHandler = new ValueHandler(AMQPDescribedTypeRegistry.newInstance());
-
- int count;
-
- while((count = inputStream.read(bytes))!=-1)
- {
- ByteBuffer buf = ByteBuffer.wrap(bytes);
- buf.limit(count);
- while(buf.hasRemaining())
- {
-
- final Object value = valueHandler.parse(buf);
- System.out.print((value == null ? "" : value.getClass().getName() + ":") +value +"\n");
-
- }
- }
-
- }
-
-
-}
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
index ad390fd498..8b792db1f1 100644
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
+++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java
@@ -241,7 +241,7 @@ public class Receiver implements DeliveryStateHandler
}
if(hasMore)
{
- xfr = receiveFromPrefetch(0L);
+ xfr = receiveFromPrefetch(-1l);
if(xfr== null)
{
// TODO - this is wrong!!!!
@@ -503,6 +503,37 @@ public class Receiver implements DeliveryStateHandler
_endpoint.drain();
}
+ /**
+ * Waits for the receiver to drain or a message to be available to be received.
+ * @return true if the receiver has been drained.
+ */
+ public boolean drainWait()
+ {
+ final Object lock = _endpoint.getLock();
+ synchronized(lock)
+ {
+ try
+ {
+ while( _prefetchQueue.peek()==null && !_endpoint.isDrained() && !_endpoint.isDetached() )
+ {
+ lock.wait();
+ }
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ return _prefetchQueue.peek()==null && _endpoint.isDrained();
+ }
+
+ /**
+ * Clears the receiver drain so that message delivery can resume.
+ */
+ public void clearDrain()
+ {
+ _endpoint.clearDrain();
+ }
+
public void setCreditWithTransaction(final UnsignedInteger credit, final Transaction txn)
{
_endpoint.setLinkCredit(credit);
@@ -558,4 +589,4 @@ public class Receiver implements DeliveryStateHandler
void messageArrived(Receiver receiver);
}
-} \ No newline at end of file
+}
diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java
deleted file mode 100644
index 6f97ecd810..0000000000
--- a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java
+++ /dev/null
@@ -1,331 +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.amqp_1_0.client;
-
-import org.apache.qpid.amqp_1_0.codec.FrameWriter;
-import org.apache.qpid.amqp_1_0.codec.ValueWriter;
-import org.apache.qpid.amqp_1_0.framing.AMQFrame;
-import org.apache.qpid.amqp_1_0.type.Binary;
-import org.apache.qpid.amqp_1_0.type.FrameBody;
-import org.apache.qpid.amqp_1_0.type.Section;
-import org.apache.qpid.amqp_1_0.type.Symbol;
-import org.apache.qpid.amqp_1_0.type.UnsignedByte;
-import org.apache.qpid.amqp_1_0.type.UnsignedInteger;
-import org.apache.qpid.amqp_1_0.type.UnsignedLong;
-import org.apache.qpid.amqp_1_0.type.UnsignedShort;
-import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry;
-import org.apache.qpid.amqp_1_0.type.messaging.Footer;
-import org.apache.qpid.amqp_1_0.type.messaging.Header;
-import org.apache.qpid.amqp_1_0.type.messaging.Properties;
-import org.apache.qpid.amqp_1_0.type.transport.Flow;
-
-import org.apache.qpid.amqp_1_0.type.transport.Transfer;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-public class SendBytes
-{
-
- public static void main(String[] args) throws
- Sender.SenderCreationException,
- Sender.SenderClosingException,
- Connection.ConnectionException,
- IOException, ParseException
- {
- Transfer xfr = new Transfer();
- Flow fs = new Flow();
- fs.setIncomingWindow(UnsignedInteger.valueOf(1024));
- fs.setDeliveryCount(UnsignedInteger.valueOf(2));
- fs.setLinkCredit(UnsignedInteger.valueOf(18));
- fs.setAvailable(UnsignedInteger.valueOf(0));
- fs.setDrain(false);
-
- xfr.setHandle(UnsignedInteger.valueOf(0));
- xfr.setDeliveryTag(new Binary("\"queue\"<-6ec024a7-d98e-4196-9348-15f6026c32ca:0".getBytes()));
- //xfr.setDeliveryTag(new Binary(new byte[] {0}));
- xfr.setDeliveryId(UnsignedInteger.valueOf(0));
- xfr.setSettled(true);
-
-
- Header h = new Header();
- Properties p = new Properties();
- p.setTo("queue");
- //p.setMessageId(new Binary(UUID.randomUUID().toString().getBytes()));
-
- Footer f = new Footer(Collections.EMPTY_MAP);
-
- Section[] sections = new Section[] { h,p,f};
- //Section[] sections = new Section[] { b };
- //Section[] sections = { h,p, b};
-/*
- Fragment[] fragments = new Fragment[5];
-
- final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance().registerTransportLayer().registerMessagingLayer();
-
- SectionEncoderImpl encoder = new SectionEncoderImpl(typeRegistry);
-
- int num = 0;
- int i = 0;
- for(Section s : sections)
- {
- Fragment frag = new Fragment();
-
- frag.setPayload(s.encode(encoder));
- frag.setFirst(true);
- frag.setLast(true);
- frag.setSectionCode(s.getSectionCode());
- frag.setSectionNumber(UnsignedInteger.valueOf(num++));
- frag.setSectionOffset(UnsignedLong.valueOf(0L));
- fragments[i++] =frag;
- }
-
- xfr.setFragments(fragments);
-*/
-
- encodeTypes("xfr",xfr);
-
- final byte[] result;
- final Object input = xfr;
-/*
- result = encode(1024, input);
-
- boolean ok = true;
-
- for(int j = 10; ok && j < 400; j++)
- {
-
- byte[] result2 = encode(j,input);
-
- for(int i = 0; i <400; i++)
- {
- if(result[i] != result2[i])
- {
- System.out.println("result differs at " + i + " Splitting at " + j+ " [" + result[i] + " - " + result2[i] + "]");
- //break;
- //ok = false;
-
- }
- }
- }*/
- //System.out.println(Arrays.equals(result, result2));
-
- //doEncodes();
- /*OutputStream out = System.out;
- if(args.length > 0)
- {
- out = new FileOutputStream(args[0]);
- }
-
- Transfer xfr = new Transfer();
- fs.setSessionCredit(UnsignedInteger.valueOf(1024));
- fs.setTransferCount(UnsignedInteger.valueOf(2));
- fs.setLinkCredit(UnsignedInteger.valueOf(18));
- fs.setAvailable(UnsignedInteger.valueOf(0));
- fs.setDrain(false);
-
- xfr.setHandle(UnsignedInteger.valueOf(0));
- //xfr.setDeliveryTag(new Binary("\"queue\"<-6ec024a7-d98e-4196-9348-15f6026c32ca:0".getBytes()));
- xfr.setDeliveryTag(new Binary(new byte[] {0}));
- xfr.setTransferId(UnsignedInteger.valueOf(0));
- xfr.setSettled(true);
- xfr.setFlowState(fs);
-
- Header h = new Header();
- h.setTransmitTime(new Date(System.currentTimeMillis()));
- Properties p = new Properties();
- p.setTo(new Address("queue"));
- //p.setMessageId(new Binary(UUID.randomUUID().toString().getBytes()));
- AmqpMapSection m = new AmqpMapSection();
- DataSection b = new DataSection("Hello World!".getBytes());
-
- Footer f = new Footer();
-
- Section[] sections = new Section[] { h,p,m,b,f};
- //Section[] sections = new Section[] { b };
- //Section[] sections = { h,p, b};
- List<Fragment> fragments = new ArrayList<Fragment>(5);
-
- final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance();
-
- SectionEncoderImpl encoder = new SectionEncoderImpl(typeRegistry);
-
- for(Section s : sections)
- {
- Fragment frag = new Fragment();
-
- frag.setPayload(s.encode(encoder));
- frag.setFirst(true);
- frag.setLast(true);
- frag.setFormatCode(s.getSectionCode());
- frag.setFragmentOffset(null);
- fragments.add(frag);
- }
-
- xfr.setFragments(fragments);
-
-
- Object[] objectsToWrite = new Object[] { xfr };
- ByteBuffer buf = ByteBuffer.allocate(4096);
-
-
- for(Object obj : objectsToWrite)
- {
- ValueWriter writer = typeRegistry.getValueWriter(obj);
-
- int count;
-
-
- do
- {
- count = writer.writeToBuffer(buf);
- out.write(buf.array(), buf.arrayOffset(), count);
- buf.clear();
- } while (!writer.isComplete());
-
- }
-
- out.flush();
- out.close();*/
-
- }
-
- public static void doEncodes() throws IOException, ParseException
- {
- encodeTypes("boolean", Boolean.TRUE, Boolean.FALSE);
- encodeTypes("ubyte", UnsignedByte.valueOf((byte)0), UnsignedByte.valueOf((byte)1 ),UnsignedByte.valueOf((byte)3), UnsignedByte.valueOf((byte)42), UnsignedByte.valueOf("255"));
- encodeTypes("byte", Byte.valueOf((byte)0), Byte.valueOf( (byte)1), Byte.valueOf((byte) 3), Byte.valueOf((byte) 42), Byte.valueOf((byte) 127), Byte.valueOf((byte) -1), Byte.valueOf((byte) -3), Byte.valueOf((byte) -42), Byte.valueOf( (byte)-128));
- encodeTypes("ushort", UnsignedShort.valueOf((short)0), UnsignedShort.valueOf((short)1), UnsignedShort.valueOf((short)3), UnsignedShort.valueOf((short)42), UnsignedShort.valueOf("65535"));
- encodeTypes("short", Short.valueOf((short)0), Short.valueOf((short)1), Short.valueOf((short)3), Short.valueOf((short)42), Short.valueOf((short)32767), Short.valueOf((short)-1), Short.valueOf((short)-3), Short.valueOf((short)-42), Short.valueOf((short)-32768));
- encodeTypes("uint",UnsignedInteger.valueOf(0), UnsignedInteger.valueOf(1), UnsignedInteger.valueOf(3), UnsignedInteger.valueOf(42), UnsignedInteger.valueOf("4294967295"));
- encodeTypes("int", 0, 1, 3, 42, 2147483647, -1, -3, -42, -2147483648);
- encodeTypes("ulong", UnsignedLong.valueOf(0), UnsignedLong.valueOf(1), UnsignedLong.valueOf(3), UnsignedLong.valueOf(42), UnsignedLong.valueOf("18446744073709551615"));
- encodeTypes("long", 0l, 1l, 3l, 42l, 9223372036854775807l, -1l, -3l, -42l, -9223372036854775808l);
- encodeTypes("float", 3.14159);
- encodeTypes("double", Double.valueOf(3.14159265359));
- encodeTypes("char", '?');
-
- SimpleDateFormat df = new SimpleDateFormat("HHa z MMM d yyyy");
-
- encodeTypes("timestamp", df.parse("9AM PST Dec 6 2010"), df.parse("9AM PST Dec 6 1910"));
- encodeTypes("uuid", UUID.fromString("f275ea5e-0c57-4ad7-b11a-b20c563d3b71"));
- encodeTypes("binary", new Binary( new byte[] {(byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF}), new Binary(new byte[] { (byte)0xCA,(byte)0xFE, (byte)0xBA, (byte)0xBE}));
- encodeTypes("string", "The quick brown fox jumped over the lazy cow.");
- encodeTypes("symbol", Symbol.valueOf("connectathon"));
- encodeTypes("list", Arrays.asList(new Object[] {Long.valueOf(1), "two", Double.valueOf(3.14159265359), null, Boolean.FALSE}));
- Map map = new HashMap();
- map.put("one", Long.valueOf(1));
- map.put("two", Long.valueOf(2));
- map.put("pi", Double.valueOf(3.14159265359));
- map.put("list:", Arrays.asList(new Object[] {Long.valueOf(1), "two", Double.valueOf(3.14159265359), null, Boolean.FALSE}));
- map.put(null, Boolean.TRUE);
- encodeTypes("map", map);
- encodeTypes("null", null);
-
- }
-
- static void encodeTypes(String name, Object... vals ) throws IOException
- {
- FileOutputStream out = new FileOutputStream("/home/rob/"+name+".out");
- ByteBuffer buf = ByteBuffer.allocate(4096);
- final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance();
-
- if(vals != null)
- {
- for(Object obj : vals)
- {
- ValueWriter writer = typeRegistry.getValueWriter(obj);
-
- int count;
-
-
- do
- {
- count = writer.writeToBuffer(buf);
- out.write(buf.array(), buf.arrayOffset(), count);
- buf.clear();
- } while (!writer.isComplete());
-
- }
- }
- else
- {
- ValueWriter writer = typeRegistry.getValueWriter(null);
-
- int count;
-
-
- do
- {
- count = writer.writeToBuffer(buf);
- out.write(buf.array(), buf.arrayOffset(), count);
- buf.clear();
- } while (!writer.isComplete());
-
- }
- out.flush();
- out.close();
-
- }
-
- static byte[] encode(int size, Object... vals)
- {
- byte[] result = new byte[10000];
- int pos = 0;
-
- final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance();
- AMQFrame frame = AMQFrame.createAMQFrame((short) 0, (FrameBody) vals[0]);
- FrameWriter writer = new FrameWriter(typeRegistry);
- /*for(Object obj : vals)
- {
- final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance();
- ValueWriter writer = typeRegistry.getValueWriter(obj);
-*/
- int count;
-
- ByteBuffer buf = ByteBuffer.wrap(result, pos, size);
-
- do
- {
-
- writer.writeToBuffer(buf);
- pos = buf.position();
- buf = ByteBuffer.wrap(result, pos, size);
- if(!writer.isComplete())
- {
- count = 3;
- }
-
- } while (!writer.isComplete());
-/*
-
- }
-*/
-
- return result;
-
- }
-
-
-}
diff --git a/java/amqp-1-0-common/resources/LICENSE b/java/amqp-1-0-common/resources/LICENSE
new file mode 100644
index 0000000000..de4b130f35
--- /dev/null
+++ b/java/amqp-1-0-common/resources/LICENSE
@@ -0,0 +1,204 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
diff --git a/java/amqp-1-0-common/resources/NOTICE b/java/amqp-1-0-common/resources/NOTICE
new file mode 100644
index 0000000000..8d1c3f3122
--- /dev/null
+++ b/java/amqp-1-0-common/resources/NOTICE
@@ -0,0 +1,5 @@
+Apache Qpid
+Copyright 2006-2012 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
diff --git a/java/amqp-1-0-common/resources/README.txt b/java/amqp-1-0-common/resources/README.txt
new file mode 100644
index 0000000000..35d25050fe
--- /dev/null
+++ b/java/amqp-1-0-common/resources/README.txt
@@ -0,0 +1,7 @@
+
+Documentation
+--------------
+All of our user documentation can be accessed at:
+
+http://qpid.apache.org/documentation.html
+
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java
index dbf9306366..95e327852b 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java
@@ -77,13 +77,21 @@ public class FrameWriter implements ValueWriter<AMQFrame>
{
case SIZE_0:
- _typeWriter.setValue(_frame.getFrameBody());
-
int payloadLength = _payload == null ? 0 : _payload.remaining();
- _size = _typeWriter.writeToBuffer(remaining > 8
- ? (ByteBuffer)buffer.duplicate().position(buffer.position()+8)
- : ByteBuffer.wrap(EMPTY_BYTE_ARRAY)) + 8 + payloadLength;
+ if(_typeWriter!=null)
+ {
+ _typeWriter.setValue(_frame.getFrameBody());
+
+
+ _size = _typeWriter.writeToBuffer(remaining > 8
+ ? (ByteBuffer)buffer.duplicate().position(buffer.position()+8)
+ : ByteBuffer.wrap(EMPTY_BYTE_ARRAY)) + 8 + payloadLength;
+ }
+ else
+ {
+ _size = 8 + payloadLength;
+ }
if(remaining >= 4)
{
buffer.putInt(_size);
@@ -239,7 +247,14 @@ public class FrameWriter implements ValueWriter<AMQFrame>
_size = -1;
_payload = null;
final Object frameBody = frame.getFrameBody();
- _typeWriter = _registry.getValueWriter(frameBody);
+ if(frameBody!=null)
+ {
+ _typeWriter = _registry.getValueWriter(frameBody);
+ }
+ else
+ {
+ _typeWriter = null;
+ }
_payload = frame.getPayload() == null ? null : frame.getPayload().duplicate();
}
}
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java
index 769fe13d29..9684e290f4 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java
@@ -21,6 +21,7 @@
package org.apache.qpid.amqp_1_0.framing;
+import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.FrameBody;
import java.nio.ByteBuffer;
@@ -65,4 +66,11 @@ public abstract class AMQFrame<T>
return _frameBody;
}
+ @Override
+ public String toString()
+ {
+ return "AMQFrame{" +
+ "frameBody=" + _frameBody +
+ '}';
+ }
}
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
index 78bed8a71e..f4cd06f3ef 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java
@@ -103,6 +103,7 @@ public class ConnectionHandler
private boolean _setForClose;
private boolean _closed;
+ private long _nextHeartbeat;
public FrameOutput(final ConnectionEndpoint conn)
{
@@ -165,14 +166,34 @@ public class ConnectionHandler
{
synchronized(_conn.getLock())
{
+ long time = System.currentTimeMillis();
try
{
AMQFrame frame = null;
while(!closed() && (frame = _queue.poll()) == null && wait)
{
- _conn.getLock().wait();
+ _conn.getLock().wait(_conn.getIdleTimeout()/2);
+
+ if(_conn.getIdleTimeout()>0)
+ {
+ time = System.currentTimeMillis();
+
+ if(frame == null && time > _nextHeartbeat)
+ {
+ frame = new TransportFrame((short) 0,null);
+ break;
+ }
+ }
}
+
+
+
+ if(frame != null)
+ {
+ _nextHeartbeat = time + _conn.getIdleTimeout()/2;
+
+ }
if(frame == _endOfFrameMarker)
{
_closed = true;
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
index 70e990d92e..17bc2caf5f 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java
@@ -81,6 +81,8 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
private boolean _closedForInput;
private boolean _closedForOutput;
+ private long _idleTimeout;
+
private AMQPDescribedTypeRegistry _describedTypeRegistry = AMQPDescribedTypeRegistry.newInstance()
.registerTransportLayer()
.registerMessagingLayer()
@@ -282,6 +284,11 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
_remoteContainerId = open.getContainerId();
+ if(open.getIdleTimeOut() != null)
+ {
+ _idleTimeout = open.getIdleTimeOut().longValue();
+ }
+
switch(_state)
{
case UNOPENED:
@@ -316,6 +323,7 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
sendClose(new Close());
break;
case CLOSE_SENT:
+
default:
}
}
@@ -650,6 +658,11 @@ public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Sour
return this;
}
+ public synchronized long getIdleTimeout()
+ {
+ return _idleTimeout;
+ }
+
public synchronized void close()
{
switch(_state)
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java
index 4135199045..aca781afb9 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java
@@ -71,6 +71,10 @@ public class Delivery
{
setComplete(true);
}
+ if(Boolean.TRUE.equals(transfer.getSettled()))
+ {
+ setSettled(true);
+ }
}
public List<Transfer> getTransfers()
diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java
index cf86fc2471..5fbca0b695 100644
--- a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java
+++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java
@@ -113,33 +113,37 @@ public class ReceivingLinkEndpoint extends LinkEndpoint<ReceivingLinkListener>
synchronized (getLock())
{
TransientState transientState;
- boolean existingState = _unsettledMap.containsKey(transfer.getDeliveryTag());
- _unsettledMap.put(transfer.getDeliveryTag(), transfer.getState());
+ final Binary deliveryTag = delivery.getDeliveryTag();
+ boolean existingState = _unsettledMap.containsKey(deliveryTag);
+ if(!existingState || transfer.getState() != null)
+ {
+ _unsettledMap.put(deliveryTag, transfer.getState());
+ }
if(!existingState)
{
transientState = new TransientState(transfer.getDeliveryId());
- if(Boolean.TRUE.equals(transfer.getSettled()))
+ if(delivery.isSettled())
{
transientState.setSettled(true);
}
- _unsettledIds.put(transfer.getDeliveryTag(), transientState);
+ _unsettledIds.put(deliveryTag, transientState);
setLinkCredit(getLinkCredit().subtract(UnsignedInteger.ONE));
setDeliveryCount(getDeliveryCount().add(UnsignedInteger.ONE));
}
else
{
- transientState = _unsettledIds.get(transfer.getDeliveryTag());
+ transientState = _unsettledIds.get(deliveryTag);
transientState.incrementCredit();
- if(Boolean.TRUE.equals(transfer.getSettled()))
+ if(delivery.isSettled())
{
transientState.setSettled(true);
}
}
- if(transientState.isSettled())
+ if(transientState.isSettled() && delivery.isComplete())
{
- _unsettledMap.remove(transfer.getDeliveryTag());
+ _unsettledMap.remove(deliveryTag);
}
getLinkEventListener().messageTransfer(transfer);
@@ -155,7 +159,7 @@ public class ReceivingLinkEndpoint extends LinkEndpoint<ReceivingLinkListener>
super.receiveFlow(flow);
_remoteDrain = Boolean.TRUE.equals((Boolean)flow.getDrain());
setAvailable(flow.getAvailable());
- _remoteTransferCount = flow.getDeliveryCount();
+ setDeliveryCount(flow.getDeliveryCount());
getLock().notifyAll();
}
}
@@ -371,7 +375,7 @@ public class ReceivingLinkEndpoint extends LinkEndpoint<ReceivingLinkListener>
tag = iter.next();
tagsToUpdate.add(tag);
- deliveryId = _unsettledIds.get(firstTag).getDeliveryId();
+ deliveryId = _unsettledIds.get(tag).getDeliveryId();
if(deliveryId.equals(last.add(UnsignedInteger.ONE)))
{
diff --git a/java/bdbstore/bin/backup.sh b/java/bdbstore/bin/backup.sh
index 61311cd2ef..ba51758d3c 100755
--- a/java/bdbstore/bin/backup.sh
+++ b/java/bdbstore/bin/backup.sh
@@ -34,11 +34,8 @@ if [ -z "${QPID_HOME}" ]; then
export QPID_HOME=`cd ${WHEREAMI}/../ && pwd`
fi
-VERSION=0.19
-
# BDB's je JAR expected to be found in lib/opt
-LIBS="${QPID_HOME}/lib/opt/*:${QPID_HOME}/lib/qpid-bdbstore-${VERSION}.jar:${QPID_HOME}/lib/qpid-all.jar"
-
+LIBS="${QPID_HOME}/lib/opt/*:${QPID_HOME}/lib/qpid-all.jar"
echo "Starting Hot Backup Script"
java -Dlog4j.configuration=backup-log4j.xml ${JAVA_OPTS} -cp "${LIBS}" org.apache.qpid.server.store.berkeleydb.BDBBackup "${ARGS[@]}"
diff --git a/java/bdbstore/build.xml b/java/bdbstore/build.xml
index 7c305c7c2f..46809f6a90 100644
--- a/java/bdbstore/build.xml
+++ b/java/bdbstore/build.xml
@@ -18,7 +18,7 @@
-->
<project name="bdbstore" xmlns:ivy="antlib:org.apache.ivy.ant" default="build">
<property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test client common/test broker/test management/common systests" />
+ <property name="module.test.depends" value="client common/tests broker/tests management/common systests broker-plugins/management-jmx" />
<property name="module.genpom" value="true"/>
<import file="../module.xml" />
@@ -78,19 +78,4 @@ http://www.oracle.com/technetwork/database/berkeleydb/downloads/jeoslicense-0868
<target name="build" depends="check-request-props, bdb-jar-required, module.build" />
- <target name="postbuild" depends="copy-store-to-upgrade" />
-
- <target name="copy-store-to-upgrade" description="copy the upgrade tool resource folder contents into the build tree">
- <copy todir="${qpid.home}" failonerror="true">
- <fileset dir="src/test/resources/upgrade"/>
- </copy>
- </target>
-
- <target name="precompile-tests">
- <mkdir dir="${module.test.resources}"/>
- <copy todir="${module.test.resources}">
- <fileset dir="src/test/resources"/>
- </copy>
- </target>
-
</project>
diff --git a/java/bdbstore/jmx/MANIFEST.MF b/java/bdbstore/jmx/MANIFEST.MF
deleted file mode 100644
index ee59bc3ad8..0000000000
--- a/java/bdbstore/jmx/MANIFEST.MF
+++ /dev/null
@@ -1,20 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Bdbstore-Plugins JMX
-Bundle-SymbolicName: bdbstore-plugins-jmx
-Bundle-Description: Bdbstore Management plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Fragment-Host: broker-plugins-management-jmx
-Import-Package: org.apache.qpid,
- org.apache.qpid.management.common.mbeans.annotations,
- org.apache.qpid.server.model,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.server.store.berkeleydb,
- org.apache.log4j;version=1.2.16,
- javax.management,
- javax.management.openmbean
-Export-Package: org.apache.qpid.server.store.berkeleydb.jmx
diff --git a/java/bdbstore/jmx/build.xml b/java/bdbstore/jmx/build.xml
index 229631555d..d3e9f63b46 100644
--- a/java/bdbstore/jmx/build.xml
+++ b/java/bdbstore/jmx/build.xml
@@ -18,13 +18,13 @@
-->
<project name="bdbstore-jmx" default="build">
<property name="module.depends" value="common broker broker-plugins/management-jmx management/common bdbstore" />
- <property name="module.test.depends" value="test broker/test common/test management/common client systests bdbstore/test" />
+ <property name="module.test.depends" value="broker/tests common/tests management/common client systests bdbstore/tests" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided -Sqpid-broker-plugins-management-jmx=provided -Sqpid-management-common=provided -Sqpid-bdbstore=provided -Sje=provided"/>
+ <property name="broker.plugin" value="true"/>
+
<import file="../../module.xml" />
<target name="bundle" depends="bundle-tasks" />
diff --git a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java
index cfcea602b4..28528ec83c 100644
--- a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java
+++ b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import javax.management.JMException;
+import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
@@ -91,7 +92,7 @@ public class BDBHAMessageStoreManagerMBean extends AMQManagedObject implements M
@Override
public String getObjectInstanceName()
{
- return _store.getName();
+ return ObjectName.quote(_store.getName());
}
@Override
diff --git a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java
index 837da1eef3..14cdec1669 100644
--- a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java
+++ b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java
@@ -28,13 +28,11 @@ import org.apache.qpid.server.jmx.MBeanProvider;
import org.apache.qpid.server.jmx.ManagedObject;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.berkeleydb.BDBHAMessageStore;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
/**
* This provide will create a {@link BDBHAMessageStoreManagerMBean} if the child is a virtual
- * host and of type {@link BDBHAMessageStore#BDB_HA_STORE_TYPE}.
+ * host and of type {@link BDBHAMessageStore#TYPE}.
*
*/
public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider
@@ -50,7 +48,7 @@ public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider
public boolean isChildManageableByMBean(ConfiguredObject child)
{
return (child instanceof VirtualHost
- && BDBHAMessageStore.BDB_HA_STORE_TYPE.equals(child.getAttribute(VirtualHost.STORE_TYPE)));
+ && BDBHAMessageStore.TYPE.equals(child.getAttribute(VirtualHost.STORE_TYPE)));
}
@Override
@@ -58,10 +56,7 @@ public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider
{
VirtualHost virtualHostChild = (VirtualHost) child;
- VirtualHostRegistry virtualHostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry();
- org.apache.qpid.server.virtualhost.VirtualHost vhost = virtualHostRegistry.getVirtualHost(virtualHostChild.getName());
-
- BDBHAMessageStore messageStore = (BDBHAMessageStore) vhost.getMessageStore();
+ BDBHAMessageStore messageStore = (BDBHAMessageStore) virtualHostChild.getMessageStore();
if (LOGGER.isDebugEnabled())
{
diff --git a/java/bdbstore/jmx/src/main/resources/META-INF/services/org.apache.qpid.server.jmx.MBeanProvider b/java/bdbstore/jmx/src/main/resources/META-INF/services/org.apache.qpid.server.jmx.MBeanProvider
index b5bc947612..8ece9627b0 100644
--- a/java/bdbstore/jmx/src/main/resources/META-INF/services/org.apache.qpid.server.jmx.MBeanProvider
+++ b/java/bdbstore/jmx/src/main/resources/META-INF/services/org.apache.qpid.server.jmx.MBeanProvider
@@ -1 +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.
+#
org.apache.qpid.server.store.berkeleydb.jmx.BDBHAMessageStoreManagerMBeanProvider
diff --git a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
index 606983cdae..ff47ed958d 100644
--- a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
+++ b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterManagementTest.java
@@ -30,6 +30,7 @@ import java.util.Iterator;
import java.util.Set;
import javax.jms.Connection;
+import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
@@ -37,7 +38,6 @@ import org.apache.log4j.Logger;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.management.common.mbeans.ManagedBroker;
import org.apache.qpid.server.store.berkeleydb.jmx.ManagedBDBHAMessageStore;
-import org.apache.qpid.server.virtualhost.ManagedVirtualHost;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
@@ -55,7 +55,7 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
private static final Set<String> NON_MASTER_STATES = new HashSet<String>(Arrays.asList(REPLICA.toString(), DETACHED.toString(), UNKNOWN.toString()));;
private static final String VIRTUAL_HOST = "test";
- private static final String MANAGED_OBJECT_QUERY = "org.apache.qpid:type=BDBHAMessageStore,name=" + VIRTUAL_HOST;
+ private static final String MANAGED_OBJECT_QUERY = "org.apache.qpid:type=BDBHAMessageStore,name=" + ObjectName.quote(VIRTUAL_HOST);
private static final int NUMBER_OF_NODES = 4;
private final HATestClusterCreator _clusterCreator = new HATestClusterCreator(this, VIRTUAL_HOST, NUMBER_OF_NODES);
@@ -67,7 +67,6 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
protected void setUp() throws Exception
{
_brokerType = BrokerType.SPAWNED;
- _jmxUtils.setUp();
_clusterCreator.configureClusterNodes();
_brokerFailoverUrl = _clusterCreator.getConnectionUrlForAllClusterNodes();
@@ -132,12 +131,11 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
final int brokerPortNumber = getBrokerPortNumbers().iterator().next();
ManagedBDBHAMessageStore storeBean = getStoreBeanForNodeAtBrokerPort(brokerPortNumber);
+ awaitAllNodesJoiningGroup(storeBean, NUMBER_OF_NODES);
+
final TabularData groupMembers = storeBean.getAllNodesInGroup();
assertNotNull(groupMembers);
- final int numberOfDataRows = groupMembers.size();
- assertEquals("Unexpected number of data rows", NUMBER_OF_NODES ,numberOfDataRows);
-
for(int bdbPortNumber : _clusterCreator.getBdbPortNumbers())
{
final String nodeName = _clusterCreator.getNodeNameForNodeAt(bdbPortNumber);
@@ -155,8 +153,7 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
final int brokerPortNumberToMakeObservation = brokerPortNumberIterator.next();
final int brokerPortNumberToBeRemoved = brokerPortNumberIterator.next();
final ManagedBDBHAMessageStore storeBean = getStoreBeanForNodeAtBrokerPort(brokerPortNumberToMakeObservation);
- final int numberOfDataRows = storeBean.getAllNodesInGroup().size();
- assertEquals("Unexpected number of data rows before test", NUMBER_OF_NODES ,numberOfDataRows);
+ awaitAllNodesJoiningGroup(storeBean, NUMBER_OF_NODES);
final String removedNodeName = _clusterCreator.getNodeNameForNodeAt(_clusterCreator.getBdbPortForBrokerPort(brokerPortNumberToBeRemoved));
_clusterCreator.stopNode(brokerPortNumberToBeRemoved);
@@ -266,4 +263,27 @@ public class HAClusterManagementTest extends QpidBrokerTestCase
return _jmxUtils.getManagedBroker(VIRTUAL_HOST);
}
+
+ private void awaitAllNodesJoiningGroup(ManagedBDBHAMessageStore storeBean, int expectedNumberOfNodes) throws Exception
+ {
+ long totalTimeWaited = 0l;
+ long waitInterval = 100l;
+ long maxWaitTime = 10000;
+
+ int currentNumberOfNodes = storeBean.getAllNodesInGroup().size();
+ while (expectedNumberOfNodes > currentNumberOfNodes || totalTimeWaited > maxWaitTime)
+ {
+ LOGGER.debug("Still awaiting nodes to join group; expecting "
+ + expectedNumberOfNodes + " node(s) but only have " + currentNumberOfNodes
+ + " after " + totalTimeWaited + " ms.");
+
+ totalTimeWaited += waitInterval;
+ Thread.sleep(waitInterval);
+
+ currentNumberOfNodes = storeBean.getAllNodesInGroup().size();
+ }
+
+ assertEquals("Unexpected number of nodes in group after " + totalTimeWaited + " ms",
+ expectedNumberOfNodes ,currentNumberOfNodes);
+ }
}
diff --git a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java
index 22877ec36c..95626f7fa5 100644
--- a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java
+++ b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java
@@ -27,6 +27,7 @@ import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
+import javax.management.ObjectName;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.server.store.berkeleydb.jmx.ManagedBDBHAMessageStore;
@@ -41,7 +42,7 @@ public class HAClusterTwoNodeTest extends QpidBrokerTestCase
private static final String VIRTUAL_HOST = "test";
- private static final String MANAGED_OBJECT_QUERY = "org.apache.qpid:type=BDBHAMessageStore,name=" + VIRTUAL_HOST;
+ private static final String MANAGED_OBJECT_QUERY = "org.apache.qpid:type=BDBHAMessageStore,name=" + ObjectName.quote(VIRTUAL_HOST);
private static final int NUMBER_OF_NODES = 2;
private final HATestClusterCreator _clusterCreator = new HATestClusterCreator(this, VIRTUAL_HOST, NUMBER_OF_NODES);
@@ -56,7 +57,6 @@ public class HAClusterTwoNodeTest extends QpidBrokerTestCase
assertTrue(isJavaBroker());
assertTrue(isBrokerStorePersistent());
- _jmxUtils.setUp();
super.setUp();
}
@@ -86,11 +86,11 @@ public class HAClusterTwoNodeTest extends QpidBrokerTestCase
String storeConfigKeyPrefix = _clusterCreator.getStoreConfigKeyPrefix();
- setConfigurationProperty(storeConfigKeyPrefix + ".repConfig(0).name", ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT);
- setConfigurationProperty(storeConfigKeyPrefix + ".repConfig(0).value", "2 s");
+ setVirtualHostConfigurationProperty(storeConfigKeyPrefix + ".repConfig(0).name", ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT);
+ setVirtualHostConfigurationProperty(storeConfigKeyPrefix + ".repConfig(0).value", "2 s");
- setConfigurationProperty(storeConfigKeyPrefix + ".repConfig(1).name", ReplicationConfig.ELECTIONS_PRIMARY_RETRIES);
- setConfigurationProperty(storeConfigKeyPrefix + ".repConfig(1).value", "0");
+ setVirtualHostConfigurationProperty(storeConfigKeyPrefix + ".repConfig(1).name", ReplicationConfig.ELECTIONS_PRIMARY_RETRIES);
+ setVirtualHostConfigurationProperty(storeConfigKeyPrefix + ".repConfig(1).value", "0");
_clusterCreator.configureClusterNodes();
_clusterCreator.setDesignatedPrimaryOnFirstBroker(designedPrimary);
diff --git a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java
index 49b3ddd3dc..298d5bc045 100644
--- a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java
+++ b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import javax.management.JMException;
+import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.TabularData;
@@ -84,7 +85,7 @@ public class BDBHAMessageStoreManagerMBeanTest extends TestCase
{
when(_store.getName()).thenReturn(TEST_STORE_NAME);
- String expectedObjectName = "org.apache.qpid:type=BDBHAMessageStore,name=" + TEST_STORE_NAME;
+ String expectedObjectName = "org.apache.qpid:type=BDBHAMessageStore,name=" + ObjectName.quote(TEST_STORE_NAME);
assertEquals(expectedObjectName, _mBean.getObjectName().toString());
}
diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
index 9323111fdd..6e64ea5597 100644
--- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
@@ -54,13 +54,10 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-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.*;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BindingRecoveryHandler;
-import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.ExchangeRecoveryHandler;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.QueueRecoveryHandler;
import org.apache.qpid.server.store.MessageStoreRecoveryHandler.StoredMessageRecoveryHandler;
@@ -73,7 +70,6 @@ import org.apache.qpid.server.store.berkeleydb.tuple.ContentBinding;
import org.apache.qpid.server.store.berkeleydb.tuple.MessageMetaDataBinding;
import org.apache.qpid.server.store.berkeleydb.tuple.PreparedTransactionBinding;
import org.apache.qpid.server.store.berkeleydb.tuple.QueueEntryBinding;
-import org.apache.qpid.server.store.berkeleydb.tuple.StringMapBinding;
import org.apache.qpid.server.store.berkeleydb.tuple.UUIDTupleBinding;
import org.apache.qpid.server.store.berkeleydb.tuple.XidBinding;
import org.apache.qpid.server.store.berkeleydb.upgrade.Upgrader;
@@ -423,8 +419,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
BindingRecoveryHandler brh = qrh.completeQueueRecovery();
_configuredObjectHelper.recoverBindings(brh, configuredObjects);
- BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
- recoverBrokerLinks(lrh);
+ brh.completeBindingRecovery();
}
catch (DatabaseException e)
{
@@ -466,66 +461,6 @@ public abstract class AbstractBDBMessageStore implements MessageStore
}
}
- private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh)
- {
- Cursor cursor = null;
-
- try
- {
- cursor = _linkDb.openCursor(null, null);
- DatabaseEntry key = new DatabaseEntry();
- DatabaseEntry value = new DatabaseEntry();
-
- while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
- {
- UUID id = UUIDTupleBinding.getInstance().entryToObject(key);
- long createTime = LongBinding.entryToLong(value);
- Map<String,String> arguments = StringMapBinding.getInstance().entryToObject(value);
-
- ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments);
-
- recoverBridges(brh, id);
- }
- }
- finally
- {
- closeCursorSafely(cursor);
- }
-
- }
-
- private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId)
- {
- Cursor cursor = null;
-
- try
- {
- cursor = _bridgeDb.openCursor(null, null);
- DatabaseEntry key = new DatabaseEntry();
- DatabaseEntry value = new DatabaseEntry();
-
- while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS)
- {
- UUID id = UUIDTupleBinding.getInstance().entryToObject(key);
-
- UUID parentId = UUIDTupleBinding.getInstance().entryToObject(value);
- if(parentId.equals(linkId))
- {
-
- long createTime = LongBinding.entryToLong(value);
- Map<String,String> arguments = StringMapBinding.getInstance().entryToObject(value);
- brh.bridge(id,createTime,arguments);
- }
- }
- brh.completeBridgeRecoveryForLink();
- }
- finally
- {
- closeCursorSafely(cursor);
- }
-
- }
-
private void recoverMessages(MessageStoreRecoveryHandler msrh) throws DatabaseException
{
@@ -940,89 +875,6 @@ public abstract class AbstractBDBMessageStore implements MessageStore
}
}
- public void createBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- if (_stateManager.isInState(State.ACTIVE))
- {
- DatabaseEntry key = new DatabaseEntry();
- UUIDTupleBinding.getInstance().objectToEntry(link.getQMFId(), key);
-
- DatabaseEntry value = new DatabaseEntry();
- LongBinding.longToEntry(link.getCreateTime(), value);
- StringMapBinding.getInstance().objectToEntry(link.getArguments(), value);
-
- try
- {
- _linkDb.put(null, key, value);
- }
- catch (DatabaseException e)
- {
- throw new AMQStoreException("Error writing Link " + link
- + " to database: " + e.getMessage(), e);
- }
- }
- }
-
- public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- DatabaseEntry key = new DatabaseEntry();
- UUIDTupleBinding.getInstance().objectToEntry(link.getQMFId(), key);
- try
- {
- OperationStatus status = _linkDb.delete(null, key);
- if (status == OperationStatus.NOTFOUND)
- {
- throw new AMQStoreException("Link " + link + " not found");
- }
- }
- catch (DatabaseException e)
- {
- throw new AMQStoreException("Error deleting the Link " + link + " from database: " + e.getMessage(), e);
- }
- }
-
- public void createBridge(final Bridge bridge) throws AMQStoreException
- {
- if (_stateManager.isInState(State.ACTIVE))
- {
- DatabaseEntry key = new DatabaseEntry();
- UUIDTupleBinding.getInstance().objectToEntry(bridge.getQMFId(), key);
-
- DatabaseEntry value = new DatabaseEntry();
- UUIDTupleBinding.getInstance().objectToEntry(bridge.getLink().getQMFId(),value);
- LongBinding.longToEntry(bridge.getCreateTime(),value);
- StringMapBinding.getInstance().objectToEntry(bridge.getArguments(), value);
-
- try
- {
- _bridgeDb.put(null, key, value);
- }
- catch (DatabaseException e)
- {
- throw new AMQStoreException("Error writing Bridge " + bridge
- + " to database: " + e.getMessage(), e);
- }
-
- }
- }
-
- public void deleteBridge(final Bridge bridge) throws AMQStoreException
- {
- DatabaseEntry key = new DatabaseEntry();
- UUIDTupleBinding.getInstance().objectToEntry(bridge.getQMFId(), key);
- try
- {
- OperationStatus status = _bridgeDb.delete(null, key);
- if (status == OperationStatus.NOTFOUND)
- {
- throw new AMQStoreException("Bridge " + bridge + " not found");
- }
- }
- catch (DatabaseException e)
- {
- throw new AMQStoreException("Error deleting the Bridge " + bridge + " from database: " + e.getMessage(), e);
- }
- }
/**
* Places a message onto a specified queue, in a given transaction.
@@ -1050,7 +902,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
{
LOGGER.debug("Enqueuing message " + messageId + " on queue "
+ (queue instanceof AMQQueue ? ((AMQQueue) queue).getName() + " with id " : "") + queue.getId()
- + " [Transaction" + tx + "]");
+ + " in transaction " + tx);
}
_deliveryDb.put(tx, key, value);
}
@@ -1204,7 +1056,8 @@ public abstract class AbstractBDBMessageStore implements MessageStore
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("commitTranImpl completed for [Transaction:" + tx + "]");
+ String transactionType = syncCommit ? "synchronous" : "asynchronous";
+ LOGGER.debug("commitTranImpl completed " + transactionType + " transaction " + tx);
}
}
catch (DatabaseException e)
@@ -1226,7 +1079,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
{
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("abortTran called for [Transaction:" + tx + "]");
+ LOGGER.debug("abortTran called for transaction " + tx);
}
try
@@ -1338,7 +1191,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("Storing content for message " + messageId + "[Transaction" + tx + "]");
+ LOGGER.debug("Storing content for message " + messageId + " in transaction " + tx);
}
}
@@ -1363,8 +1216,9 @@ public abstract class AbstractBDBMessageStore implements MessageStore
{
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("public void storeMetaData(Txn tx = " + tx + ", Long messageId = "
- + messageId + ", MessageMetaData messageMetaData = " + messageMetaData + "): called");
+ LOGGER.debug("storeMetaData called for transaction " + tx
+ + ", messageId " + messageId
+ + ", messageMetaData " + messageMetaData);
}
DatabaseEntry key = new DatabaseEntry();
@@ -1378,7 +1232,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
_messageMetaDataDb.put(tx, key, value);
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("Storing message metadata for message id " + messageId + "[Transaction" + tx + "]");
+ LOGGER.debug("Storing message metadata for message id " + messageId + " in transaction " + tx);
}
}
catch (DatabaseException e)
@@ -1680,7 +1534,8 @@ public abstract class AbstractBDBMessageStore implements MessageStore
else
{
ByteBuffer buf = ByteBuffer.allocate(size);
- getContent(offsetInMessage, buf);
+ int length = getContent(offsetInMessage, buf);
+ buf.limit(length);
buf.position(0);
return buf;
}
diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStore.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStore.java
index c40f24dbc3..ba111e8091 100644
--- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStore.java
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStore.java
@@ -105,7 +105,7 @@ public class BDBHAMessageStore extends AbstractBDBMessageStore implements HAMess
put(ReplicationConfig.LOG_FLUSH_TASK_INTERVAL, "1 min");
}});
- public static final String BDB_HA_STORE_TYPE = "BDB-HA";
+ public static final String TYPE = "BDB-HA";
private String _groupName;
private String _nodeName;
@@ -602,6 +602,6 @@ public class BDBHAMessageStore extends AbstractBDBMessageStore implements HAMess
@Override
public String getStoreType()
{
- return BDB_HA_STORE_TYPE;
+ return TYPE;
}
}
diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreFactory.java
new file mode 100644
index 0000000000..20dce2628d
--- /dev/null
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreFactory.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.berkeleydb;
+
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.MessageStoreFactory;
+
+public class BDBHAMessageStoreFactory implements MessageStoreFactory
+{
+
+ @Override
+ public String getType()
+ {
+ return BDBHAMessageStore.TYPE;
+ }
+
+ @Override
+ public MessageStore createMessageStore()
+ {
+ return new BDBHAMessageStore();
+ }
+
+}
diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
index 82bc3d8564..4028de4b80 100644
--- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
@@ -42,7 +42,7 @@ import com.sleepycat.je.EnvironmentConfig;
public class BDBMessageStore extends AbstractBDBMessageStore
{
private static final Logger LOGGER = Logger.getLogger(BDBMessageStore.class);
- private static final String BDB_STORE_TYPE = "BDB";
+ public static final String TYPE = "BDB";
private CommitThreadWrapper _commitThreadWrapper;
@Override
@@ -108,7 +108,7 @@ public class BDBMessageStore extends AbstractBDBMessageStore
@Override
public String getStoreType()
{
- return BDB_STORE_TYPE;
+ return TYPE;
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java
index 0e01c27db5..126bf1928a 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java
@@ -18,36 +18,24 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.server.store.berkeleydb;
-public enum QMFType
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.MessageStoreFactory;
+
+public class BDBMessageStoreFactory implements MessageStoreFactory
{
- UINT8,
- UINT16,
- UINT32,
- UINT64,
- UNKNOWN,
- STR8,
- STR16,
- ABSTIME,
- DELTATIME,
- OBJECTREFERENCE,
- BOOLEAN,
- FLOAT,
- DOUBLE,
- UUID,
- MAP,
- INT8,
- INT16,
- INT32,
- INT64,
- OBJECT,
- LIST,
- ARRAY;
+ @Override
+ public String getType()
+ {
+ return BDBMessageStore.TYPE;
+ }
- public int codeValue()
+ @Override
+ public MessageStore createMessageStore()
{
- return ordinal()+1;
+ return new BDBMessageStore();
}
+
}
diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CommitThreadWrapper.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CommitThreadWrapper.java
index fe1556b5a6..598d20146c 100644
--- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CommitThreadWrapper.java
+++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/CommitThreadWrapper.java
@@ -80,7 +80,7 @@ public class CommitThreadWrapper
{
if (LOGGER.isDebugEnabled())
{
- LOGGER.debug("public synchronized void complete(): called (Transaction = " + _tx + ")");
+ LOGGER.debug("complete() called for transaction " + _tx);
}
_complete = true;
@@ -101,7 +101,10 @@ public class CommitThreadWrapper
if(!_syncCommit)
{
- LOGGER.debug("CommitAsync was requested, returning immediately.");
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("CommitAsync was requested, returning immediately.");
+ }
return;
}
@@ -121,6 +124,12 @@ public class CommitThreadWrapper
public synchronized void waitForCompletion()
{
+ long startTime = 0;
+ if(LOGGER.isDebugEnabled())
+ {
+ startTime = System.currentTimeMillis();
+ }
+
while (!isComplete())
{
_commitThread.explicitNotify();
@@ -133,6 +142,12 @@ public class CommitThreadWrapper
throw new RuntimeException(e);
}
}
+
+ if(LOGGER.isDebugEnabled())
+ {
+ long duration = System.currentTimeMillis() - startTime;
+ LOGGER.debug("waitForCompletion returning after " + duration + " ms for transaction " + _tx);
+ }
}
}
@@ -198,8 +213,20 @@ public class CommitThreadWrapper
try
{
+ long startTime = 0;
+ if(LOGGER.isDebugEnabled())
+ {
+ startTime = System.currentTimeMillis();
+ }
+
_environment.flushLog(true);
+ if(LOGGER.isDebugEnabled())
+ {
+ long duration = System.currentTimeMillis() - startTime;
+ LOGGER.debug("flushLog completed in " + duration + " ms");
+ }
+
for(int i = 0; i < size; i++)
{
BDBCommitFuture commit = _jobQueue.poll();
diff --git a/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory b/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory
new file mode 100644
index 0000000000..0be7035e2e
--- /dev/null
+++ b/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+org.apache.qpid.server.store.berkeleydb.BDBMessageStoreFactory
+org.apache.qpid.server.store.berkeleydb.BDBHAMessageStoreFactory \ No newline at end of file
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java
index 342c185b99..7c04d83e79 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java
@@ -63,7 +63,7 @@ public class BDBBackupTest extends QpidBrokerTestCase
// It would be preferable to lookup the store path using #getConfigurationStringProperty("virtualhosts...")
// but the config as known to QBTC does not pull-in the virtualhost section from its separate source file
- _backupFromDir = new File(qpidWork + "/bdbstore/" + TEST_VHOST + "-store");
+ _backupFromDir = new File(qpidWork + File.separator + TEST_VHOST + "-store");
boolean fromDirExistsAndIsDir = _backupFromDir.isDirectory();
assertTrue("backupFromDir " + _backupFromDir + " should already exist", fromDirExistsAndIsDir);
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreTest.java
index a04fb20680..8e32a1d113 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreTest.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAMessageStoreTest.java
@@ -24,12 +24,8 @@ import java.io.File;
import java.net.InetAddress;
import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-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.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.TestApplicationRegistry;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.util.FileUtils;
@@ -51,6 +47,7 @@ public class BDBHAMessageStoreTest extends QpidTestCase
private int _masterPort;
private String _host;
private XMLConfiguration _configXml;
+ private VirtualHost _virtualHost;
public void setUp() throws Exception
{
@@ -63,41 +60,48 @@ public class BDBHAMessageStoreTest extends QpidTestCase
FileUtils.delete(new File(_workDir), true);
_configXml = new XMLConfiguration();
- }
- public void tearDown() throws Exception
- {
- FileUtils.delete(new File(_workDir), true);
- super.tearDown();
- }
+ BrokerTestHelper.setUp();
+ }
- public void testSetSystemConfiguration() throws Exception
+ public void tearDown() throws Exception
{
- // create virtual host configuration, registry and host instance
- addVirtualHostConfiguration();
- TestApplicationRegistry registry = initialize();
try
{
- VirtualHost virtualhost = registry.getVirtualHostRegistry().getVirtualHost("test" + _masterPort);
- BDBHAMessageStore store = (BDBHAMessageStore) virtualhost.getMessageStore();
-
- // test whether JVM system settings were applied
- Environment env = store.getEnvironment();
- assertEquals("Unexpected number of cleaner threads", TEST_NUMBER_OF_THREADS, env.getConfig().getConfigParam(EnvironmentConfig.CLEANER_THREADS));
- assertEquals("Unexpected log file max", TEST_LOG_FILE_MAX, env.getConfig().getConfigParam(EnvironmentConfig.LOG_FILE_MAX));
-
- ReplicatedEnvironment repEnv = store.getReplicatedEnvironment();
- assertEquals("Unexpected number of elections primary retries", TEST_ELECTION_RETRIES,
- repEnv.getConfig().getConfigParam(ReplicationConfig.ELECTIONS_PRIMARY_RETRIES));
- assertEquals("Unexpected number of elections primary retries", TEST_ENV_CONSISTENCY_TIMEOUT,
- repEnv.getConfig().getConfigParam(ReplicationConfig.ENV_CONSISTENCY_TIMEOUT));
+ FileUtils.delete(new File(_workDir), true);
+ if (_virtualHost != null)
+ {
+ _virtualHost.close();
+ }
}
finally
{
- ApplicationRegistry.remove();
+ BrokerTestHelper.tearDown();
+ super.tearDown();
}
}
+ public void testSetSystemConfiguration() throws Exception
+ {
+ // create virtual host configuration, registry and host instance
+ addVirtualHostConfiguration();
+ String vhostName = "test" + _masterPort;
+ VirtualHostConfiguration configuration = new VirtualHostConfiguration(vhostName, _configXml.subset("virtualhosts.virtualhost." + vhostName), BrokerTestHelper.createBrokerMock());
+ _virtualHost = BrokerTestHelper.createVirtualHost(configuration);
+ BDBHAMessageStore store = (BDBHAMessageStore) _virtualHost.getMessageStore();
+
+ // test whether JVM system settings were applied
+ Environment env = store.getEnvironment();
+ assertEquals("Unexpected number of cleaner threads", TEST_NUMBER_OF_THREADS, env.getConfig().getConfigParam(EnvironmentConfig.CLEANER_THREADS));
+ assertEquals("Unexpected log file max", TEST_LOG_FILE_MAX, env.getConfig().getConfigParam(EnvironmentConfig.LOG_FILE_MAX));
+
+ ReplicatedEnvironment repEnv = store.getReplicatedEnvironment();
+ assertEquals("Unexpected number of elections primary retries", TEST_ELECTION_RETRIES,
+ repEnv.getConfig().getConfigParam(ReplicationConfig.ELECTIONS_PRIMARY_RETRIES));
+ assertEquals("Unexpected number of elections primary retries", TEST_ENV_CONSISTENCY_TIMEOUT,
+ repEnv.getConfig().getConfigParam(ReplicationConfig.ENV_CONSISTENCY_TIMEOUT));
+ }
+
private void addVirtualHostConfiguration() throws Exception
{
int port = findFreePort();
@@ -152,14 +156,4 @@ public class BDBHAMessageStoreTest extends QpidTestCase
}
return _host + ":" + _masterPort;
}
-
- private TestApplicationRegistry initialize() throws Exception
- {
- CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
- ServerConfiguration configuration = new ServerConfiguration(_configXml);
- TestApplicationRegistry registry = new TestApplicationRegistry(configuration);
- ApplicationRegistry.initialise(registry);
- registry.getVirtualHostRegistry().setDefaultVirtualHostName("test" + _masterPort);
- return registry;
- }
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
index eef9f7eab4..d18c850ecf 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreTest.java
@@ -225,7 +225,7 @@ public class BDBMessageStoreTest extends org.apache.qpid.server.store.MessageSto
messageStore.close();
AbstractBDBMessageStore newStore = new BDBMessageStore();
- newStore.configure("", _config.subset("store"));
+ newStore.configure("", getConfig().subset("store"));
newStore.startWithNoRecover();
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgradeTestPreparer.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgradeTestPreparer.java
index 122f846a2d..390d667db0 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgradeTestPreparer.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgradeTestPreparer.java
@@ -20,6 +20,9 @@
*/
package org.apache.qpid.server.store.berkeleydb;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
@@ -35,6 +38,11 @@ import javax.jms.TopicConnection;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
import org.apache.qpid.client.AMQConnectionFactory;
import org.apache.qpid.client.AMQDestination;
@@ -62,6 +70,11 @@ public class BDBStoreUpgradeTestPreparer
public static final String QUEUE_NAME="myUpgradeQueue";
public static final String NON_DURABLE_QUEUE_NAME="queue-non-durable";
+ public static final String PRIORITY_QUEUE_NAME="myPriorityQueue";
+ public static final String QUEUE_WITH_DLQ_NAME="myQueueWithDLQ";
+ public static final String NONEXCLUSIVE_WITH_ERRONEOUS_OWNER = "nonexclusive-with-erroneous-owner";
+ public static final String MISUSED_OWNER = "misused-owner-as-description";
+
private static AMQConnectionFactory _connFac;
private static final String CONN_URL =
"amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'";
@@ -86,10 +99,10 @@ public class BDBStoreUpgradeTestPreparer
{
Connection connection = _connFac.createConnection();
AMQSession<?, ?> session = (AMQSession<?,?>)connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- AMQShortString queueName = AMQShortString.valueOf(NON_DURABLE_QUEUE_NAME);
+ AMQShortString queueName = new AMQShortString(NON_DURABLE_QUEUE_NAME);
AMQDestination destination = (AMQDestination) session.createQueue(NON_DURABLE_QUEUE_NAME);
session.sendCreateQueue(queueName, false, false, false, null);
- session.bindQueue(queueName, queueName, null, AMQShortString.valueOf("amq.direct"), destination);
+ session.bindQueue(queueName, queueName, null, new AMQShortString("amq.direct"), destination);
MessageProducer messageProducer = session.createProducer(destination);
sendMessages(session, messageProducer, destination, DeliveryMode.PERSISTENT, 1024, 3);
connection.close();
@@ -140,11 +153,56 @@ public class BDBStoreUpgradeTestPreparer
// Publish 5 persistent messages which will NOT be committed and so should be 'lost'
sendMessages(session, messageProducer, queue, DeliveryMode.PERSISTENT, 1*1024, 5);
+ messageProducer.close();
+ session.close();
+
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ // Create a priority queue on broker
+ final Map<String,Object> priorityQueueArguments = new HashMap<String, Object>();
+ priorityQueueArguments.put("x-qpid-priorities",10);
+ createAndBindQueueOnBroker(session, PRIORITY_QUEUE_NAME, priorityQueueArguments);
+
+ // Create a queue that has a DLQ
+ final Map<String,Object> queueWithDLQArguments = new HashMap<String, Object>();
+ queueWithDLQArguments.put("x-qpid-dlq-enabled", true);
+ queueWithDLQArguments.put("x-qpid-maximum-delivery-count", 2);
+ createAndBindQueueOnBroker(session, QUEUE_WITH_DLQ_NAME, queueWithDLQArguments);
+
+ // Send message to the DLQ
+ Queue dlq = session.createQueue("fanout://" + QUEUE_WITH_DLQ_NAME + "_DLE//does-not-matter");
+ MessageProducer dlqMessageProducer = session.createProducer(dlq);
+ sendMessages(session, dlqMessageProducer, dlq, DeliveryMode.PERSISTENT, 1*1024, 1);
+ session.commit();
+ // Create a queue with JMX specifying an owner, so it can later be moved into description
+ createAndBindQueueOnBrokerWithJMX(NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, MISUSED_OWNER, priorityQueueArguments);
session.close();
connection.close();
}
+ private void createAndBindQueueOnBroker(Session session, String queueName, final Map<String, Object> arguments) throws Exception
+ {
+ ((AMQSession<?,?>) session).createQueue(new AMQShortString(queueName), false, true, false, arguments);
+ Queue queue = (Queue) session.createQueue("direct://amq.direct/"+queueName+"/"+queueName+"?durable='true'");
+ ((AMQSession<?,?>) session).declareAndBind((AMQDestination)queue);
+ }
+
+ private void createAndBindQueueOnBrokerWithJMX(String queueName, String owner, final Map<String, Object> arguments) throws Exception
+ {
+ Map<String, Object> environment = new HashMap<String, Object>();
+ environment.put(JMXConnector.CREDENTIALS, new String[] {"admin","admin"});
+ JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi");
+ JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment);
+ MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
+ ObjectName virtualHost = new ObjectName("org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=\"test\"");
+
+ Object[] params = new Object[] {queueName, owner, true, arguments};
+ String[] signature = new String[] {String.class.getName(), String.class.getName(), boolean.class.getName(), Map.class.getName()};
+ mbsc.invoke(virtualHost, "createNewQueue", params, signature);
+
+ ObjectName directExchange = new ObjectName("org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=\"test\",name=\"amq.direct\",ExchangeType=direct");
+ mbsc.invoke(directExchange, "createNewBinding", new Object[] {queueName, queueName}, new String[] {String.class.getName(), String.class.getName()});
+ }
/**
* Prepare a DurableSubscription backing queue for use in testing selector
* recovery and queue exclusivity marking during the upgrade process.
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
index 4e201d5473..e4837b212e 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java
@@ -22,16 +22,20 @@ package org.apache.qpid.server.store.berkeleydb;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.NON_DURABLE_QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.PRIORITY_QUEUE_NAME;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_WITH_DLQ_NAME;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.SELECTOR_SUB_NAME;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.SELECTOR_TOPIC_NAME;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.SUB_NAME;
import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.TOPIC_NAME;
import java.io.File;
+import java.io.InputStream;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
+import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
@@ -43,7 +47,10 @@ import javax.jms.TopicConnection;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
@@ -70,7 +77,7 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
assertNotNull("QPID_WORK must be set", QPID_WORK_ORIG);
- _storeLocation = getWorkDirBaseDir() + "/bdbstore/test-store";
+ _storeLocation = getWorkDirBaseDir() + File.separator + "test-store";
//Clear the two target directories if they exist.
File directory = new File(_storeLocation);
@@ -78,15 +85,13 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
{
FileUtils.delete(directory, true);
}
+ directory.mkdirs();
// copy store files
- String src = getClass().getClassLoader().getResource("upgrade/bdbstore-v4/test-store").toURI().getPath();
- FileUtils.copyRecursive(new File(src), new File(_storeLocation));
-
- //override the broker config used and then start the broker with the updated store
- _configFile = new File("build/etc/config-systests-bdb.xml");
- setConfigurationProperty("management.enabled", "true");
+ InputStream src = getClass().getClassLoader().getResourceAsStream("upgrade/bdbstore-v4/test-store/00000000.jdb");
+ FileUtils.copy(src, new File(_storeLocation, "00000000.jdb"));
+ getBrokerConfiguration().addJmxManagementConfiguration();
super.setUp();
}
@@ -302,11 +307,110 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
Queue queue = session.createQueue(NON_DURABLE_QUEUE_NAME);
MessageConsumer messageConsumer = session.createConsumer(queue);
- for (int i = 0; i < 3; i++)
+ for (int i = 1; i <= 3; i++)
{
Message message = messageConsumer.receive(1000);
assertNotNull("Message was not migrated!", message);
assertTrue("Unexpected message received!", message instanceof TextMessage);
+ assertEquals("ID property did not match", i, message.getIntProperty("ID"));
+ }
+ }
+
+ /**
+ * Tests store upgrade has maintained the priority queue configuration,
+ * such that sending messages with priorities out-of-order and then consuming
+ * them gets the messages back in priority order.
+ */
+ public void testPriorityQueue() throws Exception
+ {
+ // Create a connection and start it
+ Connection connection = getConnection();
+ connection.start();
+
+ // send some messages to the priority queue
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue queue = session.createQueue(PRIORITY_QUEUE_NAME);
+ MessageProducer producer = session.createProducer(queue);
+
+ producer.setPriority(4);
+ producer.send(createMessage(1, false, session, producer));
+ producer.setPriority(1);
+ producer.send(createMessage(2, false, session, producer));
+ producer.setPriority(9);
+ producer.send(createMessage(3, false, session, producer));
+ session.close();
+
+ //consume the messages, expected order: msg 3, msg 1, msg 2.
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ Message msg = consumer.receive(1500);
+ assertNotNull("expected message was not received", msg);
+ assertEquals(3, msg.getIntProperty("msg"));
+ msg = consumer.receive(1500);
+ assertNotNull("expected message was not received", msg);
+ assertEquals(1, msg.getIntProperty("msg"));
+ msg = consumer.receive(1500);
+ assertNotNull("expected message was not received", msg);
+ assertEquals(2, msg.getIntProperty("msg"));
+ }
+
+ /**
+ * Test that the queue configured to have a DLQ was recovered and has the alternate exchange
+ * and max delivery count, the DLE exists, the DLQ exists with no max delivery count, the
+ * DLQ is bound to the DLE, and that the DLQ does not itself have a DLQ.
+ *
+ * DLQs are NOT enabled at the virtualhost level, we are testing recovery of the arguments
+ * that turned it on for this specific queue.
+ */
+ public void testRecoveryOfQueueWithDLQ() throws Exception
+ {
+ JMXTestUtils jmxUtils = null;
+ try
+ {
+ jmxUtils = new JMXTestUtils(this, "guest", "guest");
+ jmxUtils.open();
+ }
+ catch (Exception e)
+ {
+ fail("Unable to establish JMX connection, test cannot proceed");
+ }
+
+ try
+ {
+ //verify the DLE exchange exists, has the expected type, and a single binding for the DLQ
+ ManagedExchange exchange = jmxUtils.getManagedExchange(QUEUE_WITH_DLQ_NAME + "_DLE");
+ assertEquals("Wrong exchange type", "fanout", exchange.getExchangeType());
+ TabularDataSupport bindings = (TabularDataSupport) exchange.bindings();
+ assertEquals(1, bindings.size());
+ for(Object o : bindings.values())
+ {
+ CompositeData binding = (CompositeData) o;
+
+ String bindingKey = (String) binding.get(ManagedExchange.BINDING_KEY);
+ String[] queueNames = (String[]) binding.get(ManagedExchange.QUEUE_NAMES);
+
+ //Because its a fanout exchange, we just return a single '*' key with all bound queues
+ assertEquals("unexpected binding key", "*", bindingKey);
+ assertEquals("unexpected number of queues bound", 1, queueNames.length);
+ assertEquals("unexpected queue name", QUEUE_WITH_DLQ_NAME + "_DLQ", queueNames[0]);
+ }
+
+ //verify the queue exists, has the expected alternate exchange and max delivery count
+ ManagedQueue queue = jmxUtils.getManagedQueue(QUEUE_WITH_DLQ_NAME);
+ assertEquals("Queue does not have the expected AlternateExchange", QUEUE_WITH_DLQ_NAME + "_DLE", queue.getAlternateExchange());
+ assertEquals("Unexpected maximum delivery count", Integer.valueOf(2), queue.getMaximumDeliveryCount());
+
+ ManagedQueue dlQqueue = jmxUtils.getManagedQueue(QUEUE_WITH_DLQ_NAME + "_DLQ");
+ assertNull("Queue should not have an AlternateExchange", dlQqueue.getAlternateExchange());
+ assertEquals("Unexpected maximum delivery count", Integer.valueOf(0), dlQqueue.getMaximumDeliveryCount());
+
+ String dlqDlqObjectNameString = jmxUtils.getQueueObjectNameString("test", QUEUE_WITH_DLQ_NAME + "_DLQ" + "_DLQ");
+ assertFalse("a DLQ should not exist for the DLQ itself", jmxUtils.doesManagedObjectExist(dlqDlqObjectNameString));
+ }
+ finally
+ {
+ jmxUtils.close();
}
}
@@ -387,4 +491,11 @@ public class BDBUpgradeTest extends QpidBrokerTestCase
session.close();
}
+ private Message createMessage(int msgId, boolean first, Session producerSession, MessageProducer producer) throws JMSException
+ {
+ Message send = producerSession.createTextMessage("Message: " + msgId);
+ send.setIntProperty("msg", msgId);
+
+ return send;
+ }
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java
index c6a9ba8f8b..0e1ef7b25d 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java
@@ -31,6 +31,7 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestUtils;
import com.sleepycat.je.rep.ReplicationConfig;
@@ -134,7 +135,10 @@ public class HAClusterBlackboxTest extends QpidBrokerTestCase
public void assertFailoverOccurs(long delay) throws InterruptedException
{
- _failoverLatch.await(delay, TimeUnit.MILLISECONDS);
+ if (!_failoverLatch.await(delay, TimeUnit.MILLISECONDS))
+ {
+ LOGGER.warn("Test thread dump:\n\n" + TestUtils.dumpThreads() + "\n");
+ }
assertEquals("Failover did not occur", 0, _failoverLatch.getCount());
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java
index abe13edc32..4c2fa910f5 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java
@@ -43,6 +43,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.url.URLSyntaxException;
@@ -67,7 +68,7 @@ public class HATestClusterCreator
private final Map<Integer, Integer> _brokerPortToBdbPortMap = new HashMap<Integer, Integer>();
private final Map<Integer, BrokerConfigHolder> _brokerConfigurations = new TreeMap<Integer, BrokerConfigHolder>();
private final String _virtualHostName;
- private final String _storeConfigKeyPrefix;
+ private final String _vhostStoreConfigKeyPrefix;
private final String _ipAddressOfBroker;
private final String _groupName ;
@@ -82,7 +83,7 @@ public class HATestClusterCreator
_groupName = "group" + _testcase.getName();
_ipAddressOfBroker = getIpAddressOfBrokerHost();
_numberOfNodes = numberOfNodes;
- _storeConfigKeyPrefix = "virtualhosts.virtualhost." + _virtualHostName + ".store.";
+ _vhostStoreConfigKeyPrefix = "virtualhosts.virtualhost." + _virtualHostName + ".store.";
_bdbHelperPort = 0;
}
@@ -102,7 +103,9 @@ public class HATestClusterCreator
}
configureClusterNode(brokerPort, bdbPort);
- collectConfig(brokerPort, _testcase.getTestConfiguration(), _testcase.getTestVirtualhosts());
+ TestBrokerConfiguration brokerConfiguration = _testcase.getBrokerConfiguration(brokerPort);
+ brokerConfiguration.addJmxManagementConfiguration();
+ collectConfig(brokerPort, brokerConfiguration, _testcase.getTestVirtualhosts());
brokerPort = _testcase.getNextAvailable(bdbPort + 1);
}
@@ -127,7 +130,7 @@ public class HATestClusterCreator
*/
private String getConfigKey(String configKeySuffix)
{
- final String configKey = StringUtils.substringAfter(_storeConfigKeyPrefix + configKeySuffix, "virtualhosts.");
+ final String configKey = StringUtils.substringAfter(_vhostStoreConfigKeyPrefix + configKeySuffix, "virtualhosts.");
return configKey;
}
@@ -135,7 +138,6 @@ public class HATestClusterCreator
{
final BrokerConfigHolder brokerConfigHolder = _brokerConfigurations.get(brokerPortNumber);
- _testcase.setTestConfiguration(brokerConfigHolder.getTestConfiguration());
_testcase.setTestVirtualhosts(brokerConfigHolder.getTestVirtualhosts());
_testcase.startBroker(brokerPortNumber);
@@ -204,7 +206,7 @@ public class HATestClusterCreator
public void stopNode(final int brokerPortNumber)
{
- _testcase.stopBroker(brokerPortNumber);
+ _testcase.killBroker(brokerPortNumber);
}
public void stopCluster() throws Exception
@@ -348,12 +350,12 @@ public class HATestClusterCreator
{
final String nodeName = getNodeNameForNodeAt(bdbPort);
- _testcase.setConfigurationProperty(_storeConfigKeyPrefix + "class", "org.apache.qpid.server.store.berkeleydb.BDBHAMessageStore");
+ _testcase.setVirtualHostConfigurationProperty(_vhostStoreConfigKeyPrefix + "class", "org.apache.qpid.server.store.berkeleydb.BDBHAMessageStore");
- _testcase.setConfigurationProperty(_storeConfigKeyPrefix + "highAvailability.groupName", _groupName);
- _testcase.setConfigurationProperty(_storeConfigKeyPrefix + "highAvailability.nodeName", nodeName);
- _testcase.setConfigurationProperty(_storeConfigKeyPrefix + "highAvailability.nodeHostPort", getNodeHostPortForNodeAt(bdbPort));
- _testcase.setConfigurationProperty(_storeConfigKeyPrefix + "highAvailability.helperHostPort", getHelperHostPort());
+ _testcase.setVirtualHostConfigurationProperty(_vhostStoreConfigKeyPrefix + "highAvailability.groupName", _groupName);
+ _testcase.setVirtualHostConfigurationProperty(_vhostStoreConfigKeyPrefix + "highAvailability.nodeName", nodeName);
+ _testcase.setVirtualHostConfigurationProperty(_vhostStoreConfigKeyPrefix + "highAvailability.nodeHostPort", getNodeHostPortForNodeAt(bdbPort));
+ _testcase.setVirtualHostConfigurationProperty(_vhostStoreConfigKeyPrefix + "highAvailability.helperHostPort", getHelperHostPort());
}
public String getIpAddressOfBrokerHost()
@@ -369,24 +371,24 @@ public class HATestClusterCreator
}
}
- private void collectConfig(final int brokerPortNumber, XMLConfiguration testConfiguration, XMLConfiguration testVirtualhosts)
+ private void collectConfig(final int brokerPortNumber, TestBrokerConfiguration testConfiguration, XMLConfiguration testVirtualhosts)
{
- _brokerConfigurations.put(brokerPortNumber, new BrokerConfigHolder((XMLConfiguration) testConfiguration.clone(),
+ _brokerConfigurations.put(brokerPortNumber, new BrokerConfigHolder(testConfiguration,
(XMLConfiguration) testVirtualhosts.clone()));
}
public class BrokerConfigHolder
{
- private final XMLConfiguration _testConfiguration;
+ private final TestBrokerConfiguration _testConfiguration;
private final XMLConfiguration _testVirtualhosts;
- public BrokerConfigHolder(XMLConfiguration testConfiguration, XMLConfiguration testVirtualhosts)
+ public BrokerConfigHolder(TestBrokerConfiguration testConfiguration, XMLConfiguration testVirtualhosts)
{
_testConfiguration = testConfiguration;
_testVirtualhosts = testVirtualhosts;
}
- public XMLConfiguration getTestConfiguration()
+ public TestBrokerConfiguration getTestConfiguration()
{
return _testConfiguration;
}
@@ -416,7 +418,7 @@ public class HATestClusterCreator
public String getStoreConfigKeyPrefix()
{
- return _storeConfigKeyPrefix;
+ return _vhostStoreConfigKeyPrefix;
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageStoreCreatorTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageStoreCreatorTest.java
new file mode 100644
index 0000000000..d33eb868c2
--- /dev/null
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageStoreCreatorTest.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.berkeleydb;
+
+import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.MessageStoreCreator;
+import org.apache.qpid.server.store.berkeleydb.BDBHAMessageStore;
+import org.apache.qpid.server.store.berkeleydb.BDBMessageStore;
+import org.apache.qpid.server.store.derby.DerbyMessageStore;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class MessageStoreCreatorTest extends QpidTestCase
+{
+ private static final String[] STORE_TYPES = {MemoryMessageStore.TYPE, DerbyMessageStore.TYPE, BDBMessageStore.TYPE, BDBHAMessageStore.TYPE};
+
+ public void testMessageStoreCreator()
+ {
+ MessageStoreCreator messageStoreCreator = new MessageStoreCreator();
+ for (String type : STORE_TYPES)
+ {
+ MessageStore store = messageStoreCreator.createMessageStore(type);
+ assertNotNull("Store of type " + type + " is not created", store);
+ }
+ }
+}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java
index cd2654f79f..b2b28b3c2d 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java
@@ -20,7 +20,14 @@
*/
package org.apache.qpid.server.store.berkeleydb.upgrade;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.NONEXCLUSIVE_WITH_ERRONEOUS_OWNER;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.NON_DURABLE_QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.PRIORITY_QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_WITH_DLQ_NAME;
+
import java.io.File;
+import java.io.InputStream;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.subjects.TestBlankSubject;
@@ -51,15 +58,15 @@ public abstract class AbstractUpgradeTestCase extends QpidTestCase
}
}
- public static final String[] QUEUE_NAMES = { "clientid:myDurSubName", "clientid:mySelectorDurSubName", "myUpgradeQueue",
- "queue-non-durable", "nonexclusive-with-erroneous-owner" };
- public static int[] QUEUE_SIZES = { 1, 1, 10, 3, 0};
- public static int TOTAL_MESSAGE_NUMBER = 15;
+ public static final String[] QUEUE_NAMES = { "clientid:myDurSubName", "clientid:mySelectorDurSubName", QUEUE_NAME, NON_DURABLE_QUEUE_NAME,
+ NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, PRIORITY_QUEUE_NAME, QUEUE_WITH_DLQ_NAME, QUEUE_WITH_DLQ_NAME + "_DLQ" };
+ public static int[] QUEUE_SIZES = { 1, 1, 10, 3, 0, 0, 0, 1};
+ public static int TOTAL_MESSAGE_NUMBER = 16;
protected static final LogSubject LOG_SUBJECT = new TestBlankSubject();
- // one binding per exchange
- protected static final int TOTAL_BINDINGS = QUEUE_NAMES.length * 2;
- protected static final int TOTAL_EXCHANGES = 5;
+ // myQueueWithDLQ_DLQ is not bound to the default exchange
+ protected static final int TOTAL_BINDINGS = QUEUE_NAMES.length * 2 - 1;
+ protected static final int TOTAL_EXCHANGES = 6;
private File _storeLocation;
protected Environment _environment;
@@ -105,10 +112,24 @@ public abstract class AbstractUpgradeTestCase extends QpidTestCase
private File copyStore(String storeDirectoryName) throws Exception
{
- String src = getClass().getClassLoader().getResource("upgrade/" + storeDirectoryName).toURI().getPath();
File storeLocation = new File(new File(TMP_FOLDER), "test-store");
deleteDirectoryIfExists(storeLocation);
- FileUtils.copyRecursive(new File(src), new File(TMP_FOLDER));
+ storeLocation.mkdirs();
+ int index = 0;
+ String prefix = "0000000";
+ String extension = ".jdb";
+ InputStream is = null;
+ do
+ {
+ String fileName = prefix + index + extension;
+ is = getClass().getClassLoader().getResourceAsStream("upgrade/" + storeDirectoryName + "/test-store/" + fileName);
+ if (is != null)
+ {
+ FileUtils.copy(is, new File(storeLocation, fileName));
+ }
+ index++;
+ }
+ while (is != null);
return storeLocation;
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java
index 65a8bb03fb..500fb0a919 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java
@@ -20,6 +20,13 @@
*/
package org.apache.qpid.server.store.berkeleydb.upgrade;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.NONEXCLUSIVE_WITH_ERRONEOUS_OWNER;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.NON_DURABLE_QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_WITH_DLQ_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.SELECTOR_TOPIC_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.TOPIC_NAME;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -34,7 +41,6 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom4To5.BindingRecord;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom4To5.BindingTuple;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom4To5.MessageContentKey;
@@ -50,9 +56,6 @@ import com.sleepycat.je.Transaction;
public class UpgradeFrom4to5Test extends AbstractUpgradeTestCase
{
- private static final String NON_DURABLE_QUEUE = BDBStoreUpgradeTestPreparer.NON_DURABLE_QUEUE_NAME;
- private static final String DURABLE_QUEUE = BDBStoreUpgradeTestPreparer.QUEUE_NAME;
- private static final String NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER = "nonexclusive-with-erroneous-owner";
private static final String DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR = "clientid:mySelectorDurSubName";
private static final String DURABLE_SUBSCRIPTION_QUEUE = "clientid:myDurSubName";
private static final String EXCHANGE_DB_NAME = "exchangeDb_v5";
@@ -85,15 +88,14 @@ public class UpgradeFrom4to5Test extends AbstractUpgradeTestCase
final List<BindingRecord> queueBindings = loadBindings();
- assertEquals("Unxpected list size", TOTAL_BINDINGS, queueBindings.size());
- assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE, "amq.topic", BDBStoreUpgradeTestPreparer.TOPIC_NAME, "");
- assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR, "amq.topic",
- BDBStoreUpgradeTestPreparer.SELECTOR_TOPIC_NAME, "testprop='true'");
- assertBindingRecord(queueBindings, DURABLE_QUEUE, "amq.direct", DURABLE_QUEUE, null);
- assertBindingRecord(queueBindings, NON_DURABLE_QUEUE, "amq.direct", NON_DURABLE_QUEUE, null);
- assertBindingRecord(queueBindings, NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER, "amq.direct", NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER, null);
+ assertEquals("Unxpected bindings size", TOTAL_BINDINGS, queueBindings.size());
+ assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE, "amq.topic", TOPIC_NAME, "");
+ assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR, "amq.topic", SELECTOR_TOPIC_NAME, "testprop='true'");
+ assertBindingRecord(queueBindings, QUEUE_NAME, "amq.direct", QUEUE_NAME, null);
+ assertBindingRecord(queueBindings, NON_DURABLE_QUEUE_NAME, "amq.direct", NON_DURABLE_QUEUE_NAME, null);
+ assertBindingRecord(queueBindings, NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, "amq.direct", NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, null);
- assertQueueHasOwner(NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER, "misused-owner-as-description");
+ assertQueueHasOwner(NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, "misused-owner-as-description");
assertContent();
}
@@ -102,26 +104,29 @@ public class UpgradeFrom4to5Test extends AbstractUpgradeTestCase
{
UpgradeFrom4To5 upgrade = new UpgradeFrom4To5();
upgrade.performUpgrade(_environment, new StaticAnswerHandler(UpgradeInteractionResponse.NO), getVirtualHostName());
- assertQueues(new HashSet<String>(Arrays.asList(DURABLE_SUBSCRIPTION_QUEUE, DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR, DURABLE_QUEUE, NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER)));
+ HashSet<String> queues = new HashSet<String>(Arrays.asList(QUEUE_NAMES));
+ assertTrue(NON_DURABLE_QUEUE_NAME + " should be in the list of queues" , queues.remove(NON_DURABLE_QUEUE_NAME));
+
+ assertQueues(queues);
- assertDatabaseRecordCount(DELIVERY_DB_NAME, 12);
- assertDatabaseRecordCount(MESSAGE_META_DATA_DB_NAME, 12);
+ assertDatabaseRecordCount(DELIVERY_DB_NAME, 13);
+ assertDatabaseRecordCount(MESSAGE_META_DATA_DB_NAME, 13);
assertDatabaseRecordCount(EXCHANGE_DB_NAME, TOTAL_EXCHANGES);
assertQueueMessages(DURABLE_SUBSCRIPTION_QUEUE, 1);
assertQueueMessages(DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR, 1);
- assertQueueMessages(DURABLE_QUEUE, 10);
+ assertQueueMessages(QUEUE_NAME, 10);
+ assertQueueMessages(QUEUE_WITH_DLQ_NAME + "_DLQ", 1);
final List<BindingRecord> queueBindings = loadBindings();
assertEquals("Unxpected list size", TOTAL_BINDINGS - 2, queueBindings.size());
- assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE, "amq.topic", BDBStoreUpgradeTestPreparer.TOPIC_NAME,
- "");
+ assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE, "amq.topic", TOPIC_NAME, "");
assertBindingRecord(queueBindings, DURABLE_SUBSCRIPTION_QUEUE_WITH_SELECTOR, "amq.topic",
- BDBStoreUpgradeTestPreparer.SELECTOR_TOPIC_NAME, "testprop='true'");
- assertBindingRecord(queueBindings, DURABLE_QUEUE, "amq.direct", DURABLE_QUEUE, null);
+ SELECTOR_TOPIC_NAME, "testprop='true'");
+ assertBindingRecord(queueBindings, QUEUE_NAME, "amq.direct", QUEUE_NAME, null);
- assertQueueHasOwner(NON_EXCLUSIVE_WITH_ERRONEOUS_OWNER, "misused-owner-as-description");
+ assertQueueHasOwner(NONEXCLUSIVE_WITH_ERRONEOUS_OWNER, "misused-owner-as-description");
assertContent();
}
diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java
index 2d2a6b20a2..c33d427868 100644
--- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java
+++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.store.berkeleydb.upgrade;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.PRIORITY_QUEUE_NAME;
+import static org.apache.qpid.server.store.berkeleydb.BDBStoreUpgradeTestPreparer.QUEUE_WITH_DLQ_NAME;
import static org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.CONFIGURED_OBJECTS_DB_NAME;
import static org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NEW_CONTENT_DB_NAME;
import static org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NEW_DELIVERY_DB_NAME;
@@ -42,6 +44,7 @@ import java.util.UUID;
import org.apache.log4j.Logger;
import org.apache.qpid.server.model.Binding;
import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -50,7 +53,6 @@ import org.apache.qpid.server.store.berkeleydb.tuple.XidBinding;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.CompoundKey;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.CompoundKeyBinding;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.ConfiguredObjectBinding;
-import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.UpgradeConfiguredObjectRecord;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NewDataBinding;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NewPreparedTransaction;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NewPreparedTransactionBinding;
@@ -60,6 +62,7 @@ import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.NewRecord
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.OldPreparedTransaction;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.OldPreparedTransactionBinding;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.OldRecordImpl;
+import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.UpgradeConfiguredObjectRecord;
import org.apache.qpid.server.store.berkeleydb.upgrade.UpgradeFrom5To6.UpgradeUUIDBinding;
import org.apache.qpid.server.util.MapJsonSerializer;
@@ -115,8 +118,8 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
upgrade.performUpgrade(_environment, discardMessageInteractionHandler, getVirtualHostName());
- assertDatabaseRecordCount(NEW_METADATA_DB_NAME, 11);
- assertDatabaseRecordCount(NEW_CONTENT_DB_NAME, 11);
+ assertDatabaseRecordCount(NEW_METADATA_DB_NAME, 12);
+ assertDatabaseRecordCount(NEW_CONTENT_DB_NAME, 12);
assertConfiguredObjects();
assertQueueEntries();
@@ -264,17 +267,17 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
private void assertDatabaseRecordCounts()
{
- assertDatabaseRecordCount(CONFIGURED_OBJECTS_DB_NAME, 12);
- assertDatabaseRecordCount(NEW_DELIVERY_DB_NAME, 12);
+ assertDatabaseRecordCount(CONFIGURED_OBJECTS_DB_NAME, 21);
+ assertDatabaseRecordCount(NEW_DELIVERY_DB_NAME, 13);
- assertDatabaseRecordCount(NEW_METADATA_DB_NAME, 12);
- assertDatabaseRecordCount(NEW_CONTENT_DB_NAME, 12);
+ assertDatabaseRecordCount(NEW_METADATA_DB_NAME, 13);
+ assertDatabaseRecordCount(NEW_CONTENT_DB_NAME, 13);
}
private void assertConfiguredObjects()
{
Map<UUID, UpgradeConfiguredObjectRecord> configuredObjects = loadConfiguredObjects();
- assertEquals("Unexpected number of configured objects", 12, configuredObjects.size());
+ assertEquals("Unexpected number of configured objects", 21, configuredObjects.size());
Set<Map<String, Object>> expected = new HashSet<Map<String, Object>>(12);
List<UUID> expectedBindingIDs = new ArrayList<UUID>();
@@ -282,8 +285,26 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
expected.add(createExpectedQueueMap("myUpgradeQueue", Boolean.FALSE, null, null));
expected.add(createExpectedQueueMap("clientid:mySelectorDurSubName", Boolean.TRUE, "clientid", null));
expected.add(createExpectedQueueMap("clientid:myDurSubName", Boolean.TRUE, "clientid", null));
- expected.add(createExpectedQueueMap("nonexclusive-with-erroneous-owner", Boolean.FALSE, null,
- Collections.singletonMap(AMQQueueFactory.X_QPID_DESCRIPTION, "misused-owner-as-description")));
+
+ final Map<String, Object> queueWithOwnerArguments = new HashMap<String, Object>();
+ queueWithOwnerArguments.put("x-qpid-priorities", 10);
+ queueWithOwnerArguments.put(AMQQueueFactory.X_QPID_DESCRIPTION, "misused-owner-as-description");
+ expected.add(createExpectedQueueMap("nonexclusive-with-erroneous-owner", Boolean.FALSE, null,queueWithOwnerArguments));
+
+ final Map<String, Object> priorityQueueArguments = new HashMap<String, Object>();
+ priorityQueueArguments.put("x-qpid-priorities", 10);
+ expected.add(createExpectedQueueMap(PRIORITY_QUEUE_NAME, Boolean.FALSE, null, priorityQueueArguments));
+
+ final Map<String, Object> queueWithDLQArguments = new HashMap<String, Object>();
+ queueWithDLQArguments.put("x-qpid-dlq-enabled", true);
+ queueWithDLQArguments.put("x-qpid-maximum-delivery-count", 2);
+ expected.add(createExpectedQueueMap(QUEUE_WITH_DLQ_NAME, Boolean.FALSE, null, queueWithDLQArguments));
+
+ final Map<String, Object> dlqArguments = new HashMap<String, Object>();
+ dlqArguments.put("x-qpid-dlq-enabled", false);
+ dlqArguments.put("x-qpid-maximum-delivery-count", 0);
+ expected.add(createExpectedQueueMap(QUEUE_WITH_DLQ_NAME + "_DLQ", Boolean.FALSE, null, dlqArguments));
+ expected.add(createExpectedExchangeMap(QUEUE_WITH_DLQ_NAME + "_DLE", "fanout"));
expected.add(createExpectedQueueBindingMapAndID("myUpgradeQueue","myUpgradeQueue", "<<default>>", null, expectedBindingIDs));
expected.add(createExpectedQueueBindingMapAndID("myUpgradeQueue", "myUpgradeQueue", "amq.direct", null, expectedBindingIDs));
@@ -296,6 +317,13 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
expected.add(createExpectedQueueBindingMapAndID("nonexclusive-with-erroneous-owner", "nonexclusive-with-erroneous-owner", "amq.direct", null, expectedBindingIDs));
expected.add(createExpectedQueueBindingMapAndID("nonexclusive-with-erroneous-owner","nonexclusive-with-erroneous-owner", "<<default>>", null, expectedBindingIDs));
+ expected.add(createExpectedQueueBindingMapAndID(PRIORITY_QUEUE_NAME, PRIORITY_QUEUE_NAME, "<<default>>", null, expectedBindingIDs));
+ expected.add(createExpectedQueueBindingMapAndID(PRIORITY_QUEUE_NAME, PRIORITY_QUEUE_NAME, "amq.direct", null, expectedBindingIDs));
+
+ expected.add(createExpectedQueueBindingMapAndID(QUEUE_WITH_DLQ_NAME, QUEUE_WITH_DLQ_NAME, "<<default>>", null, expectedBindingIDs));
+ expected.add(createExpectedQueueBindingMapAndID(QUEUE_WITH_DLQ_NAME, QUEUE_WITH_DLQ_NAME, "amq.direct", null, expectedBindingIDs));
+ expected.add(createExpectedQueueBindingMapAndID(QUEUE_WITH_DLQ_NAME + "_DLQ", "dlq", QUEUE_WITH_DLQ_NAME + "_DLE", null, expectedBindingIDs));
+
Set<String> expectedTypes = new HashSet<String>();
expectedTypes.add(Queue.class.getName());
expectedTypes.add(Exchange.class.getName());
@@ -305,7 +333,9 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
{
UpgradeConfiguredObjectRecord object = entry.getValue();
Map<String, Object> deserialized = jsonSerializer.deserialize(object.getAttributes());
- assertTrue("Unexpected entry:" + object.getAttributes(), expected.remove(deserialized));
+
+ assertTrue("Unexpected entry in a store - json [" + object.getAttributes() + "], map [" + deserialized + "]",
+ expected.remove(deserialized));
String type = object.getType();
assertTrue("Unexpected type:" + type, expectedTypes.contains(type));
UUID key = entry.getKey();
@@ -350,7 +380,7 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
return expectedQueueBinding;
}
- private Map<String, Object> createExpectedQueueMap(String name, boolean exclusiveFlag, String owner, Map<String, String> argumentMap)
+ private Map<String, Object> createExpectedQueueMap(String name, boolean exclusiveFlag, String owner, Map<String, Object> argumentMap)
{
Map<String, Object> expectedQueueEntry = new HashMap<String, Object>();
expectedQueueEntry.put(Queue.NAME, name);
@@ -363,6 +393,15 @@ public class UpgradeFrom5To6Test extends AbstractUpgradeTestCase
return expectedQueueEntry;
}
+ private Map<String, Object> createExpectedExchangeMap(String name, String type)
+ {
+ Map<String, Object> expectedExchnageEntry = new HashMap<String, Object>();
+ expectedExchnageEntry.put(Exchange.NAME, name);
+ expectedExchnageEntry.put(Exchange.TYPE, type);
+ expectedExchnageEntry.put(Exchange.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name());
+ return expectedExchnageEntry;
+ }
+
private Map<UUID, UpgradeConfiguredObjectRecord> loadConfiguredObjects()
{
final Map<UUID, UpgradeConfiguredObjectRecord> configuredObjectsRecords = new HashMap<UUID, UpgradeConfiguredObjectRecord>();
diff --git a/java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdb b/java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdb
index f5ed9aa5a2..cfc1f05d28 100644
--- a/java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdb
+++ b/java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdb
Binary files differ
diff --git a/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdb b/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdb
index f5ed9aa5a2..cfc1f05d28 100644
--- a/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdb
+++ b/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdb
Binary files differ
diff --git a/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdb b/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdb
index d5ae8c1096..4b45ff61e6 100644
--- a/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdb
+++ b/java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdb
Binary files differ
diff --git a/java/broker-plugins/access-control/MANIFEST.MF b/java/broker-plugins/access-control/MANIFEST.MF
deleted file mode 100644
index a8fb99995e..0000000000
--- a/java/broker-plugins/access-control/MANIFEST.MF
+++ /dev/null
@@ -1,41 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Access Control
-Bundle-SymbolicName: broker-plugins-access-control
-Bundle-Description: Access control plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://qpid.apache.org/acl.html
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.security.access.plugins.AccessControlActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.5
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.exchange,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.logging.actors,
- org.apache.qpid.server.logging.subjects,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- javax.security.auth;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.security.access.config,
- org.apache.qpid.server.security.access.logging
-Export-Package: org.apache.qpid.server.security.access.plugins
diff --git a/java/broker-plugins/access-control/build.xml b/java/broker-plugins/access-control/build.xml
index df3346788c..4debdcb95a 100644
--- a/java/broker-plugins/access-control/build.xml
+++ b/java/broker-plugins/access-control/build.xml
@@ -18,13 +18,13 @@
-->
<project name="Qpid Broker-Plugins Access Control" default="build">
<property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test common/test broker/test management/common systests" />
+ <property name="module.test.depends" value="common/tests broker/tests management/common" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
+ <property name="broker.plugin" value="true"/>
+
<property name="broker-plugins-access-control.libs" value=""/>
<import file="../../module.xml" />
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
index f04dd38aca..f87374ac80 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
@@ -22,13 +22,8 @@ package org.apache.qpid.server.security.access.config;
import java.io.File;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-
public abstract class AbstractConfiguration implements ConfigurationFile
{
- private static final Logger _logger = Logger.getLogger(ConfigurationFile.class);
-
private File _file;
private RuleSet _config;
@@ -42,7 +37,7 @@ public abstract class AbstractConfiguration implements ConfigurationFile
return _file;
}
- public RuleSet load() throws ConfigurationException
+ public RuleSet load()
{
_config = new RuleSet();
return _config;
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
new file mode 100644
index 0000000000..e4bf21a082
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
@@ -0,0 +1,102 @@
+/*
+ * 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.access.config;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+public class AclAction
+{
+ private Action _action;
+ private FirewallRule _firewallRule;
+
+ public AclAction(Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ _action = new Action(operation, object, predicates.getObjectProperties());
+ _firewallRule = predicates.getFirewallRule();
+ }
+
+ public AclAction(Operation operation)
+ {
+ _action = new Action(operation);
+ }
+
+ public AclAction(Operation operation, ObjectType object, ObjectProperties properties)
+ {
+ _action = new Action(operation, object, properties);
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public Action getAction()
+ {
+ return _action;
+ }
+
+ public boolean isAllowed()
+ {
+ return _action.isAllowed();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder()
+ .append(_action)
+ .append(_firewallRule).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ AclAction rhs = (AclAction) obj;
+ return new EqualsBuilder()
+ .append(_action, rhs._action)
+ .append(_firewallRule, rhs._firewallRule).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_action)
+ .append(_firewallRule).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
new file mode 100644
index 0000000000..45af85be6c
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
@@ -0,0 +1,102 @@
+/*
+ * 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.access.config;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectProperties.Property;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+/**
+ * Represents the predicates on an ACL rule by combining predicates relating to the object being operated on
+ * (e.g. name=foo) with firewall rules.
+ */
+public class AclRulePredicates
+{
+ private static final Logger _logger = Logger.getLogger(AclRulePredicates.class);
+
+ private static final String SEPARATOR = ",";
+
+ private ObjectProperties _properties = new ObjectProperties();
+
+ private FirewallRule _firewallRule;
+
+ private FirewallRuleFactory _firewallRuleFactory = new FirewallRuleFactory();
+
+ public void parse(String key, String value)
+ {
+ ObjectProperties.Property property = ObjectProperties.Property.parse(key);
+
+ if(property == Property.FROM_HOSTNAME)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForHostname(value.split(SEPARATOR));
+ }
+ else if(property == Property.FROM_NETWORK)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForNetwork(value.split(SEPARATOR));
+ }
+ else
+ {
+ _properties.put(property, value);
+ }
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Parsed " + property + " with value " + value);
+ }
+ }
+
+ private void checkFirewallRuleNotAlreadyDefined(String key, String value)
+ {
+ if(_firewallRule != null)
+ {
+ throw new IllegalStateException(
+ "Cannot parse " + key + "=" + value
+ + " because firewall rule " + _firewallRule + " has already been defined");
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_properties)
+ .append(_firewallRule).toString();
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public ObjectProperties getObjectProperties()
+ {
+ return _properties;
+ }
+
+ void setFirewallRuleFactory(FirewallRuleFactory firewallRuleFactory)
+ {
+ _firewallRuleFactory = firewallRuleFactory;
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
index b887d1e079..4fff0bebf5 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.security.access.config;
-import java.util.Comparator;
-
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
@@ -32,7 +30,7 @@ import org.apache.qpid.server.security.access.Operation;
/**
* An access control v2 rule action.
- *
+ *
* An action consists of an {@link Operation} on an {@link ObjectType} with certain properties, stored in a {@link java.util.Map}.
* The operation and object should be an allowable combination, based on the {@link ObjectType#isAllowed(Operation)}
* method of the object, which is exposed as the {@link #isAllowed()} method here. The internal {@link #propertiesMatch(Map)}
@@ -45,104 +43,96 @@ import org.apache.qpid.server.security.access.Operation;
*/
public class Action
{
- private Operation _operation;
- private ObjectType _object;
- private ObjectProperties _properties;
-
+ private final Operation _operation;
+ private final ObjectType _object;
+ private final ObjectProperties _properties;
+
public Action(Operation operation)
{
this(operation, ObjectType.ALL);
}
-
+
public Action(Operation operation, ObjectType object, String name)
{
this(operation, object, new ObjectProperties(name));
}
-
+
public Action(Operation operation, ObjectType object)
{
this(operation, object, ObjectProperties.EMPTY);
}
-
+
public Action(Operation operation, ObjectType object, ObjectProperties properties)
{
- setOperation(operation);
- setObjectType(object);
- setProperties(properties);
+ _operation = operation;
+ _object = object;
+ _properties = properties;
}
-
+
public Operation getOperation()
{
return _operation;
}
- public void setOperation(Operation operation)
- {
- _operation = operation;
- }
-
public ObjectType getObjectType()
{
return _object;
}
- public void setObjectType(ObjectType object)
- {
- _object = object;
- }
-
public ObjectProperties getProperties()
{
return _properties;
}
-
- public void setProperties(ObjectProperties properties)
- {
- _properties = properties;
- }
-
+
public boolean isAllowed()
{
return _object.isAllowed(_operation);
}
- /** @see Comparable#compareTo(Object) */
public boolean matches(Action a)
{
- return ((Operation.ALL == a.getOperation() || getOperation() == a.getOperation())
- && (ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType())
- && _properties.matches(a.getProperties()));
+ if (!operationsMatch(a))
+ {
+ return false;
+ }
+
+ if (!objectTypesMatch(a))
+ {
+ return false;
+ }
+
+ if (!propertiesMatch(a))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean operationsMatch(Action a)
+ {
+ return Operation.ALL == a.getOperation() || getOperation() == a.getOperation();
}
- /**
- * An ordering based on specificity
- *
- * @see Comparator#compare(Object, Object)
- */
- public class Specificity implements Comparator<Action>
+ private boolean objectTypesMatch(Action a)
{
- public int compare(Action a, Action b)
+ return ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType();
+ }
+
+ private boolean propertiesMatch(Action a)
+ {
+ boolean propertiesMatch = false;
+ if (_properties != null)
+ {
+ propertiesMatch = _properties.matches(a.getProperties());
+ }
+ else if (a.getProperties() == null)
{
- if (a.getOperation() == Operation.ALL && b.getOperation() != Operation.ALL)
- {
- return 1; // B is more specific
- }
- else if (b.getOperation() == Operation.ALL && a.getOperation() != Operation.ALL)
- {
- return 1; // A is more specific
- }
- else if (a.getOperation() == b.getOperation())
- {
- return 1; // b is more specific
- }
- else // Different operations
- {
- return a.getOperation().compareTo(b.getOperation()); // Arbitrary
- }
+ propertiesMatch = true;
}
+ return propertiesMatch;
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -151,26 +141,24 @@ public class Action
return false;
}
Action a = (Action) o;
-
+
return new EqualsBuilder()
.append(_operation, a.getOperation())
.append(_object, a.getObjectType())
- .appendSuper(_properties.equals(a.getProperties()))
+ .append(_properties, a.getProperties())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(_operation)
- .append(_operation)
+ .append(_object)
.append(_properties)
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
new file mode 100644
index 0000000000..fed20a56c8
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
@@ -0,0 +1,88 @@
+/*
+ * 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.access.config;
+
+import java.net.InetAddress;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+/**
+ * I represent an {@link Action} taken by a client from a known address. The address is used to
+ * determine if I match an {@link AclAction}, which may contain firewall rules.
+ */
+public class ClientAction
+{
+ private Action _clientAction;
+
+ public ClientAction(Action clientAction)
+ {
+ _clientAction = clientAction;
+ }
+
+ public ClientAction(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ _clientAction = new Action(operation, objectType, properties);
+ }
+
+ public boolean matches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ return _clientAction.matches(ruleAction.getAction())
+ && addressOfClientMatches(ruleAction, addressOfClient);
+ }
+
+ private boolean addressOfClientMatches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ FirewallRule firewallRule = ruleAction.getFirewallRule();
+ if(firewallRule == null || addressOfClient == null)
+ {
+ return true;
+ }
+ else
+ {
+ return firewallRule.matches(addressOfClient);
+ }
+ }
+
+ public Operation getOperation()
+ {
+ return _clientAction.getOperation();
+ }
+
+ public ObjectType getObjectType()
+ {
+ return _clientAction.getObjectType();
+ }
+
+ public ObjectProperties getProperties()
+ {
+ return _clientAction.getProperties();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_clientAction).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
index 8b1a00259b..966c32e24e 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.security.access.config;
import java.io.File;
-import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
public interface ConfigurationFile
{
@@ -33,19 +33,17 @@ public interface ConfigurationFile
/**
* Load this configuration file's contents into a {@link RuleSet}.
- *
- * @throws ConfigurationException if the configuration file has errors.
+ * @throws IllegalConfigurationException if the configuration file has errors.
* @throws IllegalArgumentException if individual tokens cannot be parsed.
*/
- RuleSet load() throws ConfigurationException;
+ RuleSet load() throws IllegalConfigurationException;
/**
* Reload this configuration file's contents.
- *
- * @throws ConfigurationException if the configuration file has errors.
+ * @throws IllegalConfigurationException if the configuration file has errors.
* @throws IllegalArgumentException if individual tokens cannot be parsed.
*/
- RuleSet reload() throws ConfigurationException;
+ RuleSet reload() throws IllegalConfigurationException;
RuleSet getConfiguration();
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
index 9a08eb6499..ab309c54ce 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
@@ -1,5 +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
@@ -7,16 +7,16 @@
* 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.access.config;
@@ -32,55 +32,65 @@ import java.util.List;
import java.util.Map;
import java.util.Stack;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.lang.StringUtils;
-import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
public class PlainConfiguration extends AbstractConfiguration
{
+ private static final Logger _logger = Logger.getLogger(PlainConfiguration.class);
+
public static final Character COMMENT = '#';
public static final Character CONTINUATION = '\\';
- public static final String GROUP = "group";
public static final String ACL = "acl";
public static final String CONFIG = "config";
- public static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d";
- public static final String NOT_ENOUGH_TOKENS_MSG = "Not enough tokens at line %d";
- public static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d";
- public static final String CANNOT_LOAD_MSG = "Cannot load config file %s";
- public static final String PREMATURE_CONTINUATION_MSG = "Premature continuation character at line %d";
- public static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d";
- public static final String PARSE_TOKEN_FAILED_MSG = "Failed to parse token at line %d";
- public static final String CONFIG_NOT_FOUND_MSG = "Cannot find config file %s";
- public static final String NOT_ENOUGH_GROUP_MSG = "Not enough data for a group at line %d";
- public static final String NOT_ENOUGH_ACL_MSG = "Not enough data for an acl at line %d";
- public static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d";
- public static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d";
- public static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d";
- public static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d";
- public static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d";
-
+ static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d";
+ static final String NOT_ENOUGH_TOKENS_MSG = "Not enough tokens at line %d";
+ static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d";
+ static final String CANNOT_LOAD_MSG = "Cannot load config file %s";
+ static final String CANNOT_CLOSE_MSG = "Cannot close config file %s";
+ static final String PREMATURE_CONTINUATION_MSG = "Premature continuation character at line %d";
+ static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d";
+ static final String PARSE_TOKEN_FAILED_MSG = "Failed to parse token at line %d";
+ static final String CONFIG_NOT_FOUND_MSG = "Cannot find config file %s";
+ static final String NOT_ENOUGH_ACL_MSG = "Not enough data for an acl at line %d";
+ static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d";
+ static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d";
+ static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d";
+ static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d";
+ static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d";
+
private StreamTokenizer _st;
public PlainConfiguration(File file)
{
super(file);
}
-
+
@Override
- public RuleSet load() throws ConfigurationException
+ public RuleSet load()
{
RuleSet ruleSet = super.load();
-
+
+ File file = getFile();
+ FileReader fileReader = null;
+
try
{
- _st = new StreamTokenizer(new BufferedReader(new FileReader(getFile())));
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("About to load ACL file " + file);
+ }
+
+ fileReader = new FileReader(file);
+ _st = new StreamTokenizer(new BufferedReader(fileReader));
_st.resetSyntax(); // setup the tokenizer
-
+
_st.commentChar(COMMENT); // single line comments
_st.eolIsSignificant(true); // return EOL as a token
_st.ordinaryChar('='); // equals is a token
@@ -97,7 +107,7 @@ public class PlainConfiguration extends AbstractConfiguration
_st.wordChars('*', '*'); // star
_st.wordChars('@', '@'); // at
_st.wordChars(':', ':'); // colon
-
+
// parse the acl file lines
Stack<String> stack = new Stack<String>();
int current;
@@ -111,21 +121,21 @@ public class PlainConfiguration extends AbstractConfiguration
{
break; // blank line
}
-
+
// pull out the first token from the bottom of the stack and check arguments exist
String first = stack.firstElement();
stack.removeElementAt(0);
if (stack.isEmpty())
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, getLine()));
}
-
+
// check for and parse optional initial number for ACL lines
Integer number = null;
if (StringUtils.isNumeric(first))
{
// set the acl number and get the next element
- number = Integer.valueOf(first);
+ number = Integer.valueOf(first);
first = stack.firstElement();
stack.removeElementAt(0);
}
@@ -136,9 +146,9 @@ public class PlainConfiguration extends AbstractConfiguration
}
else if (number == null)
{
- if (StringUtils.equalsIgnoreCase(GROUP, first))
+ if(StringUtils.equalsIgnoreCase("GROUP", first))
{
- parseGroup(stack);
+ throw new IllegalConfigurationException(String.format("GROUP keyword not supported. Groups should defined via a Group Provider, not in the ACL file.", getLine()));
}
else if (StringUtils.equalsIgnoreCase(CONFIG, first))
{
@@ -146,14 +156,14 @@ public class PlainConfiguration extends AbstractConfiguration
}
else
{
- throw new ConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, getLine()));
+ throw new IllegalConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, getLine()));
}
}
else
{
- throw new ConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, getLine()));
+ throw new IllegalConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, getLine()));
}
-
+
// reset stack, start next line
stack.clear();
break;
@@ -171,9 +181,9 @@ public class PlainConfiguration extends AbstractConfiguration
{
break; // continue reading next line
}
-
+
// invalid location for continuation character (add one to line beacuse we ate the EOL)
- throw new ConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, getLine() + 1));
+ throw new IllegalConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, getLine() + 1));
}
else if (_st.ttype == '\'' || _st.ttype == '"')
{
@@ -185,54 +195,59 @@ public class PlainConfiguration extends AbstractConfiguration
}
}
} while (current != StreamTokenizer.TT_EOF);
-
+
if (!stack.isEmpty())
{
- throw new ConfigurationException(String.format(PREMATURE_EOF_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PREMATURE_EOF_MSG, getLine()));
}
}
catch (IllegalArgumentException iae)
{
- throw new ConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, getLine()), iae);
+ throw new IllegalConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, getLine()), iae);
}
catch (FileNotFoundException fnfe)
{
- throw new ConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, getFile().getName()), fnfe);
+ throw new IllegalConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, file.getName()), fnfe);
}
catch (IOException ioe)
{
- throw new ConfigurationException(String.format(CANNOT_LOAD_MSG, getFile().getName()), ioe);
+ throw new IllegalConfigurationException(String.format(CANNOT_LOAD_MSG, file.getName()), ioe);
}
-
- return ruleSet;
- }
-
- private void parseGroup(List<String> args) throws ConfigurationException
- {
- if (args.size() < 2)
+ finally
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_GROUP_MSG, getLine()));
+ if(fileReader != null)
+ {
+ try
+ {
+ fileReader.close();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException(String.format(CANNOT_CLOSE_MSG, file.getName()), e);
+ }
+ }
}
-
- getConfiguration().addGroup(args.get(0), args.subList(1, args.size()));
+
+
+ return ruleSet;
}
-
- private void parseAcl(Integer number, List<String> args) throws ConfigurationException
+
+ private void parseAcl(Integer number, List<String> args)
{
if (args.size() < 3)
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, getLine()));
}
Permission permission = Permission.parse(args.get(0));
String identity = args.get(1);
Operation operation = Operation.parse(args.get(2));
-
+
if (number != null && !getConfiguration().isValidNumber(number))
{
- throw new ConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, getLine()));
}
-
+
if (args.size() == 3)
{
getConfiguration().grant(number, identity, permission, operation);
@@ -240,55 +255,52 @@ public class PlainConfiguration extends AbstractConfiguration
else
{
ObjectType object = ObjectType.parse(args.get(3));
- ObjectProperties properties = toObjectProperties(args.subList(4, args.size()));
+ AclRulePredicates predicates = toRulePredicates(args.subList(4, args.size()));
- getConfiguration().grant(number, identity, permission, operation, object, properties);
+ getConfiguration().grant(number, identity, permission, operation, object, predicates);
}
}
-
- private void parseConfig(List<String> args) throws ConfigurationException
+
+ private void parseConfig(List<String> args)
{
if (args.size() < 3)
{
- throw new ConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, getLine()));
}
Map<String, Boolean> properties = toPluginProperties(args);
-
+
getConfiguration().configure(properties);
}
-
- /** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
- protected ObjectProperties toObjectProperties(List<String> args) throws ConfigurationException
+
+ private AclRulePredicates toRulePredicates(List<String> args)
{
- ObjectProperties properties = new ObjectProperties();
+ AclRulePredicates predicates = new AclRulePredicates();
Iterator<String> i = args.iterator();
while (i.hasNext())
{
String key = i.next();
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
}
if (!"=".equals(i.next()))
{
- throw new ConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
}
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
}
String value = i.next();
-
- // parse property key
- ObjectProperties.Property property = ObjectProperties.Property.parse(key);
- properties.put(property, value);
+
+ predicates.parse(key, value);
}
- return properties;
+ return predicates;
}
-
+
/** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
- protected Map<String, Boolean> toPluginProperties(List<String> args) throws ConfigurationException
+ protected Map<String, Boolean> toPluginProperties(List<String> args)
{
Map<String, Boolean> properties = new HashMap<String, Boolean>();
Iterator<String> i = args.iterator();
@@ -297,24 +309,24 @@ public class PlainConfiguration extends AbstractConfiguration
String key = i.next().toLowerCase();
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine()));
}
if (!"=".equals(i.next()))
{
- throw new ConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine()));
}
if (!i.hasNext())
{
- throw new ConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
+ throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine()));
}
-
+
// parse property value and save
Boolean value = Boolean.valueOf(i.next());
properties.put(key, value);
}
return properties;
}
-
+
protected int getLine()
{
return _st.lineno() - 1;
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
index 15d6b67192..cef9a8696b 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
@@ -29,7 +29,7 @@ import org.apache.qpid.server.security.access.Permission;
/**
* An access control v2 rule.
- *
+ *
* A rule consists of {@link Permission} for a particular identity to perform an {@link Action}. The identity
* may be either a user or a group.
*/
@@ -37,41 +37,41 @@ public class Rule implements Comparable<Rule>
{
/** String indicating all identitied. */
public static final String ALL = "all";
-
+
private Integer _number;
private Boolean _enabled = Boolean.TRUE;
private String _identity;
- private Action _action;
+ private AclAction _action;
private Permission _permission;
-
- public Rule(Integer number, String identity, Action action, Permission permission)
+
+ public Rule(Integer number, String identity, AclAction action, Permission permission)
{
setNumber(number);
setIdentity(identity);
setAction(action);
setPermission(permission);
}
-
- public Rule(String identity, Action action, Permission permission)
+
+ public Rule(String identity, AclAction action, Permission permission)
{
this(null, identity, action, permission);
}
-
+
public boolean isEnabled()
{
return _enabled;
}
-
+
public void setEnabled(boolean enabled)
{
_enabled = enabled;
}
-
+
public void enable()
{
_enabled = Boolean.TRUE;
}
-
+
public void disable()
{
_enabled = Boolean.FALSE;
@@ -96,13 +96,18 @@ public class Rule implements Comparable<Rule>
{
_identity = identity;
}
-
+
public Action getAction()
{
+ return _action.getAction();
+ }
+
+ public AclAction getAclAction()
+ {
return _action;
}
- public void setAction(Action action)
+ public void setAction(AclAction action)
{
_action = action;
}
@@ -117,7 +122,7 @@ public class Rule implements Comparable<Rule>
_permission = permission;
}
- /** @see Comparable#compareTo(Object) */
+ @Override
public int compareTo(Rule r)
{
return new CompareToBuilder()
@@ -127,7 +132,6 @@ public class Rule implements Comparable<Rule>
.toComparison();
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -136,33 +140,31 @@ public class Rule implements Comparable<Rule>
return false;
}
Rule r = (Rule) o;
-
+
return new EqualsBuilder()
.append(getIdentity(), r.getIdentity())
- .append(getAction(), r.getAction())
+ .append(getAclAction(), r.getAclAction())
.append(getPermission(), r.getPermission())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(getIdentity())
- .append(getAction())
+ .append(getAclAction())
.append(getPermission())
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("#", getNumber())
.append("identity", getIdentity())
- .append("action", getAction())
+ .append("action", getAclAction())
.append("permission", getPermission())
.append("enabled", isEnabled())
.toString();
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 815df99f80..e61370fced 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -18,8 +18,8 @@
*/
package org.apache.qpid.server.security.access.config;
+import java.net.InetAddress;
import java.security.Principal;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
@@ -54,7 +54,7 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
*/
public class RuleSet
{
- public static final Logger _logger = Logger.getLogger(RuleSet.class);
+ private static final Logger _logger = Logger.getLogger(RuleSet.class);
private static final String AT = "@";
private static final String SLASH = "/";
@@ -66,7 +66,6 @@ public class RuleSet
private static final Integer _increment = 10;
- private final Map<String, List<String>> _aclGroups = new HashMap<String, List<String>>();
private final SortedMap<Integer, Rule> _rules = new TreeMap<Integer, Rule>();
private final Map<Subject, Map<Operation, Map<ObjectType, List<Rule>>>> _cache =
new WeakHashMap<Subject, Map<Operation, Map<ObjectType, List<Rule>>>>();
@@ -79,14 +78,13 @@ public class RuleSet
}
/**
- * Clear the contents, including acl groups, rules and configuration.
+ * Clear the contents, including acl rules and configuration.
*/
public void clear()
{
_rules.clear();
_cache.clear();
_config.clear();
- _aclGroups.clear();
}
public int getRuleCount()
@@ -157,21 +155,27 @@ public class RuleSet
public void grant(Integer number, String identity, Permission permission, Operation operation)
{
- Action action = new Action(operation);
+ AclAction action = new AclAction(operation);
addRule(number, identity, permission, action);
}
public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, ObjectProperties properties)
{
- Action action = new Action(operation, object, properties);
+ AclAction action = new AclAction(operation, object, properties);
addRule(number, identity, permission, action);
}
- public boolean ruleExists(String identity, Action action)
+ public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ AclAction aclAction = new AclAction(operation, object, predicates);
+ addRule(number, identity, permission, aclAction);
+ }
+
+ public boolean ruleExists(String identity, AclAction action)
{
for (Rule rule : _rules.values())
{
- if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
+ if (rule.getIdentity().equals(identity) && rule.getAclAction().equals(action))
{
return true;
}
@@ -179,8 +183,7 @@ public class RuleSet
return false;
}
- // TODO make this work when group membership is not known at file parse time
- public void addRule(Integer number, String identity, Permission permission, Action action)
+ public void addRule(Integer number, String identity, Permission permission, AclAction action)
{
_cache.clear();
@@ -222,53 +225,6 @@ public class RuleSet
_rules.get(Integer.valueOf(ruleNumber)).disable();
}
- public boolean addGroup(String group, List<String> constituents)
- {
- _cache.clear();
-
- if (_aclGroups.containsKey(group))
- {
- // cannot redefine
- return false;
- }
- else
- {
- _aclGroups.put(group, new ArrayList<String>());
- }
-
- for (String name : constituents)
- {
- if (name.equalsIgnoreCase(group))
- {
- // recursive definition
- return false;
- }
-
- if (!checkName(name))
- {
- // invalid name
- return false;
- }
-
- if (_aclGroups.containsKey(name))
- {
- // is a group
- _aclGroups.get(group).addAll(_aclGroups.get(name));
- }
- else
- {
- // is a user
- if (!isvalidUserName(name))
- {
- // invalid username
- return false;
- }
- _aclGroups.get(group).add(name);
- }
- }
- return true;
- }
-
/** Return true if the name is well-formed (contains legal characters). */
protected boolean checkName(String name)
{
@@ -312,11 +268,15 @@ public class RuleSet
return true;
}
- // CPP broker authorise function prototype
- // virtual bool authorise(const std::string& id, const Action& action, const ObjectType& objType,
- // const std::string& name, std::map<Property, std::string>* params=0)
-
- // Possibly add a String name paramater?
+ /**
+ * Checks for the case when the client's address is not known.
+ *
+ * @see #check(Subject, Operation, ObjectType, ObjectProperties, InetAddress)
+ */
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ return check(subject, operation, objectType, properties, null);
+ }
/**
* Check the authorisation granted to a particular identity for an operation on an object type with
@@ -327,10 +287,9 @@ public class RuleSet
* the first match found, or denies access if there are no matching rules. Normally, it would be expected
* to have a default deny or allow rule at the end of an access configuration however.
*/
- public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
{
- // Create the action to check
- Action action = new Action(operation, objectType, properties);
+ ClientAction action = new ClientAction(operation, objectType, properties);
if(_logger.isDebugEnabled())
{
@@ -349,27 +308,31 @@ public class RuleSet
}
// Iterate through a filtered set of rules dealing with this identity and operation
- for (Rule current : rules)
+ for (Rule rule : rules)
{
if(_logger.isDebugEnabled())
{
- _logger.debug("Checking against rule: " + current);
+ _logger.debug("Checking against rule: " + rule);
}
- // Check if action matches
- if (action.matches(current.getAction()))
+
+ if (action.matches(rule.getAclAction(), addressOfClient))
{
- Permission permission = current.getPermission();
+ Permission permission = rule.getPermission();
switch (permission)
{
case ALLOW_LOG:
CurrentActor.get().message(AccessControlMessages.ALLOWED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case ALLOW:
return Result.ALLOWED;
case DENY_LOG:
CurrentActor.get().message(AccessControlMessages.DENIED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case DENY:
return Result.DENIED;
}
@@ -446,8 +409,7 @@ public class RuleSet
{
final Principal principal = iterator.next();
- if (rule.getIdentity().equalsIgnoreCase(principal.getName())
- || (_aclGroups.containsKey(rule.getIdentity()) && _aclGroups.get(rule.getIdentity()).contains(principal.getName())))
+ if (rule.getIdentity().equalsIgnoreCase(principal.getName()))
{
return true;
}
@@ -476,5 +438,4 @@ public class RuleSet
}
return objects;
}
-
}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
index a9e3fdc242..d08a052efd 100644
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
@@ -18,29 +18,30 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.access.config;
+package org.apache.qpid.server.security.access.firewall;
-/**
- * Firewall plugin exception.
- */
-public class FirewallException extends Exception
+public class AccessControlFirewallException extends RuntimeException
{
/** serialVersionUID */
private static final long serialVersionUID = 4526157149690917805L;
-
- public FirewallException() {
- super();
+
+ public AccessControlFirewallException()
+ {
+ super();
}
- public FirewallException(String message) {
- super(message);
+ public AccessControlFirewallException(String message)
+ {
+ super(message);
}
- public FirewallException(String message, Throwable cause) {
+ public AccessControlFirewallException(String message, Throwable cause)
+ {
super(message, cause);
}
- public FirewallException(Throwable cause) {
+ public AccessControlFirewallException(Throwable cause)
+ {
super(cause);
}
} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
new file mode 100644
index 0000000000..482a795693
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
@@ -0,0 +1,26 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+
+public interface FirewallRule
+{
+ boolean matches(InetAddress addressOfClient);
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java
new file mode 100644
index 0000000000..64be26c209
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.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.security.access.firewall;
+
+public class FirewallRuleFactory
+{
+ public FirewallRule createForHostname(String[] hostnames)
+ {
+ return new HostnameFirewallRule(hostnames);
+ }
+
+ public FirewallRule createForNetwork(String[] networks)
+ {
+ return new NetworkFirewallRule(networks);
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
new file mode 100644
index 0000000000..fb13426fbb
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
@@ -0,0 +1,156 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class HostnameFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(HostnameFirewallRule.class);
+
+ private static final long DNS_TIMEOUT = 30000;
+ private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
+
+ private Pattern[] _hostnamePatterns;
+ private String[] _hostnames;
+
+ public HostnameFirewallRule(String... hostnames)
+ {
+ _hostnames = hostnames;
+
+ int i = 0;
+ _hostnamePatterns = new Pattern[hostnames.length];
+ for (String hostname : hostnames)
+ {
+ _hostnamePatterns[i++] = Pattern.compile(hostname);
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress remote)
+ {
+ String hostname = getHostname(remote);
+ if (hostname == null)
+ {
+ throw new AccessControlFirewallException("DNS lookup failed for address " + remote);
+ }
+ for (Pattern pattern : _hostnamePatterns)
+ {
+ boolean hostnameMatches = pattern.matcher(hostname).matches();
+
+ if (hostnameMatches)
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches rule " + pattern.toString());
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches no configured hostname patterns");
+ }
+
+ return false;
+ }
+
+
+ /**
+ * @param remote
+ * the InetAddress to look up
+ * @return the hostname, null if not found, takes longer than
+ * {@value #DNS_LOOKUP} to find or otherwise fails
+ */
+ private String getHostname(final InetAddress remote) throws AccessControlFirewallException
+ {
+ FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
+ {
+ public String call()
+ {
+ return remote.getCanonicalHostName();
+ }
+ });
+ DNS_LOOKUP.execute(lookup);
+
+ try
+ {
+ return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to look up hostname from address " + remote, e);
+ return null;
+ }
+ finally
+ {
+ lookup.cancel(true);
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_hostnames).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ HostnameFirewallRule rhs = (HostnameFirewallRule) obj;
+ return new EqualsBuilder().append(_hostnames, rhs._hostnames).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_hostnames).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java
new file mode 100644
index 0000000000..2e979b38f1
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.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.access.firewall;
+
+import java.net.InetAddress;
+
+class InetNetwork
+{
+ /*
+ * Implements network masking, and is compatible with RFC 1518 and
+ * RFC 1519, which describe CIDR: Classless Inter-Domain Routing.
+ */
+
+ private InetAddress network;
+ private InetAddress netmask;
+
+ public InetNetwork(InetAddress ip, InetAddress netmask)
+ {
+ this.network = maskIP(ip, netmask);
+ this.netmask = netmask;
+ }
+
+ public boolean contains(final String name) throws java.net.UnknownHostException
+ {
+ return network.equals(maskIP(InetAddress.getByName(name), netmask));
+ }
+
+ public boolean contains(final InetAddress ip)
+ {
+ return network.equals(maskIP(ip, netmask));
+ }
+
+ @Override
+ public String toString()
+ {
+ return network.getHostAddress() + "/" + netmask.getHostAddress();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return maskIP(network, netmask).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj != null) &&
+ (obj instanceof InetNetwork) &&
+ ((InetNetwork)obj).network.equals(network) &&
+ ((InetNetwork)obj).netmask.equals(netmask);
+ }
+
+ public static InetNetwork getFromString(String netspec) throws java.net.UnknownHostException
+ {
+ if (netspec.endsWith("*"))
+ {
+ netspec = normalizeFromAsterisk(netspec);
+ }
+ else
+ {
+ int iSlash = netspec.indexOf('/');
+ if (iSlash == -1)
+ {
+ netspec += "/255.255.255.255";
+ }
+ else if (netspec.indexOf('.', iSlash) == -1)
+ {
+ netspec = normalizeFromCIDR(netspec);
+ }
+ }
+
+ return new InetNetwork(
+ InetAddress.getByName(netspec.substring(0, netspec.indexOf('/'))),
+ InetAddress.getByName(netspec.substring(netspec.indexOf('/') + 1)));
+ }
+
+ public static InetAddress maskIP(final byte[] ip, final byte[] mask)
+ {
+ try
+ {
+ return getByAddress(
+ new byte[]
+ {
+ (byte) (mask[0] & ip[0]),
+ (byte) (mask[1] & ip[1]),
+ (byte) (mask[2] & ip[2]),
+ (byte) (mask[3] & ip[3])
+ }
+ );
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ public static InetAddress maskIP(final InetAddress ip, final InetAddress mask)
+ {
+ return maskIP(ip.getAddress(), mask.getAddress());
+ }
+
+ /*
+ * This converts from an uncommon "wildcard" CIDR format
+ * to "address + mask" format:
+ *
+ * * => 000.000.000.0/000.000.000.0
+ * xxx.* => xxx.000.000.0/255.000.000.0
+ * xxx.xxx.* => xxx.xxx.000.0/255.255.000.0
+ * xxx.xxx.xxx.* => xxx.xxx.xxx.0/255.255.255.0
+ */
+ static private String normalizeFromAsterisk(final String netspec)
+ {
+ String[] masks = { "0.0.0.0/0.0.0.0", "0.0.0/255.0.0.0", "0.0/255.255.0.0", "0/255.255.255.0" };
+ char[] srcb = netspec.toCharArray();
+ int octets = 0;
+ for (int i = 1; i < netspec.length(); i++)
+ {
+ if (srcb[i] == '.')
+ {
+ octets++;
+ }
+ }
+ return (octets == 0) ? masks[0] : netspec.substring(0, netspec.length() -1 ).concat(masks[octets]);
+ }
+
+ /*
+ * RFC 1518, 1519 - Classless Inter-Domain Routing (CIDR)
+ * This converts from "prefix + prefix-length" format to
+ * "address + mask" format, e.g. from xxx.xxx.xxx.xxx/yy
+ * to xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy.
+ */
+ static private String normalizeFromCIDR(final String netspec)
+ {
+ final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/')+1));
+ final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits)-1);
+
+ return netspec.substring(0, netspec.indexOf('/') + 1) +
+ Integer.toString(mask >> 24 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 16 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 8 & 0xFF, 10) + "." +
+ Integer.toString(mask >> 0 & 0xFF, 10);
+ }
+
+ private static InetAddress getByAddress(byte[] ip) throws java.net.UnknownHostException
+ {
+ InetAddress addr = InetAddress.getByAddress(ip);
+
+ if (addr == null) {
+ addr = InetAddress.getByName
+ (
+ Integer.toString(ip[0] & 0xFF, 10) + "." +
+ Integer.toString(ip[1] & 0xFF, 10) + "." +
+ Integer.toString(ip[2] & 0xFF, 10) + "." +
+ Integer.toString(ip[3] & 0xFF, 10)
+ );
+ }
+
+ return addr;
+ }
+} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
new file mode 100644
index 0000000000..ad619a0e0b
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
@@ -0,0 +1,117 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class NetworkFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(NetworkFirewallRule.class);
+
+ private List<InetNetwork> _networks;
+
+ public NetworkFirewallRule(String... networks)
+ {
+ _networks = new ArrayList<InetNetwork>();
+ for (int i = 0; i < networks.length; i++)
+ {
+ String network = networks[i];
+ try
+ {
+ InetNetwork inetNetwork = InetNetwork.getFromString(network);
+ if (!_networks.contains(inetNetwork))
+ {
+ _networks.add(inetNetwork);
+ }
+ }
+ catch (java.net.UnknownHostException uhe)
+ {
+ _logger.error("Cannot resolve address: " + network, uhe);
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress ip)
+ {
+ for (InetNetwork network : _networks)
+ {
+ if (network.contains(ip))
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " matches configured network " + network);
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " does not match any configured networks");
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_networks).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ NetworkFirewallRule rhs = (NetworkFirewallRule) obj;
+ return new EqualsBuilder().append(_networks, rhs._networks).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_networks).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
index bf80df3722..2a5eb7b3be 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
@@ -25,4 +25,4 @@
ALLOWED = ACL-1001 : Allowed : {0} {1} {2}
# 'deny-log' rule message
-DENIED = ACL-1002 : Denied : {0} {1} {2} \ No newline at end of file
+DENIED = ACL-1002 : Denied : {0} {1} {2}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java
deleted file mode 100644
index 7c83446cf1..0000000000
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlActivator.java
+++ /dev/null
@@ -1,41 +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.access.plugins;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginActivator;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/**
- * The OSGi {@link org.osgi.framework.BundleActivator} for {@link AccessControl}.
- */
-public class AccessControlActivator extends SecurityPluginActivator
-{
- public SecurityPluginFactory getFactory()
- {
- return AccessControl.FACTORY;
- }
-
- public ConfigurationPluginFactory getConfigurationFactory()
- {
- return AccessControlConfiguration.FACTORY;
- }
-}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java
deleted file mode 100644
index c4db6db820..0000000000
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControlConfiguration.java
+++ /dev/null
@@ -1,83 +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.access.plugins;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.access.config.ConfigurationFile;
-import org.apache.qpid.server.security.access.config.PlainConfiguration;
-import org.apache.qpid.server.security.access.config.RuleSet;
-
-public class AccessControlConfiguration extends ConfigurationPlugin
-{
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new AccessControlConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.acl", "virtualhosts.virtualhost.security.acl");
- }
- };
-
- private RuleSet _ruleSet;
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public String getFileName()
- {
- return getConfig().getString("");
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
- String filename = getFileName();
- if (filename == null)
- {
- throw new ConfigurationException("No ACL file name specified");
- }
-
- File aclFile = new File(filename);
-
- ConfigurationFile configFile = new PlainConfiguration(aclFile);
- _ruleSet = configFile.load();
- }
-
- public RuleSet getRuleSet()
- {
- return _ruleSet;
- }
-
-}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java
index d8a5bd4085..6f7885da94 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java
@@ -20,56 +20,47 @@
*/
package org.apache.qpid.server.security.access.plugins;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.io.File;
+
import javax.security.auth.Subject;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.AbstractPlugin;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.apache.qpid.server.security.AccessControl;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.config.ConfigurationFile;
+import org.apache.qpid.server.security.access.config.PlainConfiguration;
import org.apache.qpid.server.security.access.config.RuleSet;
-/**
- * This access control plugin implements version two plain text access control.
- */
-public class AccessControl extends AbstractPlugin
+public class DefaultAccessControl implements AccessControl
{
- public static final Logger _logger = Logger.getLogger(AccessControl.class);
-
+ private static final Logger _logger = Logger.getLogger(DefaultAccessControl.class);
+
private RuleSet _ruleSet;
-
- public static final SecurityPluginFactory<AccessControl> FACTORY = new SecurityPluginFactory<AccessControl>()
- {
- public Class<AccessControl> getPluginClass()
- {
- return AccessControl.class;
- }
- public String getPluginName()
+ public DefaultAccessControl(String fileName)
+ {
+ if (_logger.isDebugEnabled())
{
- return AccessControl.class.getName();
+ _logger.debug("Creating AccessControl instance using file: " + fileName);
}
+ File aclFile = new File(fileName);
- public AccessControl newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- AccessControlConfiguration configuration = config.getConfiguration(AccessControlConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
+ ConfigurationFile configFile = new PlainConfiguration(aclFile);
+ _ruleSet = configFile.load();
+ }
- AccessControl plugin = new AccessControl();
- plugin.configure(configuration);
- return plugin;
- }
- };
+ DefaultAccessControl(RuleSet rs) throws ConfigurationException
+ {
+ _ruleSet = rs;
+ }
public Result getDefault()
{
@@ -82,11 +73,18 @@ public class AccessControl extends AbstractPlugin
* Delegate to the {@link #authorise(Operation, ObjectType, ObjectProperties)} method, with
* the operation set to ACCESS and no object properties.
*/
- public Result access(ObjectType objectType, Object instance)
+ public Result access(ObjectType objectType, Object inetSocketAddress)
{
- return authorise(Operation.ACCESS, objectType, ObjectProperties.EMPTY);
+ InetAddress addressOfClient = null;
+
+ if(inetSocketAddress != null)
+ {
+ addressOfClient = ((InetSocketAddress) inetSocketAddress).getAddress();
+ }
+
+ return authoriseFromAddress(Operation.ACCESS, objectType, ObjectProperties.EMPTY, addressOfClient);
}
-
+
/**
* Check if an operation is authorised by asking the configuration object about the access
* control rules granted to the current thread's {@link Subject}. If there is no current
@@ -94,23 +92,31 @@ public class AccessControl extends AbstractPlugin
*/
public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
{
+ return authoriseFromAddress(operation, objectType, properties, null);
+ }
+
+ public Result authoriseFromAddress(Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
+ {
final Subject subject = SecurityManager.getThreadSubject();
// Abstain if there is no subject/principal associated with this thread
if (subject == null || subject.getPrincipals().size() == 0)
{
return Result.ABSTAIN;
}
-
- _logger.debug("Checking " + operation + " " + objectType);
- return _ruleSet.check(subject, operation, objectType, properties);
- }
- public void configure(ConfigurationPlugin config)
- {
- super.configure(config);
-
- AccessControlConfiguration accessConfig = (AccessControlConfiguration) getConfig();
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Checking " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""));
+ }
- _ruleSet = accessConfig.getRuleSet();
+ try
+ {
+ return _ruleSet.check(subject, operation, objectType, properties, addressOfClient);
+ }
+ catch(Exception e)
+ {
+ _logger.error("Unable to check " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""), e);
+ return Result.DENIED;
+ }
}
}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.java
new file mode 100644
index 0000000000..a3d7823caf
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactory.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.access.plugins;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.plugin.AccessControlFactory;
+import org.apache.qpid.server.security.AccessControl;
+
+public class DefaultAccessControlFactory implements AccessControlFactory
+{
+ public static final String ATTRIBUTE_ACL_FILE = "aclFile";
+
+ public AccessControl createInstance(Map<String, Object> aclConfiguration)
+ {
+ if (aclConfiguration != null)
+ {
+ Object aclFile = aclConfiguration.get(ATTRIBUTE_ACL_FILE);
+ if (aclFile != null)
+ {
+ if (aclFile instanceof String)
+ {
+ String aclPath = (String) aclFile;
+ if (!new File(aclPath).exists())
+ {
+ throw new IllegalConfigurationException("ACL file '" + aclPath + "' is not found");
+ }
+ return new DefaultAccessControl(aclPath);
+ }
+ else
+ {
+ throw new IllegalConfigurationException("Expected '" + ATTRIBUTE_ACL_FILE + "' attribute value of type String but was " + aclFile.getClass()
+ + ": " + aclFile);
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory b/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory
new file mode 100644
index 0000000000..b6c429baab
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AccessControlFactory
@@ -0,0 +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.
+#
+org.apache.qpid.server.security.access.plugins.DefaultAccessControlFactory
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
new file mode 100644
index 0000000000..14620cff70
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class AclActionTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclRulePredicates predicates = createAclRulePredicates();
+ ObjectType objectType = ObjectType.EXCHANGE;
+ Operation operation = Operation.ACCESS;
+
+ AclAction aclAction = new AclAction(operation, objectType, predicates);
+ AclAction equalAclAction = new AclAction(operation, objectType, predicates);
+
+ assertTrue(aclAction.equals(aclAction));
+ assertTrue(aclAction.equals(equalAclAction));
+ assertTrue(equalAclAction.equals(aclAction));
+
+ assertTrue(aclAction.hashCode() == equalAclAction.hashCode());
+
+ assertFalse("Different operation should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(Operation.BIND, objectType, predicates)));
+
+ assertFalse("Different operation type should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, ObjectType.GROUP, predicates)));
+
+ assertFalse("Different predicates should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, objectType, createAclRulePredicates())));
+
+ }
+
+ private AclRulePredicates createAclRulePredicates()
+ {
+ AclRulePredicates predicates = mock(AclRulePredicates.class);
+ when(predicates.getFirewallRule()).thenReturn(mock(FirewallRule.class));
+ when(predicates.getObjectProperties()).thenReturn(mock(ObjectProperties.class));
+ return predicates;
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
new file mode 100644
index 0000000000..93b765d0fb
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.access.config;
+
+import static org.apache.qpid.server.security.access.ObjectProperties.Property.*;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+import static org.mockito.Mockito.*;
+
+import junit.framework.TestCase;
+
+public class AclRulePredicatesTest extends TestCase
+{
+ private AclRulePredicates _aclRulePredicates = new AclRulePredicates();
+ private FirewallRuleFactory _firewallRuleFactory = mock(FirewallRuleFactory.class);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ when(_firewallRuleFactory.createForHostname((String[]) any())).thenReturn(mock(FirewallRule.class));
+ when(_firewallRuleFactory.createForNetwork((String[]) any())).thenReturn(mock(FirewallRule.class));
+ }
+
+ public void testParse()
+ {
+ String name = "name";
+ String className = "class";
+
+ _aclRulePredicates.parse(NAME.name(), name);
+ _aclRulePredicates.parse(CLASS.name(), className);
+
+ assertEquals(name, _aclRulePredicates.getObjectProperties().get(NAME));
+ assertEquals(className, _aclRulePredicates.getObjectProperties().get(CLASS));
+ }
+
+ public void testParseHostnameFirewallRule()
+ {
+ String hostname = "hostname1,hostname2";
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), hostname);
+
+ verify(_firewallRuleFactory).createForHostname(new String[] {"hostname1", "hostname2"});
+ }
+
+ public void testParseNetworkFirewallRule()
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ String networks = "network1,network2";
+ _aclRulePredicates.parse(FROM_NETWORK.name(), networks);
+
+ verify(_firewallRuleFactory).createForNetwork(new String[] {"network1", "network2"});
+ }
+
+ public void testParseThrowsExceptionIfBothHostnameAndNetworkSpecified()
+ {
+ _aclRulePredicates.parse(FROM_NETWORK.name(), "network1,network2");
+ try
+ {
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), "hostname1,hostname2");
+ fail("Exception not thrown");
+ }
+ catch(IllegalStateException e)
+ {
+ // pass
+ }
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java
new file mode 100644
index 0000000000..00e06106bf
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ActionTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+import junit.framework.TestCase;
+
+public class ActionTest extends TestCase
+{
+ private ObjectProperties _properties1 = mock(ObjectProperties.class);
+ private ObjectProperties _properties2 = mock(ObjectProperties.class);
+
+ public void testMatchesReturnsTrueForMatchingActions()
+ {
+ when(_properties1.matches(_properties2)).thenReturn(true);
+
+ assertMatches(
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties2));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationsDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CONSUME, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationTypesDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.EXCHANGE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOperationPropertiesDiffer()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties2));
+ }
+
+ public void testMatchesReturnsFalseWhenMyOperationPropertiesIsNull()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null),
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1));
+ }
+
+ public void testMatchesReturnsFalseWhenOtherOperationPropertiesIsNull()
+ {
+ assertDoesntMatch(
+ new Action(Operation.CREATE, ObjectType.QUEUE, _properties1),
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null));
+ }
+
+ public void testMatchesReturnsTrueWhenBothOperationPropertiesAreNull()
+ {
+ assertMatches(
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null),
+ new Action(Operation.CREATE, ObjectType.QUEUE, (ObjectProperties)null));
+ }
+
+ private void assertMatches(Action action1, Action action2)
+ {
+ assertTrue(action1 + " should match " + action2, action1.matches(action2));
+ }
+
+ private void assertDoesntMatch(Action action1, Action action2)
+ {
+ assertFalse(action1 + " should not match " + action2, action1.matches(action2));
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
new file mode 100644
index 0000000000..ae5d3fda74
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class ClientActionTest extends TestCase
+{
+ private Action _action = mock(Action.class);
+ private AclAction _ruleAction = mock(AclAction.class);
+ private InetAddress _addressOfClient = mock(InetAddress.class);
+
+ private ClientAction _clientAction = new ClientAction(_action);
+
+ public void testMatches_returnsTrueWhenActionsMatchAndNoFirewallRule()
+ {
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(null);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsFalseWhenActionsDontMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(false);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertFalse(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsTrueWhenActionsAndFirewallRuleMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_ignoresFirewallRuleIfClientAddressIsNull()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, null));
+
+ verifyZeroInteractions(firewallRule);
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java
index c2282694fb..cbfc9003c8 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.qpid.server.security.access.plugins;
+package org.apache.qpid.server.security.access.config;
import java.io.File;
import java.io.FileNotFoundException;
@@ -26,7 +26,7 @@ import java.util.Map;
import junit.framework.TestCase;
-import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectProperties.Property;
import org.apache.qpid.server.security.access.ObjectType;
@@ -73,7 +73,7 @@ public class PlainConfigurationTest extends TestCase
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
assertTrue(ce.getCause() instanceof FileNotFoundException);
@@ -87,7 +87,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW ALL \\ ALL");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
}
@@ -100,7 +100,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL unparsed ALL ALL");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
assertTrue(ce.getCause() instanceof IllegalArgumentException);
@@ -108,19 +108,6 @@ public class PlainConfigurationTest extends TestCase
}
}
- public void testACLFileSyntaxNotEnoughGroup() throws Exception
- {
- try
- {
- writeACLConfig("GROUP blah");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_GROUP_MSG, 1), ce.getMessage());
- }
- }
-
public void testACLFileSyntaxNotEnoughACL() throws Exception
{
try
@@ -128,7 +115,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
}
@@ -141,7 +128,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("CONFIG");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
}
@@ -154,7 +141,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("INVALID");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
}
@@ -167,7 +154,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
}
@@ -180,7 +167,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
}
@@ -193,7 +180,7 @@ public class PlainConfigurationTest extends TestCase
writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
fail("fail");
}
- catch (ConfigurationException ce)
+ catch (IllegalConfigurationException ce)
{
assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
}
@@ -391,4 +378,86 @@ public class PlainConfigurationTest extends TestCase
assertEquals("Rule has unexpected object properties", ObjectProperties.EMPTY, rule.getAction().getProperties());
}
+ public void testUserRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE USER"),
+ "user1", Operation.CREATE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE USER name=\"otherUser\""),
+ "user1", Operation.CREATE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE USER"),
+ "user1", Operation.DELETE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE USER name=\"otherUser\""),
+ "user1", Operation.DELETE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE USER"),
+ "user1", Operation.UPDATE, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE USER name=\"otherUser\""),
+ "user1", Operation.UPDATE, ObjectType.USER, new ObjectProperties("otherUser"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL USER"),
+ "user1", Operation.ALL, ObjectType.USER, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL USER name=\"otherUser\""),
+ "user1", Operation.ALL, ObjectType.USER, new ObjectProperties("otherUser"));
+ }
+
+ public void testGroupRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE GROUP"),
+ "user1", Operation.CREATE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 CREATE GROUP name=\"groupName\""),
+ "user1", Operation.CREATE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE GROUP"),
+ "user1", Operation.DELETE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 DELETE GROUP name=\"groupName\""),
+ "user1", Operation.DELETE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE GROUP"),
+ "user1", Operation.UPDATE, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 UPDATE GROUP name=\"groupName\""),
+ "user1", Operation.UPDATE, ObjectType.GROUP, new ObjectProperties("groupName"));
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL GROUP"),
+ "user1", Operation.ALL, ObjectType.GROUP, ObjectProperties.EMPTY);
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL GROUP name=\"groupName\""),
+ "user1", Operation.ALL, ObjectType.GROUP, new ObjectProperties("groupName"));
+ }
+
+ /** explicitly test for exception indicating that this functionality has been moved to Group Providers */
+ public void testGroupDefinitionThrowsException() throws Exception
+ {
+ try
+ {
+ writeACLConfig("GROUP group1 bob alice");
+ fail("Expected exception not thrown");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ assertTrue(e.getMessage().contains("GROUP keyword not supported"));
+ }
+ }
+
+ public void testManagementRuleParsing() throws Exception
+ {
+ validateRule(writeACLConfig("ACL ALLOW user1 ALL MANAGEMENT"),
+ "user1", Operation.ALL, ObjectType.MANAGEMENT, ObjectProperties.EMPTY);
+
+ validateRule(writeACLConfig("ACL ALLOW user1 ACCESS MANAGEMENT"),
+ "user1", Operation.ACCESS, ObjectType.MANAGEMENT, ObjectProperties.EMPTY);
+ }
+
+ private void validateRule(final PlainConfiguration config, String username, Operation operation, ObjectType objectType, ObjectProperties objectProperties)
+ {
+ final RuleSet rs = config.getConfiguration();
+ assertEquals(1, rs.getRuleCount());
+
+ final Map<Integer, Rule> rules = rs.getAllRules();
+ assertEquals(1, rules.size());
+ final Rule rule = rules.get(0);
+ assertEquals("Rule has unexpected identity", username, rule.getIdentity());
+ assertEquals("Rule has unexpected operation", operation, rule.getAction().getOperation());
+ assertEquals("Rule has unexpected operation", objectType, rule.getAction().getObjectType());
+ assertEquals("Rule has unexpected object properties", objectProperties, rule.getAction().getProperties());
+ }
}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
new file mode 100644
index 0000000000..2ae7759679
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.Permission;
+
+import junit.framework.TestCase;
+
+public class RuleTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclAction aclAction = mock(AclAction.class);
+ String identity = "identity";
+ Permission allow = Permission.ALLOW;
+
+ Rule rule = new Rule(identity, aclAction, allow);
+ Rule equalRule = new Rule(identity, aclAction, allow);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different identity should cause rules to be unequal",
+ rule.equals(new Rule("identity2", aclAction, allow)));
+
+ assertFalse("Different action should cause rules to be unequal",
+ rule.equals(new Rule(identity, mock(AclAction.class), allow)));
+
+ assertFalse("Different permission should cause rules to be unequal",
+ rule.equals(new Rule(identity, aclAction, Permission.DENY)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
new file mode 100644
index 0000000000..be82cb294a
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.access.firewall;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.HostnameFirewallRule;
+
+import junit.framework.TestCase;
+
+public class HostnameFirewallRuleTest extends TestCase
+{
+ private InetAddress _addressNotInRule;
+
+ private HostnameFirewallRule _HostnameFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName("127.0.0.1");
+ }
+
+ public void testSingleHostname() throws Exception
+ {
+ String hostnameInRule = "hostnameInRule";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testSingleHostnameWilcard() throws Exception
+ {
+ String hostnameInRule = ".*FOO.*";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn("xxFOOxx");
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testMultipleHostnames() throws Exception
+ {
+ String[] hostnamesInRule = new String[] {"hostnameInRule1", "hostnameInRule2"};
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnamesInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ for (String hostnameInRule : hostnamesInRule)
+ {
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ String hostname1 = "hostname1";
+ String hostname2 = "hostname2";
+
+ HostnameFirewallRule rule = new HostnameFirewallRule(hostname1, hostname2);
+ HostnameFirewallRule equalRule = new HostnameFirewallRule(hostname1, hostname2);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different hostnames should cause rules to be unequal",
+ rule.equals(new HostnameFirewallRule(hostname1, "different-hostname")));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
new file mode 100644
index 0000000000..e521039db2
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.access.firewall;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.NetworkFirewallRule;
+
+import junit.framework.TestCase;
+
+public class NetworkFirewallRuleTest extends TestCase
+{
+ private static final String LOCALHOST_IP = "127.0.0.1";
+ private static final String OTHER_IP_1 = "192.168.23.1";
+ private static final String OTHER_IP_2 = "192.168.23.2";
+
+ private InetAddress _addressNotInRule;
+
+ private NetworkFirewallRule _networkFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName(LOCALHOST_IP);
+ }
+
+ public void testIpRule() throws Exception
+ {
+ String ipAddressInRule = OTHER_IP_1;
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+
+ public void testNetMask() throws Exception
+ {
+ String ipAddressInRule = "192.168.23.0/24";
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(InetAddress.getByName("192.168.24.1")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.0")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.255")));
+ }
+
+ public void testWildcard() throws Exception
+ {
+ // Test xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.169.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.255.255")));
+
+ // Test xxx.xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.169.2.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.255")));
+ }
+
+ public void testMultipleNetworks() throws Exception
+ {
+ String[] ipAddressesInRule = new String[] {OTHER_IP_1, OTHER_IP_2};
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressesInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ for (String ipAddressInRule : ipAddressesInRule)
+ {
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ NetworkFirewallRule rule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+ NetworkFirewallRule equalRule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different networks should cause rules to be unequal",
+ rule.equals(new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_2)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java
new file mode 100644
index 0000000000..ca1f19098f
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlFactoryTest.java
@@ -0,0 +1,69 @@
+package org.apache.qpid.server.security.access.plugins;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.security.AccessControl;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+public class DefaultAccessControlFactoryTest extends QpidTestCase
+{
+ public void testCreateInstanceWhenAclFileIsNotPresent()
+ {
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ AccessControl acl = factory.createInstance(attributes);
+ assertNull("ACL was created without a configuration file", acl);
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecified()
+ {
+ File aclFile = TestFileUtils.createTempFile(this, ".acl", "ACL ALLOW all all");
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile.getAbsolutePath());
+ AccessControl acl = factory.createInstance(attributes);
+
+ assertNotNull("ACL was not created from acl file: " + aclFile.getAbsolutePath(), acl);
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecifiedButDoesNotExist()
+ {
+ File aclFile = new File(TMP_FOLDER, "my-non-existing-acl-" + System.currentTimeMillis());
+ assertFalse("ACL file " + aclFile.getAbsolutePath() + " actually exists but should not", aclFile.exists());
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile.getAbsolutePath());
+ try
+ {
+ factory.createInstance(attributes);
+ fail("It should not be possible to create ACL from non existing file");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertTrue("Unexpected exception message", Pattern.matches("ACL file '.*' is not found", e.getMessage()));
+ }
+ }
+
+ public void testCreateInstanceWhenAclFileIsSpecifiedAsNonString()
+ {
+ DefaultAccessControlFactory factory = new DefaultAccessControlFactory();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ Integer aclFile = new Integer(0);
+ attributes.put(DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE, aclFile);
+ try
+ {
+ factory.createInstance(attributes);
+ fail("It should not be possible to create ACL from Integer");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message", "Expected '" + DefaultAccessControlFactory.ATTRIBUTE_ACL_FILE
+ + "' attribute value of type String but was " + Integer.class + ": " + aclFile, e.getMessage());
+ }
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
index 5db02d10ce..a8406308c0 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
@@ -20,12 +20,16 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import java.util.Arrays;
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.security.auth.Subject;
import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.logging.UnitTestMessageLogger;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.TestLogActor;
@@ -37,20 +41,19 @@ import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
/**
- * Unit test for ACL V2 plugin.
- *
- * This unit test tests the AccessControl class and it collaboration with {@link RuleSet},
- * {@link SecurityManager} and {@link CurrentActor}. The ruleset is configured programmatically,
- * rather than from an external file.
- *
+ * In these tests, the ruleset is configured programmatically rather than from an external file.
+ *
* @see RuleSetTest
*/
-public class AccessControlTest extends TestCase
+public class DefaultAccessControlTest extends TestCase
{
- private AccessControl _plugin = null; // Class under test
+ private static final String ALLOWED_GROUP = "allowed_group";
+ private static final String DENIED_GROUP = "denied_group";
+
+ private DefaultAccessControl _plugin = null; // Class under test
private final UnitTestMessageLogger messageLogger = new UnitTestMessageLogger();
private void setUpGroupAccessControl() throws ConfigurationException
@@ -60,7 +63,7 @@ public class AccessControlTest extends TestCase
private void configureAccessControl(final RuleSet rs) throws ConfigurationException
{
- _plugin = (AccessControl) AccessControl.FACTORY.newInstance(createConfiguration(rs));
+ _plugin = new DefaultAccessControl(rs);
SecurityManager.setThreadSubject(null);
CurrentActor.set(new TestLogActor(messageLogger));
}
@@ -68,14 +71,12 @@ public class AccessControlTest extends TestCase
private RuleSet createGroupRuleSet()
{
final RuleSet rs = new RuleSet();
- rs.addGroup("aclGroup1", Arrays.asList(new String[] {"member1", "Member2"}));
// Rule expressed with username
rs.grant(0, "user1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with a acl group
- rs.grant(1, "aclGroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with an external group
- rs.grant(2, "extGroup1", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ // Rules expressed with groups
+ rs.grant(1, ALLOWED_GROUP, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ rs.grant(2, DENIED_GROUP, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
// Catch all rule
rs.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
@@ -117,31 +118,23 @@ public class AccessControlTest extends TestCase
* Tests that an allow rule expressed with an <b>ACL groupname</b> allows an operation performed by a thread running
* by a user who belongs to the same group..
*/
- public void testAclGroupMembershipAllowsOperation() throws ConfigurationException
+ public void testGroupMembershipAllowsOperation() throws ConfigurationException
{
setUpGroupAccessControl();
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("member1"));
- Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
-
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("Member2"));
-
- result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ authoriseAndAssertResult(Result.ALLOWED, "member of allowed group", ALLOWED_GROUP);
+ authoriseAndAssertResult(Result.DENIED, "member of denied group", DENIED_GROUP);
+ authoriseAndAssertResult(Result.ALLOWED, "another member of allowed group", ALLOWED_GROUP);
}
/**
- * Tests that a deny rule expressed with an <b>External groupname</b> denies an operation performed by a thread running
+ * Tests that a deny rule expressed with a <b>groupname</b> denies an operation performed by a thread running
* by a user who belongs to the same group.
*/
- public void testExternalGroupMembershipDeniesOperation() throws ConfigurationException
+ public void testGroupMembershipDeniesOperation() throws ConfigurationException
{
setUpGroupAccessControl();
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user3", "extGroup1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
+ authoriseAndAssertResult(Result.DENIED, "user3", DENIED_GROUP);
}
/**
@@ -203,6 +196,46 @@ public class AccessControlTest extends TestCase
assertEquals(Result.DEFER, result);
}
+ public void testAccess() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet);
+
+ accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ verify(mockRuleSet).check(subject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY, inetAddress);
+ }
+
+ public void testAccessIsDeniedIfRuleThrowsException() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+ when(mockRuleSet.check(
+ subject,
+ Operation.ACCESS,
+ ObjectType.VIRTUALHOST,
+ ObjectProperties.EMPTY,
+ inetAddress)).thenThrow(new RuntimeException());
+
+ DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet);
+ Result result = accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ assertEquals(Result.DENIED, result);
+ }
+
+
/**
* Tests that a grant access method rule allows any access operation to be performed on a specified component
*/
@@ -325,31 +358,11 @@ public class AccessControlTest extends TestCase
assertEquals(Result.DEFER, result);
}
- /**
- * Creates a configuration plugin for the {@link AccessControl} plugin.
- */
- private ConfigurationPlugin createConfiguration(final RuleSet rs)
+ private void authoriseAndAssertResult(Result expectedResult, String userName, String... groups)
{
- final ConfigurationPlugin cp = new ConfigurationPlugin()
- {
- @SuppressWarnings("unchecked")
- public AccessControlConfiguration getConfiguration(final String plugin)
- {
- return new AccessControlConfiguration()
- {
- public RuleSet getRuleSet()
- {
- return rs;
- }
- };
- }
-
- public String[] getElementsProcessed()
- {
- throw new UnsupportedOperationException();
- }
- };
-
- return cp;
+ SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject(userName, groups));
+
+ Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ assertEquals(expectedResult, result);
}
}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index f7cc60543d..181d693614 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -22,7 +22,6 @@
package org.apache.qpid.server.security.access.plugins;
import java.security.Principal;
-import java.util.Arrays;
import javax.security.auth.Subject;
@@ -34,8 +33,7 @@ import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
import org.apache.qpid.test.utils.QpidTestCase;
/**
@@ -46,10 +44,7 @@ import org.apache.qpid.test.utils.QpidTestCase;
* access control mechanism is validated by checking whether operations would be authorised by calling the
* {@link RuleSet#check(Principal, Operation, ObjectType, ObjectProperties)} method.
*
- * It ensure that permissions can be granted correctly on users directly, ACL groups (that is those
- * groups declared directly in the ACL itself), and External groups (that is a group from an External
- * Authentication Provider, such as an LDAP).
-
+ * It ensure that permissions can be granted correctly on users directly and on groups.
*/
public class RuleSetTest extends QpidTestCase
{
@@ -316,63 +311,36 @@ public class RuleSetTest extends QpidTestCase
assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
- /**
- * Tests support for ACL groups (i.e. inline groups declared in the ACL file itself).
- */
- public void testAclGroupsSupported()
+ public void testGroupsSupported()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera", "userb"})));
-
- _ruleSet.grant(1, "aclgroup", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DEFER, _ruleSet.check(TestPrincipalUtils.createTestSubject("userc"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Tests support for nested ACL groups.
- */
- public void testNestedAclGroupsSupported()
- {
- assertTrue(_ruleSet.addGroup("aclgroup1", Arrays.asList(new String[] {"userb"})));
- assertTrue(_ruleSet.addGroup("aclgroup2", Arrays.asList(new String[] {"usera", "aclgroup1"})));
-
- _ruleSet.grant(1, "aclgroup2", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
+ String allowGroup = "allowGroup";
+ String deniedGroup = "deniedGroup";
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
+ _ruleSet.grant(1, allowGroup, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, deniedGroup, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- /**
- * Tests support for nested External groups (i.e. those groups coming from an external source such as an LDAP).
- */
- public void testExternalGroupsSupported()
- {
- _ruleSet.grant(1, "extgroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "extgroup2", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera", "extgroup1"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb", "extgroup2"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera", allowGroup),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb", deniedGroup),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DEFER, _ruleSet.check(TestPrincipalUtils.createTestSubject("user", "group not mentioned in acl"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
/**
* Rule order in the ACL determines the outcome of the check. This test ensures that a user who is
- * granted explicit permission on an object, is granted that access even although late a group
+ * granted explicit permission on an object, is granted that access even though a group
* to which the user belongs is later denied the permission.
*/
public void testAllowDeterminedByRuleOrder()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
+ String group = "group";
+ String user = "user";
- _ruleSet.grant(1, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(1, user, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, group, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject(user, group),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
/**
@@ -381,13 +349,33 @@ public class RuleSetTest extends QpidTestCase
*/
public void testDenyDeterminedByRuleOrder()
{
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
+ String group = "aclgroup";
+ String user = "usera";
- _ruleSet.grant(1, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(1, group, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, user, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject(user, group),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ }
+
+ public void testUserInMultipleGroups()
+ {
+ String allowedGroup = "group1";
+ String deniedGroup = "group2";
+
+ _ruleSet.grant(1, allowedGroup, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ _ruleSet.grant(2, deniedGroup, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+
+ Subject subjectInBothGroups = TestPrincipalUtils.createTestSubject("user", allowedGroup, deniedGroup);
+ Subject subjectInDeniedGroupAndOneOther = TestPrincipalUtils.createTestSubject("user", deniedGroup, "some other group");
+ Subject subjectInAllowedGroupAndOneOther = TestPrincipalUtils.createTestSubject("user", allowedGroup, "some other group");
+
+ assertEquals(Result.ALLOWED, _ruleSet.check(subjectInBothGroups,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+
+ assertEquals(Result.DENIED, _ruleSet.check(subjectInDeniedGroupAndOneOther,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+
+ assertEquals(Result.ALLOWED, _ruleSet.check(subjectInAllowedGroupAndOneOther,Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
}
diff --git a/java/broker-plugins/firewall/MANIFEST.MF b/java/broker-plugins/firewall/MANIFEST.MF
deleted file mode 100644
index a302921d03..0000000000
--- a/java/broker-plugins/firewall/MANIFEST.MF
+++ /dev/null
@@ -1,34 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Firewall
-Bundle-SymbolicName: broker-plugins-firewall
-Bundle-Description: Firewall plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.security.access.plugins.FirewallActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.security.access.config
-Export-Package: org.apache.qpid.server.security.access.plugins;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/firewall/build.xml b/java/broker-plugins/firewall/build.xml
deleted file mode 100644
index 6ae6a35b89..0000000000
--- a/java/broker-plugins/firewall/build.xml
+++ /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.
- -->
-<project name="Qpid Broker-Plugins Firewall" default="build">
- <property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test broker/test common/test management/common" />
-
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
- <property name="module.genpom" value="true"/>
- <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
-
- <property name="broker-plugins-firewall.libs" value=""/>
-
- <import file="../../module.xml" />
-
- <target name="bundle" depends="bundle-tasks" />
-
-</project>
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
deleted file mode 100644
index ecec4b0cec..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
+++ /dev/null
@@ -1,136 +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.access.config;
-
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.util.NetMatcher;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-public class FirewallRule
-{
- public static final String ALLOW = "ALLOW";
- public static final String DENY = "DENY";
-
- private static final long DNS_TIMEOUT = 30000;
- private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
-
- private Result _access;
- private NetMatcher _network;
- private Pattern[] _hostnamePatterns;
-
- public FirewallRule(String access, List networks, List hostnames)
- {
- _access = (access.equalsIgnoreCase(ALLOW)) ? Result.ALLOWED : Result.DENIED;
-
- if (networks != null && networks.size() > 0)
- {
- String[] networkStrings = objListToStringArray(networks);
- _network = new NetMatcher(networkStrings);
- }
-
- if (hostnames != null && hostnames.size() > 0)
- {
- int i = 0;
- _hostnamePatterns = new Pattern[hostnames.size()];
- for (String hostname : objListToStringArray(hostnames))
- {
- _hostnamePatterns[i++] = Pattern.compile(hostname);
- }
- }
- }
-
- private String[] objListToStringArray(List objList)
- {
- String[] networkStrings = new String[objList.size()];
- int i = 0;
- for (Object network : objList)
- {
- networkStrings[i++] = (String) network;
- }
- return networkStrings;
- }
-
- public boolean match(InetAddress remote) throws FirewallException
- {
- if (_hostnamePatterns != null)
- {
- String hostname = getHostname(remote);
- if (hostname == null)
- {
- throw new FirewallException("DNS lookup failed");
- }
- for (Pattern pattern : _hostnamePatterns)
- {
- if (pattern.matcher(hostname).matches())
- {
- return true;
- }
- }
- return false;
- }
- else
- {
- return _network.matchInetNetwork(remote);
- }
- }
-
- /**
- * @param remote the InetAddress to look up
- * @return the hostname, null if not found, takes longer than 30s to find or otherwise fails
- */
- private String getHostname(final InetAddress remote) throws FirewallException
- {
- FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
- {
- public String call()
- {
- return remote.getCanonicalHostName();
- }
- });
- DNS_LOOKUP.execute(lookup);
-
- try
- {
- return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
- }
- catch (Exception e)
- {
- return null;
- }
- finally
- {
- lookup.cancel(true);
- }
- }
-
- public Result getAccess()
- {
- return _access;
- }
-} \ No newline at end of file
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
deleted file mode 100644
index 40a65fddba..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
+++ /dev/null
@@ -1,137 +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.access.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.AbstractPlugin;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.access.config.FirewallException;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-
-public class Firewall extends AbstractPlugin
-{
- public static final SecurityPluginFactory<Firewall> FACTORY = new SecurityPluginFactory<Firewall>()
- {
- public Firewall newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- FirewallConfiguration configuration = config.getConfiguration(FirewallConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- Firewall plugin = new Firewall();
- plugin.configure(configuration);
- return plugin;
- }
-
- public Class<Firewall> getPluginClass()
- {
- return Firewall.class;
- }
-
- public String getPluginName()
- {
- return Firewall.class.getName();
- }
- };
-
- private Result _default = Result.ABSTAIN;
- private FirewallRule[] _rules;
-
- public Result getDefault()
- {
- return _default;
- }
-
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- return Result.ABSTAIN; // We only deal with access requests
- }
-
- public Result access(ObjectType objectType, Object instance)
- {
- if (objectType != ObjectType.VIRTUALHOST)
- {
- return Result.ABSTAIN; // We are only interested in access to virtualhosts
- }
-
- if (!(instance instanceof InetSocketAddress))
- {
- return Result.ABSTAIN; // We need an internet address
- }
-
- InetAddress address = ((InetSocketAddress) instance).getAddress();
-
- try
- {
- for (FirewallRule rule : _rules)
- {
- boolean match = rule.match(address);
- if (match)
- {
- return rule.getAccess();
- }
- }
- return getDefault();
- }
- catch (FirewallException fe)
- {
- return Result.DENIED;
- }
- }
-
-
- public void configure(ConfigurationPlugin config)
- {
- super.configure(config);
- FirewallConfiguration firewallConfiguration = (FirewallConfiguration) getConfig();
-
- // Get default action
- _default = firewallConfiguration.getDefaultAction();
-
- Configuration finalConfig = firewallConfiguration.getConfiguration();
-
- // all rules must have an access attribute
- int numRules = finalConfig.getList("rule[@access]").size();
- _rules = new FirewallRule[numRules];
- for (int i = 0; i < numRules; i++)
- {
- FirewallRule rule = new FirewallRule(finalConfig.getString("rule(" + i + ")[@access]"),
- finalConfig.getList("rule(" + i + ")[@network]"),
- finalConfig.getList("rule(" + i + ")[@hostname]"));
- _rules[i] = rule;
- }
-
- }
-}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java
deleted file mode 100644
index 1669352085..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java
+++ /dev/null
@@ -1,41 +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.access.plugins;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginActivator;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/**
- * The OSGi {@link org.osgi.framework.BundleActivator} for {@link Firewall}.
- */
-public class FirewallActivator extends SecurityPluginActivator
-{
- public SecurityPluginFactory getFactory()
- {
- return Firewall.FACTORY;
- }
-
- public ConfigurationPluginFactory getConfigurationFactory()
- {
- return FirewallConfiguration.FACTORY;
- }
-}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
deleted file mode 100644
index 010d1652f0..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
+++ /dev/null
@@ -1,103 +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.access.plugins;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-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.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class FirewallConfiguration extends ConfigurationPlugin
-{
- private CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new FirewallConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.firewall", "virtualhosts.virtualhost.security.firewall");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
- public Result getDefaultAction()
- {
- String defaultAction = getConfig().getString("[@default-action]");
- if (defaultAction == null)
- {
- return Result.ABSTAIN;
- }
- else if (defaultAction.equalsIgnoreCase(FirewallRule.ALLOW))
- {
- return Result.ALLOWED;
- }
- else
- {
- return Result.DENIED;
- }
- }
-
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- // all rules must have an access attribute or a default value
- if (_finalConfig.getList("rule[@access]").size() == 0 &&
- getConfig().getString("[@default-action]") == null)
- {
- throw new ConfigurationException("No rules or default-action found in firewall configuration.");
- }
- }
-
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
deleted file mode 100644
index 8969363979..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ /dev/null
@@ -1,322 +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.access;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.net.InetSocketAddress;
-
-public class FirewallConfigurationTest extends QpidTestCase
-{
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
- public void testFirewallConfiguration() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.1.2.3", 65535)));
- }
-
- public void testCombinedConfigurationFirewall() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<cache-directory>${QPID_WORK}/cache</cache-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testCombinedConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException
- {
- FileWriter out = new FileWriter(vhostsFile);
- String ipAddr = "127.0.0.1"; // FIXME: get this from InetAddress.getLocalHost().getAddress() ?
- out.write("<virtualhosts><virtualhost>");
- out.write("<name>test</name>");
- out.write("<test>");
- out.write("<security><firewall>");
- out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\""+ipAddr +"\"/>");
- out.write("</firewall></security>");
- out.write("</test>");
- out.write("</virtualhost></virtualhosts>");
- out.close();
- }
-
- private void writeConfigFile(File mainFile, boolean allow) throws IOException {
- writeConfigFile(mainFile, allow, true, null, "test");
- }
-
- /*
- XMLConfiguration config = new XMLConfiguration(mainFile);
- PluginManager pluginManager = new MockPluginManager("");
- SecurityManager manager = new SecurityManager(config, pluginManager, Firewall.FACTORY);
-
- */
- private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- if (includeVhosts)
- {
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<default>test</default>\n");
- out.write("\t\t<virtualhost>\n");
- out.write(String.format("\t\t\t<name>%s</name>\n", name));
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- }
- if (vhostsFile != null)
- {
- out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n");
- }
- out.write("</broker>\n");
- out.close();
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file only.
- * <p>
- * Test for QPID-2360
- */
- public void testExternalFirewallVirtualhostXMLFile() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeConfigFile(mainFile, false, false, vhostsFile, null);
- writeFirewallVhostsFile(vhostsFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
-
- assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size());
- assertEquals("Incorrect virtualhost name", "test", virtualHost.getName());
- }
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
deleted file mode 100644
index 2004852c48..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
+++ /dev/null
@@ -1,294 +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.access;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.plugins.Firewall;
-import org.apache.qpid.server.security.access.plugins.FirewallConfiguration;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-public class FirewallPluginTest extends QpidTestCase
-{
- public class RuleInfo
- {
- private String _access;
- private String _network;
- private String _hostname;
-
- public void setAccess(String _access)
- {
- this._access = _access;
- }
-
- public String getAccess()
- {
- return _access;
- }
-
- public void setNetwork(String _network)
- {
- this._network = _network;
- }
-
- public String getNetwork()
- {
- return _network;
- }
-
- public void setHostname(String _hostname)
- {
- this._hostname = _hostname;
- }
-
- public String getHostname()
- {
- return _hostname;
- }
- }
-
- // IP address
- private SocketAddress _address;
- private ServerConfiguration _serverConfig;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- _serverConfig = new ServerConfiguration(new XMLConfiguration());
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
- _address = new InetSocketAddress("127.0.0.1", 65535);
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
- private Firewall initialisePlugin(String defaultAction, RuleInfo[] rules) throws IOException, ConfigurationException
- {
- // Create sample config file
- File confFile = File.createTempFile(getClass().getSimpleName()+"conffile", null);
- confFile.deleteOnExit();
- BufferedWriter buf = new BufferedWriter(new FileWriter(confFile));
- buf.write("<firewall default-action=\""+defaultAction+"\">\n");
- if (rules != null)
- {
- for (RuleInfo rule : rules)
- {
- buf.write("<rule");
- buf.write(" access=\""+rule.getAccess()+"\"");
- if (rule.getHostname() != null)
- {
- buf.write(" hostname=\""+rule.getHostname()+"\"");
- }
- if (rule.getNetwork() != null)
- {
- buf.write(" network=\""+rule.getNetwork()+"\"");
- }
- buf.write("/>\n");
- }
- }
- buf.write("</firewall>");
- buf.close();
-
- // Configure plugin
- FirewallConfiguration config = new FirewallConfiguration();
- config.setConfiguration("", new XMLConfiguration(confFile));
- Firewall plugin = new Firewall();
- plugin.configure(config);
- return plugin;
- }
-
- private Firewall initialisePlugin(String string) throws ConfigurationException, IOException
- {
- return initialisePlugin(string, null);
- }
-
- public void testDefaultAction() throws Exception
- {
- // Test simple deny
- Firewall plugin = initialisePlugin("deny");
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Test simple allow
- plugin = initialisePlugin("allow");
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
-
- public void testSingleIPRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleNetworkRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.0/24");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setHostname(new InetSocketAddress("127.0.0.1", 5672).getHostName());
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostWilcardRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- String hostname = new InetSocketAddress("127.0.0.1", 0).getHostName();
- rule.setHostname(".*"+hostname.subSequence(hostname.length() - 1, hostname.length())+"*");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralFirstAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.23");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("deny");
- thirdRule.setHostname("localhost");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralLastAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("deny");
- firstRule.setHostname("localhost");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("allow");
- thirdRule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("10.1.1.1/8, 192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedHostnames() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setHostname("foo, bar, "+new InetSocketAddress("127.0.0.1", 5672).getHostName());
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("10.0.0.1", 65535);
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-}
diff --git a/java/broker-plugins/management-http/MANIFEST.MF b/java/broker-plugins/management-http/MANIFEST.MF
deleted file mode 100644
index cca10d3f89..0000000000
--- a/java/broker-plugins/management-http/MANIFEST.MF
+++ /dev/null
@@ -1,70 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Management HTTP
-Bundle-SymbolicName: broker-plugins-management-http
-Bundle-Description: HTTP management plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.management.plugin.ManagementActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.common,
- org.apache.qpid.server.security.auth,
- org.apache.qpid.server.security.auth.manager,
- org.apache.qpid.server.security.auth.sasl,
- org.apache.qpid.server.binding,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.message,
- org.apache.qpid.server.model,
- org.apache.qpid.server.model.adapter,
- org.apache.qpid.server.model.impl,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.connection,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.protocol,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.subscription,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.stats,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.eclipse.jetty.server;version=7.6.3,
- org.eclipse.jetty.server.session;version=7.6.3,
- org.eclipse.jetty.server.ssl;version=7.6.3,
- org.eclipse.jetty.server.nio;version=7.6.3,
- org.eclipse.jetty.security;version=7.6.3,
- org.eclipse.jetty.http;version=7.6.3,
- org.eclipse.jetty.io;version=7.6.3,
- org.eclipse.jetty.io.nio;version=7.6.3,
- org.eclipse.jetty.servlet;version=7.6.3,
- org.eclipse.jetty.util.ssl;version=7.6.3,
- org.apache.commons.codec;version=1.3.0,
- org.apache.commons.codec.binary;version=1.3.0,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- org.codehaus.jackson;version=1.9.0,
- org.codehaus.jackson.map;version=1.9.0,
- javax.crypto,
- javax.crypto.spec,
- javax.security.auth,
- javax.security.auth.callback,
- javax.security.sasl,
- javax.servlet,
- javax.servlet.http,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.management.plugin.impl
-Export-Package: org.apache.qpid.server.management.plugin;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/management-http/build.xml b/java/broker-plugins/management-http/build.xml
index b792cb292e..abf35d9c88 100644
--- a/java/broker-plugins/management-http/build.xml
+++ b/java/broker-plugins/management-http/build.xml
@@ -18,39 +18,36 @@
-->
<project name="Qpid Broker-Plugins Management HTTP" default="build">
- <condition property="systests.optional.depends" value="bdbstore" else="">
- <or>
- <and>
- <contains string="${modules.opt}" substring="bdbstore"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- <and>
- <istrue value="${optional}"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- </or>
- </condition>
-
<property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="systests test broker/test common/test management/common client ${systests.optional.depends}" />
+ <property name="module.test.depends" value="broker/tests common/tests management/common client" />
+
+ <property name="module.genpom" value="true" />
+ <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
- <property name="module.genpom" value="true"/>
- <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
+ <property name="broker.plugin" value="true"/>
- <property name="broker-plugins-management-http.libs" value=""/>
+ <property name="broker-plugins-management-http.libs" value="" />
<import file="../../module.xml" />
- <target name="precompile">
- <unwar src="${project.root}/${dojo}" dest="${module.classes}/resources/dojo">
- <patternset>
- <exclude name="META-INF/**"/>
- <exclude name="WEB-INF/**"/>
- <exclude name="**/*.uncompressed.js"/>
- </patternset>
- </unwar>
+ <!-- Flagfile used to determine if uwar needs to be done. ._ is part of Ant's defaultexcludes so wont appear bundles -->
+ <property name="dojo.uptodate.flagfile" value="${module.classes}/resources/dojo/._dojouptodate.timestamp" />
+
+ <target name="precompile" depends="unwardojo" />
+
+ <target name="unwardojo" depends="check-unwardojo.done" unless="unwardojo.done">
+ <unwar src="${project.root}/${dojo}" dest="${module.classes}/resources/dojo">
+ <patternset>
+ <exclude name="META-INF/**" />
+ <exclude name="WEB-INF/**" />
+ <exclude name="**/*.uncompressed.js" />
+ </patternset>
+ </unwar>
+ <touch file="${dojo.uptodate.flagfile}" />
+ </target>
+
+ <target name="check-unwardojo.done">
+ <uptodate property="unwardojo.done" targetfile="${dojo.uptodate.flagfile}" srcfile="${project.root}/${dojo}" />
</target>
<target name="bundle" depends="bundle-tasks" />
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
new file mode 100644
index 0000000000..c2ac675e20
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -0,0 +1,416 @@
+/*
+ *
+ * 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.plugin;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
+import org.apache.qpid.server.management.plugin.servlet.FileServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.AbstractServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.LogoutServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.MessageServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.SaslServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.StructureServlet;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.Broker;
+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.Group;
+import org.apache.qpid.server.model.GroupMember;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.Session;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.User;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+public class HttpManagement extends AbstractPluginAdapter
+{
+ private final Logger _logger = Logger.getLogger(HttpManagement.class);
+
+ // 10 minutes by default
+ public static final int DEFAULT_TIMEOUT_IN_SECONDS = 60 * 10;
+ public static final boolean DEFAULT_HTTP_BASIC_AUTHENTICATION_ENABLED = false;
+ public static final boolean DEFAULT_HTTPS_BASIC_AUTHENTICATION_ENABLED = true;
+ public static final boolean DEFAULT_HTTP_SASL_AUTHENTICATION_ENABLED = true;
+ public static final boolean DEFAULT_HTTPS_SASL_AUTHENTICATION_ENABLED = true;
+ public static final String DEFAULT_NAME = "httpManagement";
+
+ public static final String TIME_OUT = "sessionTimeout";
+ public static final String HTTP_BASIC_AUTHENTICATION_ENABLED = "httpBasicAuthenticationEnabled";
+ public static final String HTTPS_BASIC_AUTHENTICATION_ENABLED = "httpsBasicAuthenticationEnabled";
+ public static final String HTTP_SASL_AUTHENTICATION_ENABLED = "httpSaslAuthenticationEnabled";
+ public static final String HTTPS_SASL_AUTHENTICATION_ENABLED = "httpsSaslAuthenticationEnabled";
+
+ public static final String PLUGIN_TYPE = "MANAGEMENT-HTTP";
+
+ @SuppressWarnings("serial")
+ private static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<String>(Plugin.AVAILABLE_ATTRIBUTES)
+ {{
+ add(HTTP_BASIC_AUTHENTICATION_ENABLED);
+ add(HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ add(HTTP_SASL_AUTHENTICATION_ENABLED);
+ add(HTTPS_SASL_AUTHENTICATION_ENABLED);
+ add(TIME_OUT);
+ add(PluginFactory.PLUGIN_TYPE);
+ }});
+
+ public static final String ENTRY_POINT_PATH = "/management";
+
+ private static final String OPERATIONAL_LOGGING_NAME = "Web";
+
+
+ @SuppressWarnings("serial")
+ public static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>()
+ {{
+ put(HTTP_BASIC_AUTHENTICATION_ENABLED, DEFAULT_HTTP_BASIC_AUTHENTICATION_ENABLED);
+ put(HTTPS_BASIC_AUTHENTICATION_ENABLED, DEFAULT_HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ put(HTTP_SASL_AUTHENTICATION_ENABLED, DEFAULT_HTTP_SASL_AUTHENTICATION_ENABLED);
+ put(HTTPS_SASL_AUTHENTICATION_ENABLED, DEFAULT_HTTPS_SASL_AUTHENTICATION_ENABLED);
+ put(TIME_OUT, DEFAULT_TIMEOUT_IN_SECONDS);
+ put(NAME, DEFAULT_NAME);
+ }});
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{
+ put(HTTP_BASIC_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTPS_BASIC_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTP_SASL_AUTHENTICATION_ENABLED, Boolean.class);
+ put(HTTPS_SASL_AUTHENTICATION_ENABLED, Boolean.class);
+ put(NAME, String.class);
+ put(TIME_OUT, Integer.class);
+ put(PluginFactory.PLUGIN_TYPE, String.class);
+ }});
+
+ private final Broker _broker;
+
+ private Server _server;
+
+ public HttpManagement(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), broker.getTaskExecutor());
+ _broker = broker;
+ addParent(Broker.class, broker);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.ACTIVE)
+ {
+ start();
+ return true;
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ stop();
+ return true;
+ }
+ return false;
+ }
+
+ private void start()
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
+
+ Collection<Port> httpPorts = getHttpPorts(_broker.getPorts());
+ _server = createServer(httpPorts);
+ try
+ {
+ _server.start();
+ logOperationalListenMessages(_server);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to start http management on ports " + httpPorts);
+ }
+
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
+ }
+
+ private void stop()
+ {
+ if (_server != null)
+ {
+ try
+ {
+ _server.stop();
+ logOperationalShutdownMessage(_server);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to stop http management on port " + getHttpPorts(_broker.getPorts()));
+ }
+ }
+
+ CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
+ }
+
+ /** Added for testing purposes */
+ Broker getBroker()
+ {
+ return _broker;
+ }
+
+ /** Added for testing purposes */
+ int getSessionTimeout()
+ {
+ return (Integer)getAttribute(TIME_OUT);
+ }
+
+ private boolean isManagementHttp(Port port)
+ {
+ return port.getProtocols().contains(Protocol.HTTP) || port.getProtocols().contains(Protocol.HTTPS);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Server createServer(Collection<Port> ports)
+ {
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Starting up web server on " + ports);
+ }
+
+ Server server = new Server();
+ for (Port port : ports)
+ {
+ if (State.QUIESCED.equals(port.getActualState()))
+ {
+ continue;
+ }
+ final Collection<Protocol> protocols = port.getProtocols();
+ Connector connector = null;
+
+ //TODO: what to do if protocol HTTP and transport SSL?
+ if (protocols.contains(Protocol.HTTP))
+ {
+ connector = new SelectChannelConnector();
+ }
+ else if (protocols.contains(Protocol.HTTPS))
+ {
+ KeyStore keyStore = _broker.getDefaultKeyStore();
+ if (keyStore == null)
+ {
+ throw new IllegalConfigurationException("Key store is not configured. Cannot start management on HTTPS port without keystore");
+ }
+ String keyStorePath = (String)keyStore.getAttribute(KeyStore.PATH);
+ String keyStorePassword = keyStore.getPassword();
+ validateKeystoreParameters(keyStorePath, keyStorePassword);
+
+ SslContextFactory factory = new SslContextFactory();
+ factory.setKeyStorePath(keyStorePath);
+ factory.setKeyStorePassword(keyStorePassword);
+
+ connector = new SslSocketConnector(factory);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unexpected protocol " + protocols);
+ }
+ connector.setPort(port.getPort());
+ server.addConnector(connector);
+ }
+
+ ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ root.setContextPath("/");
+ server.setHandler(root);
+
+ // set servlet context attributes for broker and configuration
+ root.getServletContext().setAttribute(AbstractServlet.ATTR_BROKER, _broker);
+ root.getServletContext().setAttribute(AbstractServlet.ATTR_MANAGEMENT, this);
+
+ addRestServlet(root, "broker");
+ addRestServlet(root, "virtualhost", VirtualHost.class);
+ addRestServlet(root, "authenticationprovider", AuthenticationProvider.class);
+ addRestServlet(root, "user", AuthenticationProvider.class, User.class);
+ addRestServlet(root, "groupprovider", GroupProvider.class);
+ addRestServlet(root, "group", GroupProvider.class, Group.class);
+ addRestServlet(root, "groupmember", GroupProvider.class, Group.class, GroupMember.class);
+ addRestServlet(root, "exchange", VirtualHost.class, Exchange.class);
+ addRestServlet(root, "queue", VirtualHost.class, Queue.class);
+ addRestServlet(root, "connection", VirtualHost.class, Connection.class);
+ addRestServlet(root, "binding", VirtualHost.class, Exchange.class, Queue.class, Binding.class);
+ addRestServlet(root, "port", Port.class);
+ addRestServlet(root, "session", VirtualHost.class, Connection.class, Session.class);
+
+ root.addServlet(new ServletHolder(new StructureServlet()), "/rest/structure");
+ root.addServlet(new ServletHolder(new MessageServlet()), "/rest/message/*");
+ root.addServlet(new ServletHolder(new MessageContentServlet()), "/rest/message-content/*");
+
+ root.addServlet(new ServletHolder(new LogRecordsServlet()), "/rest/logrecords");
+
+ root.addServlet(new ServletHolder(new SaslServlet()), "/rest/sasl");
+
+ root.addServlet(new ServletHolder(new DefinedFileServlet("index.html")), ENTRY_POINT_PATH);
+ root.addServlet(new ServletHolder(new LogoutServlet()), "/logout");
+
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.js");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.css");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.html");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.png");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.gif");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpg");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpeg");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.json");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
+ root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
+
+ final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
+
+ sessionManager.setMaxInactiveInterval((Integer)getAttribute(TIME_OUT));
+
+ return server;
+ }
+
+ private void addRestServlet(ServletContextHandler root, String name, Class<? extends ConfiguredObject>... hierarchy)
+ {
+ root.addServlet(new ServletHolder(new RestServlet(hierarchy)), "/rest/" + name + "/*");
+ }
+
+ private void validateKeystoreParameters(String keyStorePath, String password)
+ {
+ if (keyStorePath == null)
+ {
+ throw new RuntimeException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
+ }
+ if (password == null)
+ {
+ throw new RuntimeException("Management SSL keystore password, unable to start SSL protected HTTP connector");
+ }
+ File ksf = new File(keyStorePath);
+ if (!ksf.exists())
+ {
+ throw new RuntimeException("Cannot find management SSL keystore file: " + ksf);
+ }
+ if (!ksf.canRead())
+ {
+ throw new RuntimeException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
+ }
+ }
+
+ private void logOperationalListenMessages(Server server)
+ {
+ Connector[] connectors = server.getConnectors();
+ for (Connector connector : connectors)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING(stringifyConnectorScheme(connector), connector.getPort()));
+ if (connector instanceof SslSocketConnector)
+ {
+ SslContextFactory sslContextFactory = ((SslSocketConnector)connector).getSslContextFactory();
+ if (sslContextFactory != null && sslContextFactory.getKeyStorePath() != null)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(sslContextFactory.getKeyStorePath()));
+ }
+ }
+ }
+ }
+
+ private void logOperationalShutdownMessage(Server server)
+ {
+ Connector[] connectors = server.getConnectors();
+ for (Connector connector : connectors)
+ {
+ CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN(stringifyConnectorScheme(connector), connector.getPort()));
+ }
+ }
+
+ private String stringifyConnectorScheme(Connector connector)
+ {
+ return connector instanceof SslSocketConnector ? "HTTPS" : "HTTP";
+ }
+
+ private Collection<Port> getHttpPorts(Collection<Port> ports)
+ {
+ Collection<Port> httpPorts = new HashSet<Port>();
+ for (Port port : ports)
+ {
+ if (isManagementHttp(port))
+ {
+ httpPorts.add(port);
+ }
+ }
+ return httpPorts;
+ }
+
+
+ @Override
+ public String getName()
+ {
+ return (String)getAttribute(NAME);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Collections.unmodifiableCollection(AVAILABLE_ATTRIBUTES);
+ }
+
+ public boolean isHttpsSaslAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTPS_SASL_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpSaslAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTP_SASL_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpsBasicAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTPS_BASIC_AUTHENTICATION_ENABLED);
+ }
+
+ public boolean isHttpBasicAuthenticationEnabled()
+ {
+ return (Boolean)getAttribute(HTTP_BASIC_AUTHENTICATION_ENABLED);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
index 233134abc5..ccf5373234 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementFactory.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,26 +15,27 @@
* 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;
+package org.apache.qpid.server.management.plugin;
import java.util.Map;
+import java.util.UUID;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
-public interface BindingConfig extends ConfiguredObject<BindingConfigType, BindingConfig>
+public class HttpManagementFactory implements PluginFactory
{
- ExchangeConfig getExchange();
-
- QueueConfig getQueue();
-
- String getBindingKey();
-
- Map<String, Object> getArguments();
-
- String getOrigin();
-
- long getMatches();
-} \ No newline at end of file
+ @Override
+ public Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker)
+ {
+ if (!HttpManagement.PLUGIN_TYPE.equals(attributes.get(PLUGIN_TYPE)))
+ {
+ return null;
+ }
+
+ return new HttpManagement(id, broker, attributes);
+ }
+}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java
deleted file mode 100644
index c2f9b73b54..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/Management.java
+++ /dev/null
@@ -1,248 +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.plugin;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
-import org.apache.qpid.server.management.plugin.servlet.FileServlet;
-import org.apache.qpid.server.management.plugin.servlet.api.ExchangesServlet;
-import org.apache.qpid.server.management.plugin.servlet.api.VhostsServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.MessageContentServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.MessageServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.RestServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.SaslServlet;
-import org.apache.qpid.server.management.plugin.servlet.rest.StructureServlet;
-import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.model.Binding;
-import org.apache.qpid.server.model.Broker;
-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.Port;
-import org.apache.qpid.server.model.Protocol;
-import org.apache.qpid.server.model.Queue;
-import org.apache.qpid.server.model.Session;
-import org.apache.qpid.server.model.Transport;
-import org.apache.qpid.server.model.User;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.server.ssl.SslSocketConnector;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-public class Management
-{
-
- private final Logger _logger = Logger.getLogger(Management.class);
-
- private Broker _broker;
-
- private Collection<Server> _servers = new ArrayList<Server>();
-
- public Management() throws ConfigurationException, IOException
- {
- _broker = ApplicationRegistry.getInstance().getBroker();
-
- Collection<Port> ports = _broker.getPorts();
- int httpPort = -1, httpsPort = -1;
- for (Port port : ports)
- {
- if (port.getProtocols().contains(Protocol.HTTP))
- {
- if (port.getTransports().contains(Transport.TCP))
- {
- httpPort = port.getPort();
- }
- }
- if (port.getProtocols().contains(Protocol.HTTPS))
- {
- if (port.getTransports().contains(Transport.SSL))
- {
- httpsPort = port.getPort();
- }
- }
- }
-
- if (httpPort != -1 || httpsPort != -1)
- {
- _servers.add(createServer(httpPort, httpsPort));
- if (_logger.isDebugEnabled())
- {
- _logger.debug(_servers.size() + " server(s) defined");
- }
- }
- else
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Cannot create web server as neither HTTP nor HTTPS port specified");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private Server createServer(int port, int sslPort) throws IOException, ConfigurationException
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Starting up web server on" + (port == -1 ? "" : " HTTP port " + port)
- + (sslPort == -1 ? "" : " HTTPS port " + sslPort));
- }
-
- Server server = new Server();
-
- if (port != -1)
- {
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setPort(port);
- if (sslPort != -1)
- {
- connector.setConfidentialPort(sslPort);
- }
- server.addConnector(connector);
- }
-
- if (sslPort != -1)
- {
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- String keyStorePath = getKeyStorePath(appRegistry);
-
- SslContextFactory factory = new SslContextFactory();
- factory.setKeyStorePath(keyStorePath);
- factory.setKeyStorePassword(appRegistry.getConfiguration().getManagementKeyStorePassword());
-
- SslSocketConnector connector = new SslSocketConnector(factory);
- connector.setPort(sslPort);
- server.addConnector(connector);
- }
-
- ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
- root.setContextPath("/");
- server.setHandler(root);
-
- root.addServlet(new ServletHolder(new VhostsServlet(_broker)), "/api/vhosts/*");
- root.addServlet(new ServletHolder(new ExchangesServlet(_broker)), "/api/exchanges/*");
-
- addRestServlet(root, "broker");
- addRestServlet(root, "virtualhost", VirtualHost.class);
- addRestServlet(root, "authenticationprovider", AuthenticationProvider.class);
- addRestServlet(root, "user", AuthenticationProvider.class, User.class);
- addRestServlet(root, "exchange", VirtualHost.class, Exchange.class);
- addRestServlet(root, "queue", VirtualHost.class, Queue.class);
- addRestServlet(root, "connection", VirtualHost.class, Connection.class);
- addRestServlet(root, "binding", VirtualHost.class, Exchange.class, Queue.class, Binding.class);
- addRestServlet(root, "port", Port.class);
- addRestServlet(root, "session", VirtualHost.class, Connection.class, Session.class);
-
- root.addServlet(new ServletHolder(new StructureServlet(_broker)), "/rest/structure");
- root.addServlet(new ServletHolder(new MessageServlet(_broker)), "/rest/message/*");
- root.addServlet(new ServletHolder(new MessageContentServlet(_broker)), "/rest/message-content/*");
-
- root.addServlet(new ServletHolder(new LogRecordsServlet(_broker)), "/rest/logrecords");
-
- root.addServlet(new ServletHolder(new SaslServlet(_broker)), "/rest/sasl");
-
- root.addServlet(new ServletHolder(new DefinedFileServlet("management.html")), "/management");
-
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.js");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.css");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.html");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.png");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.gif");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpg");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.jpeg");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.json");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.txt");
- root.addServlet(new ServletHolder(FileServlet.INSTANCE), "*.xsl");
-
- final SessionManager sessionManager = root.getSessionHandler().getSessionManager();
-
- sessionManager.setMaxInactiveInterval(60 * 15);
-
- return server;
- }
-
- private void addRestServlet(ServletContextHandler root, String name, Class<? extends ConfiguredObject>... hierarchy)
- {
- root.addServlet(new ServletHolder(new RestServlet(_broker, hierarchy)), "/rest/" + name + "/*");
- }
-
- public void start() throws Exception
- {
- for (Server server : _servers)
- {
- server.start();
- }
- }
-
- public void stop() throws Exception
- {
- for (Server server : _servers)
- {
- server.stop();
- }
- }
-
- private String getKeyStorePath(IApplicationRegistry appRegistry) throws ConfigurationException, FileNotFoundException
- {
- String keyStorePath = null;
- if (System.getProperty("javax.net.ssl.keyStore") != null)
- {
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
- }
- else
- {
- keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
- }
-
- if (keyStorePath == null)
- {
- throw new ConfigurationException("Management SSL keystore path not defined, unable to start SSL protected HTTP connector");
- }
- else
- {
- File ksf = new File(keyStorePath);
- if (!ksf.exists())
- {
- throw new FileNotFoundException("Cannot find management SSL keystore file: " + ksf);
- }
- if (!ksf.canRead())
- {
- throw new FileNotFoundException("Cannot read management SSL keystore file: " + ksf + ". Check permissions.");
- }
- }
- return keyStorePath;
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java
deleted file mode 100644
index 09b7e08bfb..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementActivator.java
+++ /dev/null
@@ -1,73 +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.plugin;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class ManagementActivator implements BundleActivator
-{
- private static final Logger _logger = Logger.getLogger(ManagementActivator.class);
-
-
- private BundleContext _ctx;
- private String _bundleName;
- private Management _managementService;
-
-
- public void start(final BundleContext ctx) throws Exception
- {
- _ctx = ctx;
- if (!ApplicationRegistry.getInstance().getConfiguration().getHTTPManagementEnabled()
- && !ApplicationRegistry.getInstance().getConfiguration().getHTTPSManagementEnabled())
- {
- _logger.info("Management plugin is disabled!");
- ctx.getBundle().uninstall();
- return;
- }
- _managementService = new Management();
- _managementService.start();
- _bundleName = ctx.getBundle().getSymbolicName();
-
- // register the service
- _logger.info("Registering management plugin: " + _bundleName);
- _ctx.registerService(Management.class.getName(), _managementService, null);
- _ctx.registerService(ConfigurationPluginFactory.class.getName(), ManagementConfiguration.FACTORY, null);
- }
-
- public void stop(final BundleContext bundleContext) throws Exception
- {
- if (_managementService != null)
- {
- _logger.info("Stopping management plugin: " + _bundleName);
-
- _managementService.stop();
-
- // null object references
- _managementService = null;
- }
- _ctx = null;
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java
deleted file mode 100644
index 3866da8f89..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ManagementConfiguration.java
+++ /dev/null
@@ -1,77 +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.plugin;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-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.configuration.plugins.ConfigurationPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class ManagementConfiguration extends ConfigurationPlugin
-{
- CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new ManagementConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("management");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
index d8a8395550..e6ae47dcff 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/DefinedFileServlet.java
@@ -73,7 +73,7 @@ public class DefinedFileServlet extends HttpServlet
}
else
{
- response.sendError(404, "unknown file: "+ _filename);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "unknown file: "+ _filename);
}
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
index f8ca082d79..24e5e7c049 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
@@ -20,11 +20,8 @@
*/
package org.apache.qpid.server.management.plugin.servlet;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
@@ -101,7 +98,7 @@ public class FileServlet extends HttpServlet
}
else
{
- response.sendError(404, "unknown file: "+ filename);
+ response.sendError(HttpServletResponse.SC_NOT_FOUND, "unknown file: "+ filename);
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java
deleted file mode 100644
index a3c5ec68a2..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/ExchangesServlet.java
+++ /dev/null
@@ -1,208 +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.plugin.servlet.api;
-
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.ObjectReader;
-
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.Exchange;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ExchangesServlet extends HttpServlet
-{
-
-
- private Broker _broker;
-
- public ExchangesServlet()
- {
- super();
- _broker = ApplicationRegistry.getInstance().getBroker();
- }
-
- public ExchangesServlet(Broker broker)
- {
- _broker = broker;
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_OK);
-
- Collection<VirtualHost> vhosts = _broker.getVirtualHosts();
- Collection<Exchange> exchanges = new ArrayList<Exchange>();
- Collection<Map<String,Object>> outputObject = new ArrayList<Map<String,Object>>();
-
- final PrintWriter writer = response.getWriter();
-
- ObjectMapper mapper = new ObjectMapper();
- String vhostName = null;
- String exchangeName = null;
-
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String path = request.getPathInfo().substring(1);
- String[] parts = path.split("/");
- vhostName = parts.length == 0 ? "" : parts[0];
- if(parts.length > 1)
- {
- exchangeName = parts[1];
- }
- }
-
- for(VirtualHost vhost : vhosts)
- {
- if(vhostName == null || vhostName.equals(vhost.getName()))
- {
- for(Exchange exchange : vhost.getExchanges())
- {
- if(exchangeName == null || exchangeName.equals(exchange.getName()))
- {
- outputObject.add(convertToObject(exchange));
- if(exchangeName != null)
- {
- break;
- }
- }
- }
- if(vhostName != null)
- {
- break;
- }
- }
- }
-
- mapper.writeValue(writer, outputObject);
-
- }
-
- private Map<String,Object> convertToObject(final Exchange exchange)
- {
- Map<String, Object> object = new LinkedHashMap<String, Object>();
- object.put("name",exchange.getName());
- object.put("type", exchange.getExchangeType());
- object.put("durable", exchange.isDurable());
- object.put("auto-delete", exchange.getLifetimePolicy() == LifetimePolicy.AUTO_DELETE);
-
- Map<String,Object> arguments = new HashMap<String, Object>();
- for(String key : exchange.getAttributeNames())
- {
- if(!key.equals(Exchange.TYPE))
- {
- arguments.put(key, exchange.getAttribute(key));
- }
- }
- object.put("arguments", arguments);
- return object;
- }
-
- protected void doPut(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
- {
-
- response.setContentType("application/json");
-
-
- String vhostName = null;
- String exchangeName = null;
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String path = request.getPathInfo().substring(1);
- String[] parts = path.split("/");
- vhostName = parts.length == 0 ? "" : parts[0];
- if(parts.length > 1)
- {
- exchangeName = parts[1];
- }
- }
- if(vhostName == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else if (exchangeName == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else
- {
- VirtualHost vhost = null;
- for(VirtualHost host : _broker.getVirtualHosts())
- {
- if(host.getName().equals(vhostName))
- {
- vhost = host;
- }
- }
- if(vhost == null)
- {
- response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED);
- }
- else
- {
- response.setStatus(HttpServletResponse.SC_NO_CONTENT);
- ObjectMapper mapper = new ObjectMapper();
- Map<String,Object> exchangeObject = mapper.readValue(request.getInputStream(), LinkedHashMap.class);
-
- final boolean isDurable = exchangeObject.get("durable") instanceof Boolean
- && ((Boolean)exchangeObject.get("durable"));
- final boolean isAutoDelete = exchangeObject.get("auto_delete") instanceof Boolean
- && ((Boolean)exchangeObject.get("auto_delete"));
-
- final String type = (String) exchangeObject.get("type");
- final Map<String, Object> attributes = new HashMap<String, Object>(exchangeObject);
- attributes.remove("durable");
- attributes.remove("auto_delete");
- attributes.remove("type");
-
- vhost.createExchange(exchangeName, State.ACTIVE, isDurable,
- isAutoDelete ? LifetimePolicy.AUTO_DELETE : LifetimePolicy.PERMANENT,
- 0l,
- type,
- attributes);
- }
-
-
-
- }
-
-
-
- }
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java
deleted file mode 100644
index b2c0fcfe52..0000000000
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/api/VhostsServlet.java
+++ /dev/null
@@ -1,118 +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.plugin.servlet.api;
-
-import org.codehaus.jackson.map.ObjectMapper;
-
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.LifetimePolicy;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.*;
-
-public class VhostsServlet extends HttpServlet
-{
-
-
- private Broker _broker;
-
- public VhostsServlet()
- {
- super();
- _broker = ApplicationRegistry.getInstance().getBroker();
- }
-
- public VhostsServlet(Broker broker)
- {
- _broker = broker;
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
- {
-System.out.println("Get /api/vhosts");
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_OK);
-
- Collection<VirtualHost> vhosts = _broker.getVirtualHosts();
-
-
-
- final PrintWriter writer = response.getWriter();
-
- ObjectMapper mapper = new ObjectMapper();
-
- if(request.getPathInfo() == null || request.getPathInfo().length()==0)
- {
-
- LinkedHashMap<String, Object> vhostObject = new LinkedHashMap<String, Object>();
- List<Map> vhostList = new ArrayList<Map>();
-
- for(VirtualHost vhost : vhosts)
- {
- vhostList.add(Collections.singletonMap("name", vhost.getName()));
- }
- mapper.writeValue(writer, vhostList);
- }
- else
- {
- LinkedHashMap<String, Object> vhostObject = new LinkedHashMap<String, Object>();
- String vhostName = request.getPathInfo().substring(1);
-
- for(VirtualHost vhost : vhosts)
- {
- if(vhostName.equals(vhost.getName()))
- {
- vhostObject.put("name", vhost.getName());
- break;
- }
- }
- mapper.writeValue(writer, vhostObject);
- }
- }
-
-
- protected void doPut(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
- {
-
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_NO_CONTENT);
-
- if(request.getPathInfo() != null && request.getPathInfo().length()>0)
- {
- String vhostName = request.getPathInfo().substring(1);
- _broker.createVirtualHost(vhostName, State.ACTIVE, true, LifetimePolicy.PERMANENT, 0L, Collections.EMPTY_MAP);
- }
-
-
- }
-}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
index a76bd98179..689bdb50d8 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
@@ -18,191 +18,456 @@
* under the License.
*
*/
-
package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.security.Principal;
-import java.util.Collections;
+import java.security.AccessControlException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
import javax.security.auth.Subject;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.HttpManagementActor;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter;
import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
public abstract class AbstractServlet extends HttpServlet
{
- private final Broker _broker;
+ private static final Logger LOGGER = Logger.getLogger(AbstractServlet.class);
+
+ /**
+ * Servlet context attribute holding a reference to a broker instance
+ */
+ public static final String ATTR_BROKER = "Qpid.broker";
+
+ /**
+ * Servlet context attribute holding a reference to plugin configuration
+ */
+ public static final String ATTR_MANAGEMENT = "Qpid.management";
+
+ private static final String ATTR_LOGIN_LOGOUT_REPORTER = "AbstractServlet.loginLogoutReporter";
+ private static final String ATTR_SUBJECT = "AbstractServlet.subject";
+ private static final String ATTR_LOG_ACTOR = "AbstractServlet.logActor";
+
+ private Broker _broker;
+ private RootMessageLogger _rootLogger;
+ private HttpManagement _httpManagement;
protected AbstractServlet()
{
super();
- _broker = ApplicationRegistry.getInstance().getBroker();
}
- protected AbstractServlet(Broker broker)
+ @Override
+ public void init() throws ServletException
{
- _broker = broker;
+ ServletConfig servletConfig = getServletConfig();
+ ServletContext servletContext = servletConfig.getServletContext();
+ _broker = (Broker)servletContext.getAttribute(ATTR_BROKER);
+ _rootLogger = _broker.getRootMessageLogger();
+ _httpManagement = (HttpManagement)servletContext.getAttribute(ATTR_MANAGEMENT);
+ super.init();
}
@Override
- protected final void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ protected final void doGet(final HttpServletRequest request, final HttpServletResponse resp)
{
- setAuthorizedSubject(request);
- try
- {
- onGet(request, resp);
- }
- finally
- {
- clearAuthorizedSubject();
- }
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doGetWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
+ }
+
+ /**
+ * Performs the GET action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("GET not supported by this servlet");
+ }
+
+
+ @Override
+ protected final void doPost(final HttpServletRequest request, final HttpServletResponse resp)
+ {
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doPostWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
+ }
+
+ /**
+ * Performs the POST action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doPostWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("POST not supported by this servlet");
+ }
+
+ @Override
+ protected final void doPut(final HttpServletRequest request, final HttpServletResponse resp)
+ {
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doPutWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
}
- protected void onGet(HttpServletRequest request, HttpServletResponse resp) throws IOException, ServletException
+ /**
+ * Performs the PUT action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doPutWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
- super.doGet(request, resp);
+ throw new UnsupportedOperationException("PUT not supported by this servlet");
}
- private void clearAuthorizedSubject()
+ @Override
+ protected final void doDelete(final HttpServletRequest request, final HttpServletResponse resp)
+ throws ServletException, IOException
{
- org.apache.qpid.server.security.SecurityManager.setThreadSubject(null);
+ doWithSubjectAndActor(
+ new PrivilegedExceptionAction<Void>()
+ {
+ @Override
+ public Void run() throws Exception
+ {
+ doDeleteWithSubjectAndActor(request, resp);
+ return null;
+ }
+ },
+ request,
+ resp
+ );
}
+ /**
+ * Performs the PUT action as the logged-in {@link Subject}.
+ * The {@link LogActor} is set before this method is called.
+ * Subclasses commonly override this method
+ */
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ {
+ throw new UnsupportedOperationException("DELETE not supported by this servlet");
+ }
- private void setAuthorizedSubject(HttpServletRequest request)
+ private void doWithSubjectAndActor(
+ PrivilegedExceptionAction<Void> privilegedExceptionAction,
+ final HttpServletRequest request,
+ final HttpServletResponse resp)
{
- HttpSession session = request.getSession(true);
- Subject subject = (Subject) session.getAttribute("subject");
+ Subject subject;
+ try
+ {
+ subject = getAndCacheAuthorizedSubject(request);
+ }
+ catch (AccessControlException e)
+ {
+ sendError(resp, HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
- if(subject == null)
+ SecurityManager.setThreadSubject(subject);
+ try
{
- Principal principal = request.getUserPrincipal();
- if(principal != null)
+ HttpManagementActor logActor = getLogActorAndCacheInSession(request);
+ CurrentActor.set(logActor);
+ try
+ {
+ Subject.doAs(subject, privilegedExceptionAction);
+ }
+ catch(RuntimeException e)
{
- subject = new Subject(false, Collections.singleton(principal),Collections.emptySet(),
- Collections.emptySet());
+ LOGGER.error("Unable to perform action", e);
+ throw e;
}
- else
+ catch (PrivilegedActionException e)
{
- String header = request.getHeader("Authorization");
+ LOGGER.error("Unable to perform action", e);
+ throw new RuntimeException(e.getCause());
+ }
+ finally
+ {
+ CurrentActor.remove();
+ }
+ }
+ finally
+ {
+ try
+ {
+ SecurityManager.setThreadSubject(null);
+ }
+ finally
+ {
+ AMQShortString.clearLocalCache();
+ }
+ }
+ }
+
+ /**
+ * Gets the logged-in {@link Subject} by trying the following:
+ *
+ * <ul>
+ * <li>Get it from the session</li>
+ * <li>Get it from the request</li>
+ * <li>Log in using the username and password in the Authorization HTTP header</li>
+ * <li>Create a Subject representing the anonymous user.</li>
+ * </ul>
+ *
+ * If an authenticated subject is found it is cached in the http session.
+ */
+ private Subject getAndCacheAuthorizedSubject(HttpServletRequest request)
+ {
+ HttpSession session = request.getSession();
+ Subject subject = getAuthorisedSubjectFromSession(session);
- /*
- * TODO - Should configure whether basic authentication is allowed... and in particular whether it
- * should be allowed over non-ssl connections
- * */
+ if(subject != null)
+ {
+ return subject;
+ }
- if (header != null)
+ SubjectCreator subjectCreator = getSubjectCreator(request);
+ subject = authenticate(request, subjectCreator);
+ if (subject != null)
+ {
+ authoriseManagement(request, subject);
+ setAuthorisedSubjectInSession(subject, request, session);
+ }
+ else
+ {
+ subject = subjectCreator.createSubjectWithGroups(AnonymousAuthenticationManager.ANONYMOUS_USERNAME);
+ }
+
+ return subject;
+ }
+
+ protected void authoriseManagement(HttpServletRequest request, Subject subject)
+ {
+ // TODO: We should eliminate SecurityManager.setThreadSubject in favour of Subject.doAs
+ SecurityManager.setThreadSubject(subject); // Required for accessManagement check
+ LogActor actor = createHttpManagementActor(request);
+ CurrentActor.set(actor);
+ try
+ {
+ try
+ {
+ Subject.doAs(subject, new PrivilegedExceptionAction<Void>() // Required for proper logging of Subject
{
- String[] tokens = header.split("\\s");
- if(tokens.length >= 2
- && "BASIC".equalsIgnoreCase(tokens[0]))
+ @Override
+ public Void run() throws Exception
{
- String[] credentials = (new String(Base64.decodeBase64(tokens[1].getBytes()))).split(":",2);
- if(credentials.length == 2)
+ boolean allowed = getSecurityManager().accessManagement();
+ if (!allowed)
{
- SocketAddress address = getSocketAddress(request);
- AuthenticationManager authenticationManager =
- ApplicationRegistry.getInstance().getAuthenticationManager(address);
- AuthenticationResult authResult =
- authenticationManager.authenticate(credentials[0], credentials[1]);
- subject = authResult.getSubject();
-
+ throw new AccessControlException("User is not authorised for management");
}
+ return null;
}
- }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw new RuntimeException("Unable to perform access check", e);
}
}
- if (subject == null)
+ finally
{
- subject = AnonymousAuthenticationManager.ANONYMOUS_SUBJECT;
+ try
+ {
+ CurrentActor.remove();
+ }
+ finally
+ {
+ SecurityManager.setThreadSubject(null);
+ }
}
- org.apache.qpid.server.security.SecurityManager.setThreadSubject(subject);
-
}
- protected Subject getSubject(HttpSession session)
+ private Subject authenticate(HttpServletRequest request, SubjectCreator subjectCreator)
{
- return (Subject)session.getAttribute("subject");
+ Subject subject = null;
+
+ String remoteUser = request.getRemoteUser();
+ if(remoteUser != null)
+ {
+ subject = authenticateUserAndGetSubject(subjectCreator, remoteUser, null);
+ }
+ else
+ {
+ String header = request.getHeader("Authorization");
+
+ if (header != null)
+ {
+ String[] tokens = header.split("\\s");
+ if(tokens.length >= 2 && "BASIC".equalsIgnoreCase(tokens[0]))
+ {
+ if(!isBasicAuthSupported(request))
+ {
+ //TODO: write a return response indicating failure?
+ throw new IllegalArgumentException("BASIC Authorization is not enabled.");
+ }
+
+ subject = performBasicAuth(subject, subjectCreator, tokens[1]);
+ }
+ }
+ }
+
+ return subject;
}
- @Override
- protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private Subject performBasicAuth(Subject subject,SubjectCreator subjectCreator, String base64UsernameAndPassword)
{
- setAuthorizedSubject(req);
- try
+ String[] credentials = (new String(Base64.decodeBase64(base64UsernameAndPassword.getBytes()))).split(":",2);
+ if(credentials.length == 2)
{
- onPost(req, resp);
+ subject = authenticateUserAndGetSubject(subjectCreator, credentials[0], credentials[1]);
}
- finally
+ else
{
- clearAuthorizedSubject();
+ //TODO: write a return response indicating failure?
+ throw new AccessControlException("Invalid number of credentials supplied: "
+ + credentials.length);
}
+ return subject;
+ }
+ private Subject authenticateUserAndGetSubject(SubjectCreator subjectCreator, String username, String password)
+ {
+ SubjectAuthenticationResult authResult = subjectCreator.authenticate(username, password);
+ if( authResult.getStatus() != AuthenticationStatus.SUCCESS)
+ {
+ //TODO: write a return response indicating failure?
+ throw new AccessControlException("Incorrect username or password");
+ }
+ Subject subject = authResult.getSubject();
+ return subject;
}
- protected void onPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private boolean isBasicAuthSupported(HttpServletRequest req)
{
- super.doPost(req, resp);
+ return req.isSecure() ? _httpManagement.isHttpsBasicAuthenticationEnabled()
+ : _httpManagement.isHttpBasicAuthenticationEnabled();
}
- @Override
- protected final void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private HttpManagementActor getLogActorAndCacheInSession(HttpServletRequest req)
{
- setAuthorizedSubject(req);
- try
- {
- onPut(req, resp);
+ HttpSession session = req.getSession();
- }
- finally
+ HttpManagementActor actor = (HttpManagementActor) session.getAttribute(ATTR_LOG_ACTOR);
+ if(actor == null)
{
- clearAuthorizedSubject();
+ actor = createHttpManagementActor(req);
+ session.setAttribute(ATTR_LOG_ACTOR, actor);
}
+
+ return actor;
}
- protected void onPut(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
+ protected Subject getAuthorisedSubjectFromSession(HttpSession session)
{
- super.doPut(req,resp);
+ return (Subject)session.getAttribute(ATTR_SUBJECT);
}
- @Override
- protected final void doDelete(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException
+ protected void setAuthorisedSubjectInSession(Subject subject, HttpServletRequest request, final HttpSession session)
+ {
+ session.setAttribute(ATTR_SUBJECT, subject);
+
+ LogActor logActor = createHttpManagementActor(request);
+ // Cause the user logon to be logged.
+ session.setAttribute(ATTR_LOGIN_LOGOUT_REPORTER, new LoginLogoutReporter(logActor, subject));
+ }
+
+ protected Broker getBroker()
+ {
+ return _broker;
+ }
+
+ protected SocketAddress getSocketAddress(HttpServletRequest request)
+ {
+ return InetSocketAddress.createUnresolved(request.getServerName(), request.getServerPort());
+ }
+
+ protected void sendError(final HttpServletResponse resp, int errorCode)
{
- setAuthorizedSubject(req);
try
{
- onDelete(req, resp);
+ resp.sendError(errorCode);
}
- finally
+ catch (IOException e)
{
- clearAuthorizedSubject();
+ throw new RuntimeException("Failed to send error response code " + errorCode, e);
}
}
- protected void onDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
+ private HttpManagementActor createHttpManagementActor(HttpServletRequest request)
{
- super.doDelete(req, resp);
+ return new HttpManagementActor(_rootLogger, request.getRemoteAddr(), request.getRemotePort());
}
+ protected HttpManagement getManagement()
+ {
+ return _httpManagement;
+ }
- protected Broker getBroker()
+ protected SecurityManager getSecurityManager()
{
- return _broker;
+ return _broker.getSecurityManager();
}
- protected SocketAddress getSocketAddress(HttpServletRequest request)
+ protected SubjectCreator getSubjectCreator(HttpServletRequest request)
{
- return InetSocketAddress.createUnresolved(request.getServerName(), request.getServerPort());
+ return _broker.getSubjectCreator(getSocketAddress(request));
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
index 404793b592..f2cf5d7734 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsServlet.java
@@ -26,8 +26,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.logging.LogRecorder;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
@@ -35,16 +33,11 @@ public class LogRecordsServlet extends AbstractServlet
{
public LogRecordsServlet()
{
- super(ApplicationRegistry.getInstance().getBroker());
- }
-
- public LogRecordsServlet(Broker broker)
- {
- super(broker);
+ super();
}
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -53,10 +46,10 @@ public class LogRecordsServlet extends AbstractServlet
response.setHeader("Pragma","no-cache");
response.setDateHeader ("Expires", 0);
- ApplicationRegistry applicationRegistry = (ApplicationRegistry) ApplicationRegistry.getInstance();
List<Map<String,Object>> logRecords = new ArrayList<Map<String, Object>>();
- for(LogRecorder.Record record : applicationRegistry.getLogRecorder())
+ LogRecorder logRecorder = getBroker().getLogRecorder();
+ for(LogRecorder.Record record : logRecorder)
{
logRecords.add(logRecordToObject(record));
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
new file mode 100644
index 0000000000..4188e7d60d
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/LogoutServlet.java
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.plugin.servlet.rest;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.qpid.server.management.plugin.HttpManagement;
+
+@SuppressWarnings("serial")
+public class LogoutServlet extends HttpServlet
+{
+ public static final String RETURN_URL_INIT_PARAM = "qpid.webui_logout_redirect";
+ private String _returnUrl = HttpManagement.ENTRY_POINT_PATH;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+
+ String initValue = config.getServletContext().getInitParameter(RETURN_URL_INIT_PARAM);
+ if(initValue != null)
+ {
+ _returnUrl = initValue;
+ }
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException
+ {
+ HttpSession session = request.getSession(false);
+ if(session != null)
+ {
+ // Invalidating the session will cause LoginLogoutReporter to log the user logoff.
+ session.invalidate();
+ }
+
+ resp.sendRedirect(_returnUrl);
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
index bc87f0bcc5..d61c48bb2c 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java
@@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.queue.QueueEntry;
@@ -42,13 +41,8 @@ public class MessageContentServlet extends AbstractServlet
super();
}
- public MessageContentServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2)
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
index 6e7bc1d935..49e0c2b1bf 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
@@ -34,13 +34,10 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.queue.QueueEntryVisitor;
-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 org.apache.qpid.server.subscription.Subscription;
@@ -56,13 +53,8 @@ public class MessageServlet extends AbstractServlet
super();
}
- public MessageServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if(request.getPathInfo() != null && request.getPathInfo().length()>0 && request.getPathInfo().substring(1).split("/").length > 2)
@@ -400,7 +392,7 @@ public class MessageServlet extends AbstractServlet
* POST moves or copies messages to the given queue from a queue specified in the posted JSON data
*/
@Override
- protected void onPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doPostWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
@@ -422,7 +414,7 @@ public class MessageServlet extends AbstractServlet
// FIXME: added temporary authorization check until we introduce management layer
// and review current ACL rules to have common rules for all management interfaces
String methodName = isMoveTransaction? "moveMessages":"copyMessages";
- if (isQueueUpdateMethodAuthorized(methodName, vhost.getName()))
+ if (isQueueUpdateMethodAuthorized(methodName, vhost))
{
final Queue destinationQueue = getQueueFromVirtualHost(destQueueName, vhost);
final List messageIds = new ArrayList((List) providedObject.get("messages"));
@@ -435,7 +427,7 @@ public class MessageServlet extends AbstractServlet
}
else
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
catch(RuntimeException e)
@@ -450,7 +442,7 @@ public class MessageServlet extends AbstractServlet
* DELETE removes messages from the queue
*/
@Override
- protected void onDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response)
{
final Queue sourceQueue = getQueueFromRequest(request);
@@ -466,37 +458,22 @@ public class MessageServlet extends AbstractServlet
// FIXME: added temporary authorization check until we introduce management layer
// and review current ACL rules to have common rules for all management interfaces
- if (isQueueUpdateMethodAuthorized("deleteMessages", vhost.getName()))
+ if (isQueueUpdateMethodAuthorized("deleteMessages", vhost))
{
vhost.executeTransaction(new DeleteTransaction(sourceQueue, messageIds));
response.setStatus(HttpServletResponse.SC_OK);
}
else
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
- private boolean isQueueUpdateMethodAuthorized(String methodName, String virtualHost)
+ private boolean isQueueUpdateMethodAuthorized(String methodName, VirtualHost host)
{
- SecurityManager securityManager = getSecurityManager(virtualHost);
+ SecurityManager securityManager = host.getSecurityManager();
return securityManager.authoriseMethod(Operation.UPDATE, "VirtualHost.Queue", methodName);
}
- private SecurityManager getSecurityManager(String virtualHost)
- {
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- SecurityManager security;
- if (virtualHost == null)
- {
- security = appRegistry.getSecurityManager();
- }
- else
- {
- security = appRegistry.getVirtualHostRegistry().getVirtualHost(virtualHost).getSecurityManager();
- }
- return security;
- }
-
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
index 6a79916d07..3fab26cde5 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
@@ -19,6 +19,7 @@ package org.apache.qpid.server.management.plugin.servlet.rest;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
+import java.security.AccessControlException;
import java.util.*;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@@ -31,7 +32,6 @@ import org.apache.qpid.server.model.*;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
-
public class RestServlet extends AbstractServlet
{
private static final Logger LOGGER = Logger.getLogger(RestServlet.class);
@@ -47,29 +47,29 @@ public class RestServlet extends AbstractServlet
private Class<? extends ConfiguredObject>[] _hierarchy;
- private volatile boolean initializationRequired = false;
-
private final ConfiguredObjectToMapConverter _objectConverter = new ConfiguredObjectToMapConverter();
+ private final boolean _hierarchyInitializationRequired;
public RestServlet()
{
super();
- initializationRequired = true;
+ _hierarchyInitializationRequired = true;
}
- public RestServlet(Broker broker, Class<? extends ConfiguredObject>... hierarchy)
+ public RestServlet(Class<? extends ConfiguredObject>... hierarchy)
{
- super(broker);
+ super();
_hierarchy = hierarchy;
+ _hierarchyInitializationRequired = false;
}
@Override
public void init() throws ServletException
{
- if (initializationRequired)
+ super.init();
+ if (_hierarchyInitializationRequired)
{
doInitialization();
- initializationRequired = false;
}
}
@@ -285,7 +285,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -319,7 +319,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doPutWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
@@ -336,7 +336,8 @@ public class RestServlet extends AbstractServlet
if(names.size() != _hierarchy.length)
{
- throw new IllegalArgumentException("Path to object to create must be fully specified");
+ throw new IllegalArgumentException("Path to object to create must be fully specified. "
+ + "Found " + names.size() + " expecting " + _hierarchy.length);
}
}
@@ -428,8 +429,11 @@ public class RestServlet extends AbstractServlet
|| (obj.getName().equals(providedObject.get("name")) && equalParents(obj, otherParents)))
{
doUpdate(obj, providedObject);
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
}
}
+
theParent.createChild(objClass, providedObject, otherParents);
}
catch (RuntimeException e)
@@ -462,13 +466,17 @@ public class RestServlet extends AbstractServlet
private void setResponseStatus(HttpServletResponse response, RuntimeException e) throws IOException
{
- if (e.getCause() instanceof AMQSecurityException)
+ if (e instanceof AccessControlException || e.getCause() instanceof AMQSecurityException)
{
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Caught security exception, sending " + HttpServletResponse.SC_FORBIDDEN, e);
+ }
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
else
{
- LOGGER.warn("Unexpected exception is caught", e);
+ LOGGER.warn("Caught exception", e);
// TODO
response.setStatus(HttpServletResponse.SC_CONFLICT);
@@ -476,7 +484,7 @@ public class RestServlet extends AbstractServlet
}
@Override
- protected void onDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
index 1b78611a50..069132af1e 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
@@ -25,10 +25,9 @@ import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.management.plugin.HttpManagement;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
@@ -39,6 +38,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
+import java.security.AccessControlException;
import java.security.Principal;
import java.security.SecureRandom;
import java.util.LinkedHashMap;
@@ -47,6 +47,7 @@ import java.util.Random;
public class SaslServlet extends AbstractServlet
{
+
private static final Logger LOGGER = Logger.getLogger(SaslServlet.class);
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
@@ -56,18 +57,12 @@ public class SaslServlet extends AbstractServlet
private static final String ATTR_EXPIRY = "SaslServlet.Expiry";
private static final long SASL_EXCHANGE_EXPIRY = 1000L;
-
public SaslServlet()
{
super();
}
- public SaslServlet(Broker broker)
- {
- super(broker);
- }
-
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws
ServletException,
IOException
{
@@ -79,15 +74,16 @@ public class SaslServlet extends AbstractServlet
response.setDateHeader ("Expires", 0);
HttpSession session = request.getSession();
- Random rand = getRandom(session);
+ getRandom(session);
- AuthenticationManager authManager = ApplicationRegistry.getInstance().getAuthenticationManager(getSocketAddress(request));
- String[] mechanisms = authManager.getMechanisms().split(" ");
+ SubjectCreator subjectCreator = getSubjectCreator(request);
+ String[] mechanisms = subjectCreator.getMechanisms().split(" ");
Map<String, Object> outputObject = new LinkedHashMap<String, Object>();
- final Subject subject = (Subject) session.getAttribute("subject");
+
+ final Subject subject = getAuthorisedSubjectFromSession(session);
if(subject != null)
{
- final Principal principal = subject.getPrincipals().iterator().next();
+ Principal principal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
outputObject.put("user", principal.getName());
}
else if (request.getRemoteUser() != null)
@@ -121,9 +117,10 @@ public class SaslServlet extends AbstractServlet
@Override
- protected void onPost(final HttpServletRequest request, final HttpServletResponse response)
- throws ServletException, IOException
+ protected void doPostWithSubjectAndActor(final HttpServletRequest request, final HttpServletResponse response) throws IOException
{
+ checkSaslAuthEnabled(request);
+
try
{
response.setContentType("application/json");
@@ -137,14 +134,18 @@ public class SaslServlet extends AbstractServlet
String id = request.getParameter("id");
String saslResponse = request.getParameter("response");
- AuthenticationManager authManager = ApplicationRegistry.getInstance().getAuthenticationManager(getSocketAddress(request));
+ SubjectCreator subjectCreator = getSubjectCreator(request);
if(mechanism != null)
{
if(id == null)
{
- SaslServer saslServer = authManager.createSaslServer(mechanism, request.getServerName(), null/*TODO*/);
- evaluateSaslResponse(response, session, saslResponse, saslServer);
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Creating SaslServer for mechanism: " + mechanism);
+ }
+ SaslServer saslServer = subjectCreator.createSaslServer(mechanism, request.getServerName(), null/*TODO*/);
+ evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
}
else
{
@@ -152,9 +153,7 @@ public class SaslServlet extends AbstractServlet
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
-
}
-
}
else
{
@@ -163,8 +162,7 @@ public class SaslServlet extends AbstractServlet
if(id.equals(session.getAttribute(ATTR_ID)) && System.currentTimeMillis() < (Long) session.getAttribute(ATTR_EXPIRY))
{
SaslServer saslServer = (SaslServer) session.getAttribute(ATTR_SASL_SERVER);
- evaluateSaslResponse(response, session, saslResponse, saslServer);
-
+ evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
}
else
{
@@ -180,7 +178,6 @@ public class SaslServlet extends AbstractServlet
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
-
}
}
}
@@ -194,12 +191,30 @@ public class SaslServlet extends AbstractServlet
LOGGER.error("Error processing SASL request", e);
throw e;
}
+ }
+ private void checkSaslAuthEnabled(HttpServletRequest request)
+ {
+ boolean saslAuthEnabled;
+ HttpManagement management = getManagement();
+ if (request.isSecure())
+ {
+ saslAuthEnabled = management.isHttpsSaslAuthenticationEnabled();
+ }
+ else
+ {
+ saslAuthEnabled = management.isHttpSaslAuthenticationEnabled();
+ }
+
+ if (!saslAuthEnabled)
+ {
+ throw new RuntimeException("Sasl authentication disabled.");
+ }
}
- private void evaluateSaslResponse(final HttpServletResponse response,
- final HttpSession session,
- final String saslResponse, final SaslServer saslServer) throws IOException
+ private void evaluateSaslResponse(final HttpServletRequest request,
+ final HttpServletResponse response,
+ final HttpSession session, final String saslResponse, final SaslServer saslServer, SubjectCreator subjectCreator) throws IOException
{
final String id;
byte[] challenge;
@@ -209,27 +224,34 @@ public class SaslServlet extends AbstractServlet
}
catch(SaslException e)
{
-
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
if(saslServer.isComplete())
{
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(saslServer.getAuthorizationID()));
- session.setAttribute("subject", subject);
+ Subject subject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID());
+
+ try
+ {
+ authoriseManagement(request, subject);
+ }
+ catch (AccessControlException ace)
+ {
+ sendError(response, HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ setAuthorisedSubjectInSession(subject, request, session);
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
response.setStatus(HttpServletResponse.SC_OK);
-
-
}
else
{
@@ -250,7 +272,6 @@ public class SaslServlet extends AbstractServlet
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
mapper.writeValue(writer, outputObject);
-
}
}
}
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
index 60f977ca66..40d3c02768 100644
--- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java
@@ -41,13 +41,8 @@ public class StructureServlet extends AbstractServlet
super();
}
- public StructureServlet(Broker broker)
- {
- super(broker);
- }
-
@Override
- protected void onGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
@@ -56,6 +51,8 @@ public class StructureServlet extends AbstractServlet
response.setHeader("Pragma","no-cache");
response.setDateHeader ("Expires", 0);
+ // TODO filtering??? request.getParameter("filter"); // filter=1,2,3 /groups/*/*
+
Map<String,Object> structure = generateStructure(getBroker(), Broker.class);
final PrintWriter writer = response.getWriter();
diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java
new file mode 100644
index 0000000000..238f1b4719
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporter.java
@@ -0,0 +1,103 @@
+/*
+ * 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.plugin.session;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+/**
+ * Logs {@link ManagementConsoleMessages#OPEN(String)} and {@link ManagementConsoleMessages#CLOSE(String)}
+ * messages. A single instance of this class must be placed in the {@link HttpSession} immediately after
+ * the user has successfully logged-in, and removed (or the whole session invalidated) as the user logs out.
+ */
+public class LoginLogoutReporter implements HttpSessionBindingListener
+{
+ private static final Logger LOGGER = Logger.getLogger(LoginLogoutReporter.class);
+ private final LogActor _logActor;
+ private final Subject _subject;
+ private final Principal _principal;
+
+ public LoginLogoutReporter(LogActor logActor, Subject subject)
+ {
+ super();
+ _logActor = logActor;
+ _subject = subject;
+ _principal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(_subject);
+ }
+
+ @Override
+ public void valueBound(HttpSessionBindingEvent arg0)
+ {
+ reportLogin();
+ }
+
+ @Override
+ public void valueUnbound(HttpSessionBindingEvent arg0)
+ {
+ reportLogout();
+ }
+
+ private void reportLogin()
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("User logging in : " + _principal);
+ }
+
+ Subject.doAs(_subject, new PrivilegedAction<Void>()
+ {
+ @Override
+ public Void run()
+ {
+ _logActor.message(ManagementConsoleMessages.OPEN(_principal.getName()));
+ return null;
+ }
+ });
+ }
+
+ private void reportLogout()
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("User logging out : " + _principal);
+ }
+
+ Subject.doAs(_subject, new PrivilegedAction<Void>()
+ {
+ @Override
+ public Void run()
+ {
+ _logActor.message(ManagementConsoleMessages.CLOSE(_principal.getName()));
+ return null;
+ }
+ });
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html b/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
index baadc8c35f..e6c067fddf 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/authenticationprovider/showPrincipalDatabaseAuthenticationManager.html
@@ -23,7 +23,5 @@
<div class="users"></div>
<button data-dojo-type="dijit.form.Button" class="addUserButton">Add User</button>
<button data-dojo-type="dijit.form.Button" class="deleteUserButton">Delete Users</button>
-
</div>
-
</div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html b/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html
new file mode 100644
index 0000000000..0372468f91
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/group/addGroupMember.html
@@ -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.
+ -
+ -->
+<div class="dijitHidden">
+ <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Add Group Member'" id="addGroupMember">
+ <form id="formAddGroupMember" method="post" dojoType="dijit.form.Form">
+ <table cellpadding="0" cellspacing="2">
+ <tr>
+ <td valign="top"><strong>Name*: </strong></td>
+ <td><input type="text" required="true" name="name" id="formAddGroupMember.name" placeholder="Name"
+ dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></td>
+ </tr>
+ </table>
+ <br/>
+
+ <!-- submit buttons -->
+ <input type="submit" value="Add Group Member" label="Add Group Member" dojoType="dijit.form.Button" />
+ </form>
+ </div>
+</div>
diff --git a/java/systests/etc/config-systests-derby-mem.xml b/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html
index 8e40df986e..4fddf727d0 100644
--- a/java/systests/etc/config-systests-derby-mem.xml
+++ b/java/broker-plugins/management-http/src/main/java/resources/group/showGroup.html
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -19,11 +18,13 @@
- under the License.
-
-->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-derby-mem-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- </override>
-</configuration>
+<div class="group">
+ <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
+ <br/>
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Group Members'">
+ <div class="groupMembers"></div>
+ <button data-dojo-type="dijit.form.Button" class="addGroupMemberButton" type="button">Add Group Member</button>
+ <button data-dojo-type="dijit.form.Button" class="removeGroupMemberButton" type="button">Remove Group Members</button>
+ </div>
+</div>
+
diff --git a/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html
new file mode 100644
index 0000000000..8d3431808a
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/addGroup.html
@@ -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.
+ -
+ -->
+<div class="dijitHidden">
+ <div data-dojo-type="dijit.Dialog" style="width:600px;" data-dojo-props="title:'Add Group'" id="addGroup">
+ <form id="formAddGroup" method="post" dojoType="dijit.form.Form">
+ <table cellpadding="0" cellspacing="2">
+ <tr>
+ <td valign="top"><strong>Group Name*: </strong></td>
+ <td><input type="text" required="true" name="name" id="formAddGroup.name" placeholder="Group Name"
+ dojoType="dijit.form.ValidationTextBox" missingMessage="A name must be supplied" /></td>
+ </tr>
+ </table>
+ <br/>
+
+ <!-- submit buttons -->
+ <input type="submit" value="Create Group" label="Create Group" dojoType="dijit.form.Button" />
+
+ </form>
+ </div>
+</div>
diff --git a/java/systests/etc/config-systests-bdb.xml b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html
index 6b17b564a8..734e8b5419 100644
--- a/java/systests/etc/config-systests-bdb.xml
+++ b/java/broker-plugins/management-http/src/main/java/resources/groupprovider/showFileGroupManager.html
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -19,11 +18,11 @@
- under the License.
-
-->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-bdb-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- </override>
-</configuration>
+<div class="FileGroupManager">
+ <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Groups'">
+ <div class="groups"></div>
+ <button data-dojo-type="dijit.form.Button" class="addGroupButton">Add Group</button>
+ <button data-dojo-type="dijit.form.Button" class="deleteGroupButton">Delete Groups</button>
+ </div>
+
+</div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/management.html b/java/broker-plugins/management-http/src/main/java/resources/index.html
index a8345a8503..2fb9137ff8 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/management.html
+++ b/java/broker-plugins/management-http/src/main/java/resources/index.html
@@ -73,10 +73,8 @@
<div id="pageLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline', gutters: false">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
- <div id="header" class="header"></div>
- </div>
- <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
- <div id="login"></div>
+ <div id="header" class="header" style="float: left; width: 300px"></div>
+ <div id="login" style="float: right"></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'leading', splitter: true">
<div qpid-type="treeView" qpid-props="query: 'rest/structure'" ></div>
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
index 152504da86..b4f0728685 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
@@ -71,7 +71,7 @@ var saslPlain = function saslPlain(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -127,7 +127,7 @@ var saslCramMD5 = function saslCramMD5(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -141,7 +141,7 @@ var saslCramMD5 = function saslCramMD5(user, password)
},
function(error)
{
- if(error.status == 401)
+ if(error.status == 403)
{
alert("Authentication Failed");
}
@@ -152,10 +152,45 @@ var saslCramMD5 = function saslCramMD5(user, password)
});
};
+var containsMechanism = function containsMechanism(mechanisms, mech)
+{
+ for (var i = 0; i < mechanisms.length; i++) {
+ if (mechanisms[i] == mech) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
var doAuthenticate = function doAuthenticate()
{
- saslCramMD5(dojo.byId("username").value, dojo.byId("pass").value);
- updateAuthentication();
+ dojo.xhrGet({
+ // The URL of the request
+ url: "rest/sasl",
+ handleAs: "json"
+ }).then(function(data)
+ {
+ var mechMap = data.mechanisms;
+
+ if (containsMechanism(mechMap, "CRAM-MD5"))
+ {
+ saslCramMD5(dojo.byId("username").value, dojo.byId("pass").value);
+ updateAuthentication();
+ }
+ else if (containsMechanism(mechMap, "PLAIN"))
+ {
+ saslPlain(dojo.byId("username").value, dojo.byId("pass").value);
+ updateAuthentication();
+ }
+ else
+ {
+ alert("No supported SASL mechanism offered: " + mechMap);
+ }
+ }
+ );
+
+
};
@@ -170,13 +205,13 @@ var updateAuthentication = function updateAuthentication()
if(data.user)
{
dojo.byId("authenticatedUser").innerHTML = data.user;
- dojo.style(button.domNode, {visibility: 'hidden'});
- dojo.style(usernameSpan, {visibility: 'visible'});
+ dojo.style(button.domNode, {display: 'none'});
+ dojo.style(usernameSpan, {display: 'block'});
}
else
{
- dojo.style(button.domNode, {visibility: 'visible'});
- dojo.style(usernameSpan, {visibility: 'hidden'});
+ dojo.style(button.domNode, {display: 'block'});
+ dojo.style(usernameSpan, {display: 'none'});
}
}
);
@@ -198,13 +233,13 @@ require(["dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox
dropDown: dialog
});
- usernameSpan = domConstruct.create("span", { innerHTML: '<strong>User: </strong><span id="authenticatedUser"></span>',
- style: { visibility: "hidden" }});
+ usernameSpan = domConstruct.create("span", { innerHTML: '<strong>User: </strong> <span id="authenticatedUser"></span><a href="logout">[logout]</a>',
+ style: { display: "none" }});
var loginDiv = dom.byId("login");
- loginDiv.appendChild(button.domNode);
loginDiv.appendChild(usernameSpan);
+ loginDiv.appendChild(button.domNode);
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
index 08fdf5c99b..5557c37a2c 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
@@ -58,10 +58,10 @@ define(["dojo/_base/xhr"],
return exchangeName == null || exchangeName == "" || "<<default>>" == exchangeName || exchangeName.indexOf("amq.") == 0 || exchangeName.indexOf("qpid.") == 0;
};
- util.deleteGridSelections = function(updater, gridName, url, confirmationMessageStart)
+ util.deleteGridSelections = function(updater, grid, url, confirmationMessageStart)
{
- var grid = updater[gridName].grid;
var data = grid.selection.getSelected();
+
if(data.length)
{
var confirmationMessage = null;
@@ -103,7 +103,8 @@ define(["dojo/_base/xhr"],
xhr.del({url: query, sync: true, handleAs: "json"}).then(
function(data)
{
- grid.setQuery({id: "*"});
+ // TODO why query *??
+ //grid.setQuery({id: "*"});
grid.selection.deselectAll();
updater.update();
},
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
index 37bae1ef8e..5a5a6515ef 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Exchange.js
@@ -115,7 +115,7 @@ define(["dojo/_base/xhr",
{
util.deleteGridSelections(
this.exchangeUpdater,
- "bindingsGrid",
+ that.exchangeUpdater.bindingsGrid.grid,
"rest/binding/"+ encodeURIComponent(this.getVirtualHostName()) + "/" + encodeURIComponent(this.name),
"Are you sure you want to delete binding for queue");
}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
new file mode 100644
index 0000000000..4e05f4b0ea
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/GroupProvider.js
@@ -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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/parser",
+ "dojo/query",
+ "dojo/_base/connect",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/util",
+ "qpid/common/UpdatableStore",
+ "dojox/grid/EnhancedGrid",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojo/domReady!"],
+ function (xhr, parser, query, connect, properties, updater, util, UpdatableStore, EnhancedGrid) {
+
+ function GroupProvider(name, parent, controller) {
+ this.name = name;
+ this.controller = controller;
+ this.modelObj = { type: "groupprovider", name: name };
+ if(parent) {
+ this.modelObj.parent = {};
+ this.modelObj.parent[ parent.type] = parent;
+ }
+ }
+
+ GroupProvider.prototype.getTitle = function() {
+ return "GroupProvider";
+ };
+
+ GroupProvider.prototype.open = function(contentPane) {
+ var that = this;
+ this.contentPane = contentPane;
+ xhr.get({url: "showGroupProvider.html",
+ sync: true,
+ load: function(data) {
+ contentPane.containerNode.innerHTML = data;
+ parser.parse(contentPane.containerNode);
+
+ that.groupProviderAdapter = new GroupProviderUpdater(contentPane.containerNode, that.modelObj, that.controller);
+
+ updater.add( that.groupProviderAdapter );
+
+ that.groupProviderAdapter.update();
+
+ }});
+ };
+
+ GroupProvider.prototype.close = function() {
+ updater.remove( this.groupProviderAdapter );
+ };
+
+ function GroupProviderUpdater(node, groupProviderObj, controller)
+ {
+ this.controller = controller;
+ this.name = query(".name", node)[0];
+ this.query = "rest/groupprovider/"+encodeURIComponent(groupProviderObj.name);
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data)
+ {
+ that.groupProviderData = data[0];
+
+ util.flattenStatistics( that.groupProviderData );
+
+ that.updateHeader();
+
+ require(["qpid/management/groupprovider/"+that.groupProviderData.type],
+ function(SpecificProvider) {
+ that.details = new SpecificProvider(node, groupProviderObj, controller);
+ that.details.update();
+ });
+
+ });
+
+ }
+
+ GroupProviderUpdater.prototype.updateHeader = function()
+ {
+ this.name.innerHTML = this.groupProviderData[ "name" ];
+ };
+
+ GroupProviderUpdater.prototype.update = function()
+ {
+ var that = this;
+ };
+
+ return GroupProvider;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
index 957f2381cf..2efc46476d 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/VirtualHost.js
@@ -72,7 +72,7 @@ define(["dojo/_base/xhr",
function(evt){
util.deleteGridSelections(
that.vhostUpdater,
- "queuesGrid",
+ that.vhostUpdater.queuesGrid.grid,
"rest/queue/"+ encodeURIComponent(that.name),
"Are you sure you want to delete queue");
}
@@ -87,7 +87,7 @@ define(["dojo/_base/xhr",
{
util.deleteGridSelections(
that.vhostUpdater,
- "exchangesGrid",
+ that.vhostUpdater.exchangesGrid.grid,
"rest/exchange/"+ encodeURIComponent(that.name),
"Are you sure you want to delete exchange");
}
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
index 1aa05a5a3c..5d3a666760 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/controller.js
@@ -27,13 +27,17 @@ define(["dojo/dom",
"qpid/management/Queue",
"qpid/management/Connection",
"qpid/management/AuthenticationProvider",
+ "qpid/management/GroupProvider",
+ "qpid/management/group/Group",
"dojo/ready",
"dojo/domReady!"],
- function (dom, registry, ContentPane, Broker, VirtualHost, Exchange, Queue, Connection, AuthProvider, ready) {
+ function (dom, registry, ContentPane, Broker, VirtualHost, Exchange, Queue, Connection, AuthProvider, GroupProvider, Group, ready) {
var controller = {};
var constructors = { broker: Broker, virtualhost: VirtualHost, exchange: Exchange,
- queue: Queue, connection: Connection, authenticationprovider: AuthProvider };
+ queue: Queue, connection: Connection,
+ authenticationprovider: AuthProvider, groupprovider: GroupProvider,
+ group: Group };
var tabDiv = dom.byId("managedViews");
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js
new file mode 100644
index 0000000000..ea918644e9
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/Group.js
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/parser",
+ "dojo/query",
+ "dijit/registry",
+ "dojo/_base/connect",
+ "dojo/_base/event",
+ "dojo/json",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/util",
+ "qpid/common/formatter",
+ "qpid/common/UpdatableStore",
+ "dojo/store/JsonRest",
+ "dojox/grid/EnhancedGrid",
+ "dojo/data/ObjectStore",
+ "qpid/management/group/addGroupMember",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojo/domReady!"],
+ function (xhr, parser, query, registry, connect, event, json, properties, updater, util, formatter,
+ UpdatableStore, JsonRest, EnhancedGrid, ObjectStore, addGroupMember) {
+
+ function Group(name, parent, controller) {
+ this.name = name;
+ this.controller = controller;
+ this.modelObj = { type: "group", name: name };
+
+ if(parent) {
+ this.modelObj.parent = {};
+ this.modelObj.parent[ parent.type] = parent;
+ }
+ }
+
+ Group.prototype.getGroupName = function()
+ {
+ return this.name;
+ };
+
+
+ Group.prototype.getGroupProviderName = function()
+ {
+ return this.modelObj.parent.groupprovider.name;
+ };
+
+ Group.prototype.getTitle = function()
+ {
+ return "Group: " + this.name;
+ };
+
+ Group.prototype.open = function(contentPane) {
+ var that = this;
+ this.contentPane = contentPane;
+
+ xhr.get({url: "group/showGroup.html",
+ sync: true,
+ load: function(data) {
+ contentPane.containerNode.innerHTML = data;
+ parser.parse(contentPane.containerNode);
+
+ that.groupUpdater = new GroupUpdater(contentPane.containerNode, that, that.controller);
+
+ updater.add( that.groupUpdater );
+
+ that.groupUpdater.update();
+
+ var addGroupMemberButton = query(".addGroupMemberButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(addGroupMemberButton), "onClick",
+ function(evt){
+ addGroupMember.show(that.getGroupProviderName(), that.getGroupName())
+ }
+ );
+
+ var removeGroupMemberButton = query(".removeGroupMemberButton", contentPane.containerNode)[0];
+ connect.connect(registry.byNode(removeGroupMemberButton), "onClick",
+ function(evt){
+ util.deleteGridSelections(
+ that.groupUpdater,
+ that.groupUpdater.groupMembersUpdatableStore.grid,
+ "rest/groupmember/"+ encodeURIComponent(that.getGroupProviderName()) +
+ "/" + encodeURIComponent(that.getGroupName()),
+ "Are you sure you want to remove group member");
+ }
+ );
+ }});
+ };
+
+ Group.prototype.close = function() {
+ updater.remove( this.groupUpdater );
+ };
+
+ function GroupUpdater(containerNode, groupObj, controller)
+ {
+ var that = this;
+
+ function findNode(name) {
+ return query("." + name, containerNode)[0];
+ }
+
+ function storeNodes(names)
+ {
+ for(var i = 0; i < names.length; i++) {
+ that[names[i]] = findNode(names[i]);
+ }
+ }
+
+ storeNodes(["name",
+ "state",
+ "durable",
+ "lifetimePolicy",
+ "type"]);
+
+ this.query = "rest/groupmember/"+ encodeURIComponent(groupObj.getGroupProviderName()) + "/" + encodeURIComponent(groupObj.getGroupName());
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"}).then(function(data)
+ {
+ that.groupMemberData = data;
+
+ util.flattenStatistics( that.groupMemberData );
+
+ var gridProperties = {
+ keepSelection: true,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+
+ }};
+
+ that.groupMembersUpdatableStore = new UpdatableStore(that.groupMemberData, findNode("groupMembers"),
+ [ { name: "Group Member Name", field: "name", width: "100%" }],
+ function(obj)
+ {
+ connect.connect(obj.grid, "onRowDblClick", obj.grid,
+ function(evt){
+
+ });
+ } , gridProperties, EnhancedGrid);
+
+ });
+
+ }
+
+ GroupUpdater.prototype.update = function()
+ {
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupMemberData = data;
+
+ util.flattenStatistics( that.groupMemberData );
+
+ that.groupMembersUpdatableStore.update(that.groupMemberData);
+ });
+ };
+
+ Group.prototype.deleteGroupMember = function() {
+ if(confirm("Are you sure you want to delete group member'" +this.name+"'?")) {
+ var query = "rest/groupmember/"+ encodeURIComponent(this.getGroupProviderName()) + "/" + encodeURIComponent(this.name);
+ this.success = true
+ var that = this;
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ that.contentPane.onClose()
+ that.controller.tabContainer.removeChild(that.contentPane);
+ that.contentPane.destroyRecursive();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!this.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
+ }
+
+ return Group;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js
new file mode 100644
index 0000000000..1861cc6ffe
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/group/addGroupMember.js
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/dom",
+ "dojo/dom-construct",
+ "dojo/_base/window",
+ "dijit/registry",
+ "dojo/parser",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ 'dojo/_base/json',
+ "dijit/form/NumberSpinner", // required by the form
+ /* dojox/ validate resources */
+ "dojox/validate/us", "dojox/validate/web",
+ /* basic dijit classes */
+ "dijit/Dialog",
+ "dijit/form/CheckBox", "dijit/form/Textarea",
+ "dijit/form/FilteringSelect", "dijit/form/TextBox",
+ "dijit/form/ValidationTextBox", "dijit/form/DateTextBox",
+ "dijit/form/TimeTextBox", "dijit/form/Button",
+ "dijit/form/RadioButton", "dijit/form/Form",
+ "dijit/form/DateTextBox",
+ /* basic dojox classes */
+ "dojox/form/BusyButton", "dojox/form/CheckedMultiSelect",
+ "dojo/domReady!"],
+ function (xhr, dom, construct, win, registry, parser, array, event, json) {
+
+ var addGroupMember = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToGroupMember = function convertToGroupMember(formValues)
+ {
+ var newGroupMember = {};
+ newGroupMember.name = formValues.name;
+ return newGroupMember;
+ };
+
+ xhr.get({url: "group/addGroupMember.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addGroupMember.dialogNode = dom.byId("addGroupMember");
+ parser.instantiate([addGroupMember.dialogNode]);
+
+ theForm = registry.byId("formAddGroupMember");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var newGroupMember = convertToGroupMember(theForm.getValues());
+ var that = this;
+ xhr.put({url: "rest/groupmember/"+encodeURIComponent(addGroupMember.groupProvider) +
+ "/" + encodeURIComponent(addGroupMember.group) + "/" + encodeURIComponent(newGroupMember.name), sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newGroupMember),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(this.success === true)
+ {
+ registry.byId("addGroupMember").hide();
+ }
+ else
+ {
+ alert("Error:" + this.failureReason);
+ }
+
+ return false;
+
+
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+
+ });
+ }});
+
+ addGroupMember.show = function(groupProvider, group) {
+ addGroupMember.groupProvider = groupProvider;
+ addGroupMember.group = group;
+ registry.byId("formAddGroupMember").reset();
+ registry.byId("addGroupMember").show();
+ };
+
+ return addGroupMember;
+ }); \ No newline at end of file
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js
new file mode 100644
index 0000000000..44fc9702e2
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/groupprovider/FileGroupManager.js
@@ -0,0 +1,251 @@
+/*
+ *
+ * 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.
+ *
+ */
+define(["dojo/_base/xhr",
+ "dojo/dom",
+ "dojo/parser",
+ "dojo/query",
+ "dojo/dom-construct",
+ "dojo/_base/connect",
+ "dojo/_base/window",
+ "dojo/_base/event",
+ "dojo/_base/json",
+ "dijit/registry",
+ "qpid/common/util",
+ "qpid/common/properties",
+ "qpid/common/updater",
+ "qpid/common/UpdatableStore",
+ "dojox/grid/EnhancedGrid",
+ "dojox/grid/enhanced/plugins/Pagination",
+ "dojox/grid/enhanced/plugins/IndirectSelection",
+ "dojox/validate/us", "dojox/validate/web",
+ "dijit/Dialog",
+ "dijit/form/TextBox",
+ "dijit/form/ValidationTextBox",
+ "dijit/form/TimeTextBox", "dijit/form/Button",
+ "dijit/form/Form",
+ "dijit/form/DateTextBox",
+ "dojo/domReady!"],
+ function (xhr, dom, parser, query, construct, connect, win, event, json, registry, util, properties, updater, UpdatableStore, EnhancedGrid) {
+ function DatabaseGroupManager(containerNode, groupProviderObj, controller) {
+ var node = construct.create("div", null, containerNode, "last");
+ var that = this;
+ this.name = groupProviderObj.name;
+ xhr.get({url: "groupprovider/showFileGroupManager.html",
+ sync: true,
+ load: function(data) {
+ node.innerHTML = data;
+ parser.parse(node);
+
+
+ that.groupDatabaseUpdater= new GroupProviderUpdater(node, groupProviderObj, controller);
+
+ updater.add( that.groupDatabaseUpdater);
+
+ that.groupDatabaseUpdater.update();
+
+
+ }});
+ }
+
+ DatabaseGroupManager.prototype.update = function() {
+ this.groupDatabaseUpdater.update();
+ };
+
+ DatabaseGroupManager.prototype.close = function() {
+ updater.remove( this.groupDatabaseUpdater );
+ };
+
+ function GroupProviderUpdater(node, groupProviderObj, controller)
+ {
+ this.controller = controller;
+ this.query = "rest/groupprovider/"+encodeURIComponent(groupProviderObj.name);
+ this.name = groupProviderObj.name;
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupProviderData = data[0];
+
+ util.flattenStatistics( that.groupProviderData );
+
+ var groupDiv = query(".groups")[0];
+
+ var gridProperties = {
+ height: 400,
+ keepSelection: true,
+ plugins: {
+ pagination: {
+ pageSizes: ["10", "25", "50", "100"],
+ description: true,
+ sizeSwitch: true,
+ pageStepper: true,
+ gotoButton: true,
+ maxPageStep: 4,
+ position: "bottom"
+ },
+ indirectSelection: true
+
+ }};
+
+
+ that.groupsGrid =
+ new UpdatableStore(that.groupProviderData.groups, groupDiv,
+ [ { name: "Group Name", field: "name", width: "100%" }
+ ], null, gridProperties, EnhancedGrid);
+
+
+ var addGroupButton = query(".addGroupButton", node)[0];
+ connect.connect(registry.byNode(addGroupButton), "onClick", function(evt){ addGroup.show(groupProviderObj.name) });
+
+ var deleteMessagesButton = query(".deleteGroupButton", node)[0];
+ var deleteWidget = registry.byNode(deleteMessagesButton);
+ connect.connect(deleteWidget, "onClick",
+ function(evt){
+ event.stop(evt);
+ that.deleteGroups();
+ });
+ });
+ }
+
+ GroupProviderUpdater.prototype.deleteGroups = function()
+ {
+ var grid = this.groupsGrid.grid;
+ var data = grid.selection.getSelected();
+ if(data.length) {
+ var that = this;
+ if(confirm("Delete " + data.length + " groups?")) {
+ var i, queryParam;
+ for(i = 0; i<data.length; i++) {
+ if(queryParam) {
+ queryParam += "&";
+ } else {
+ queryParam = "?";
+ }
+
+ queryParam += "id=" + data[i].id;
+ }
+ var query = "rest/group/"+ encodeURIComponent(that.name)
+ + queryParam;
+ that.success = true
+ xhr.del({url: query, sync: true, handleAs: "json"}).then(
+ function(data) {
+ grid.setQuery({id: "*"});
+ grid.selection.deselectAll();
+ that.update();
+ },
+ function(error) {that.success = false; that.failureReason = error;});
+ if(!that.success ) {
+ alert("Error:" + this.failureReason);
+ }
+ }
+}
+ };
+
+ GroupProviderUpdater.prototype.update = function()
+ {
+
+ var that = this;
+
+ xhr.get({url: this.query, sync: properties.useSyncGet, handleAs: "json"})
+ .then(function(data) {
+ that.groupProviderData = data[0];
+ util.flattenStatistics( that.groupProviderData );
+
+ that.groupsGrid.update(that.groupProviderData.groups);
+
+ });
+
+
+ };
+
+ var addGroup = {};
+
+ var node = construct.create("div", null, win.body(), "last");
+
+ var convertToGroup = function convertToGroup(formValues) {
+ var newGroup = {};
+ newGroup.name = formValues.name;
+ for(var propName in formValues)
+ {
+ if(formValues.hasOwnProperty(propName)) {
+ if(formValues[ propName ] !== "") {
+ newGroup[ propName ] = formValues[propName];
+ }
+ }
+ }
+
+ return newGroup;
+ };
+
+
+ xhr.get({url: "groupprovider/addGroup.html",
+ sync: true,
+ load: function(data) {
+ var theForm;
+ node.innerHTML = data;
+ addGroup.dialogNode = dom.byId("addGroup");
+ parser.instantiate([addGroup.dialogNode]);
+
+ var that = this;
+
+ theForm = registry.byId("formAddGroup");
+ theForm.on("submit", function(e) {
+
+ event.stop(e);
+ if(theForm.validate()){
+
+ var newGroup = convertToGroup(theForm.getValues());
+
+
+ var url = "rest/group/"+encodeURIComponent(addGroup.groupProvider) +
+ "/"+encodeURIComponent(newGroup.name);
+
+ xhr.put({url: url, sync: true, handleAs: "json",
+ headers: { "Content-Type": "application/json"},
+ putData: json.toJson(newGroup),
+ load: function(x) {that.success = true; },
+ error: function(error) {that.success = false; that.failureReason = error;}});
+
+ if(that.success === true) {
+ registry.byId("addGroup").hide();
+ } else {
+ alert("Error:" + that.failureReason);
+ }
+
+ return false;
+
+
+ }else{
+ alert('Form contains invalid data. Please correct first');
+ return false;
+ }
+
+ });
+ }});
+
+ addGroup.show = function(groupProvider) {
+ addGroup.groupProvider = groupProvider;
+ registry.byId("formAddGroup").reset();
+ registry.byId("addGroup").show();
+ };
+
+ return DatabaseGroupManager;
+ });
diff --git a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
index b1d4abf8c1..59356cfce1 100644
--- a/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
+++ b/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
@@ -273,10 +273,12 @@ define(["dojo/_base/xhr",
controller.show("port", details.port, { type: "virtualhost", name: details.virtualhost, parent: {broker: {type:"broker", name:""}}});
} else if (details.type == 'authenticationprovider') {
controller.show("authenticationprovider", details.authenticationprovider, {broker: {type:"broker", name:""}});
+ } else if (details.type == 'groupprovider') {
+ controller.show("groupprovider", details.groupprovider, {broker: {type:"broker", name:""}});
+ } else if (details.type == 'group') {
+ controller.show("group", details.group, { type: "groupprovider", name: details.groupprovider, parent: {broker: {type:"broker", name:""}}});
}
-
-
};
TreeViewModel.prototype.update = function () {
diff --git a/java/systests/etc/config-systests-derby-settings.xml b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
index 3ed3a9e33b..914857db5c 100644
--- a/java/systests/etc/config-systests-derby-settings.xml
+++ b/java/broker-plugins/management-http/src/main/java/resources/showGroupProvider.html
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -19,8 +18,8 @@
- under the License.
-
-->
-<broker>
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-derby.xml</virtualhosts>
-</broker>
-
-
+<div class="groupProvider">
+ <span style="">Name:</span><span class="name" style="position:absolute; left:6em"></span>
+ <br/>
+ <span style="">Type:</span><span class="type" style="position:absolute; left:6em"></span>
+</div> \ No newline at end of file
diff --git a/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory b/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
new file mode 100644
index 0000000000..7ffb9a9013
--- /dev/null
+++ b/java/broker-plugins/management-http/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
@@ -0,0 +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.
+#
+org.apache.qpid.server.management.plugin.HttpManagementFactory
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java
new file mode 100644
index 0000000000..bb4c46826c
--- /dev/null
+++ b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/HttpManagementFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.plugin;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class HttpManagementFactoryTest extends QpidTestCase
+{
+ private static final int SESSION_TIMEOUT = 3600;
+
+ private PluginFactory _pluginFactory = new HttpManagementFactory();
+ private Map<String, Object> _attributes = new HashMap<String, Object>();
+ private Broker _broker = mock(Broker.class);
+ private UUID _id = UUID.randomUUID();
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeMissing() throws Exception
+ {
+ assertNull(_pluginFactory.createInstance(_id, _attributes, _broker));
+ }
+ public void testCreateInstanceReturnsNullWhenPluginTypeNotHttp()
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, "notHttp");
+ assertNull(_pluginFactory.createInstance(_id, _attributes, _broker));
+ }
+
+ public void testCreateInstance() throws Exception
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, HttpManagement.PLUGIN_TYPE);
+ _attributes.put(HttpManagement.TIME_OUT, SESSION_TIMEOUT);
+
+ HttpManagement management = (HttpManagement) _pluginFactory.createInstance(_id, _attributes, _broker);
+
+ assertEquals(_broker, management.getBroker());
+ assertEquals(SESSION_TIMEOUT, management.getSessionTimeout());
+ }
+
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java
deleted file mode 100644
index e83341de80..0000000000
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QpidRestTestCase.java
+++ /dev/null
@@ -1,245 +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.plugin.servlet.rest;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.codehaus.jackson.JsonGenerationException;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.type.TypeReference;
-
-public class QpidRestTestCase extends QpidBrokerTestCase
-{
- private static final Logger LOGGER = Logger.getLogger(QpidRestTestCase.class);
-
- public static final String[] EXPECTED_HOSTS = { "development", "test", "localhost" };
- public static final String[] EXPECTED_QUEUES = { "queue", "ping" };
- public static final String[] EXPECTED_EXCHANGES = { "amq.fanout", "amq.match", "amq.direct", "amq.topic",
- "qpid.management", "<<default>>" };
-
- private int _httpPort;
- private String _hostName;
- private List<HttpURLConnection> _httpConnections;
-
- @Override
- public void setUp() throws Exception
- {
- _httpConnections = new ArrayList<HttpURLConnection>();
- _hostName = InetAddress.getLocalHost().getHostName();
- _httpPort = findFreePort();
- customizeConfiguration();
- super.setUp();
-
- }
-
- protected void customizeConfiguration() throws ConfigurationException, IOException
- {
- setConfigurationProperty("management.enabled", "false");
- setConfigurationProperty("management.http.enabled", "true");
- setConfigurationProperty("management.https.enabled", "false");
- setConfigurationProperty("management.http.port", Integer.toString(_httpPort));
- }
-
- public void teearDown() throws Exception
- {
- for (HttpURLConnection connection : _httpConnections)
- {
- try
- {
- connection.disconnect();
- }
- catch (Exception e)
- {
- // ignore
- }
- }
- super.tearDown();
- }
-
- protected int getHttpPort()
- {
- return _httpPort;
- }
-
- protected String getHostName()
- {
- return _hostName;
- }
-
- protected String getProtocol()
- {
- return "http";
- }
-
- protected String getManagementURL()
- {
- return getProtocol() + "://" + getHostName() + ":" + getHttpPort();
- }
-
- protected URL getManagementURL(String path) throws MalformedURLException
- {
- return new URL(getManagementURL() + path);
- }
-
- protected HttpURLConnection openManagementConection(String path) throws IOException
- {
- URL url = getManagementURL(path);
- HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
- httpCon.setDoOutput(true);
- return httpCon;
- }
-
- protected HttpURLConnection openManagementConection(String path, String method) throws IOException
- {
- HttpURLConnection httpCon = openManagementConection(path);
- httpCon.setRequestMethod(method);
- return httpCon;
- }
-
- protected List<Map<String, Object>> readJsonResponseAsList(HttpURLConnection connection) throws IOException,
- JsonParseException, JsonMappingException
- {
- byte[] data = readConnectionInputStream(connection);
-
- ObjectMapper mapper = new ObjectMapper();
-
- TypeReference<List<LinkedHashMap<String, Object>>> typeReference = new TypeReference<List<LinkedHashMap<String, Object>>>()
- {
- };
- List<Map<String, Object>> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
- return providedObject;
- }
-
- protected Map<String, Object> readJsonResponseAsMap(HttpURLConnection connection) throws IOException,
- JsonParseException, JsonMappingException
- {
- byte[] data = readConnectionInputStream(connection);
-
- ObjectMapper mapper = new ObjectMapper();
-
- TypeReference<LinkedHashMap<String, Object>> typeReference = new TypeReference<LinkedHashMap<String, Object>>()
- {
- };
- Map<String, Object> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
- return providedObject;
- }
-
- protected byte[] readConnectionInputStream(HttpURLConnection connection) throws IOException
- {
- InputStream is = connection.getInputStream();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = -1;
- while ((len = is.read(buffer)) != -1)
- {
- baos.write(buffer, 0, len);
- }
- if (LOGGER.isTraceEnabled())
- {
- LOGGER.trace("RESPONSE:" + new String(baos.toByteArray()));
- }
- return baos.toByteArray();
- }
-
- protected void writeJsonRequest(HttpURLConnection connection, Map<String, Object> data) throws JsonGenerationException,
- JsonMappingException, IOException
- {
- ObjectMapper mapper = new ObjectMapper();
- mapper.writeValue(connection.getOutputStream(), data);
- }
-
- protected Map<String, Object> find(String name, Object value, List<Map<String, Object>> data)
- {
- for (Map<String, Object> map : data)
- {
- Object mapValue = map.get(name);
- if (value.equals(mapValue))
- {
- return map;
- }
- }
- return null;
- }
-
- protected Map<String, Object> find(Map<String, Object> searchAttributes, List<Map<String, Object>> data)
- {
- for (Map<String, Object> map : data)
- {
- boolean equals = true;
- for (Map.Entry<String, Object> entry : searchAttributes.entrySet())
- {
- Object mapValue = map.get(entry.getKey());
- if (!entry.getValue().equals(mapValue))
- {
- equals = false;
- break;
- }
- }
- if (equals)
- {
- return map;
- }
- }
- return null;
- }
-
- protected Map<String, Object> getJsonAsSingletonList(String path) throws IOException
- {
- List<Map<String, Object>> response = getJsonAsList(path);
-
- assertNotNull("Response cannot be null", response);
- assertEquals("Unexpected response", 1, response.size());
- return response.get(0);
- }
-
- protected List<Map<String, Object>> getJsonAsList(String path) throws IOException, JsonParseException,
- JsonMappingException
- {
- HttpURLConnection connection = openManagementConection(path, "GET");
- connection.connect();
- List<Map<String, Object>> response = readJsonResponseAsList(connection);
- return response;
- }
-
- protected Map<String, Object> getJsonAsMap(String path) throws IOException
- {
- HttpURLConnection connection = openManagementConection(path, "GET");
- connection.connect();
- Map<String, Object> response = readJsonResponseAsMap(connection);
- return response;
- }
-}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.java
new file mode 100644
index 0000000000..1d43c44587
--- /dev/null
+++ b/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/session/LoginLogoutReporterTest.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.management.plugin.session;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.argThat;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.LogMessage;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import junit.framework.TestCase;
+
+public class LoginLogoutReporterTest extends TestCase
+{
+ private LoginLogoutReporter _loginLogoutReport;
+ private Subject _subject = new Subject();
+ private LogActor _logActor = Mockito.mock(LogActor.class);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ _subject.getPrincipals().add(new AuthenticatedPrincipal("mockusername"));
+ _loginLogoutReport = new LoginLogoutReporter(_logActor, _subject);
+ }
+
+ public void testLoginLogged()
+ {
+ _loginLogoutReport.valueBound(null);
+ verify(_logActor).message(isLogMessageWithMessage("MNG-1007 : Open : User mockusername"));
+ }
+
+ public void testLogoutLogged()
+ {
+ _loginLogoutReport.valueUnbound(null);
+ verify(_logActor).message(isLogMessageWithMessage("MNG-1008 : Close : User mockusername"));
+ }
+
+ private LogMessage isLogMessageWithMessage(final String expectedMessage)
+ {
+ return argThat( new ArgumentMatcher<LogMessage>()
+ {
+ @Override
+ public boolean matches(Object argument)
+ {
+ LogMessage actual = (LogMessage) argument;
+ return actual.toString().equals(expectedMessage);
+ }
+ });
+ }
+}
diff --git a/java/broker-plugins/management-jmx/MANIFEST.MF b/java/broker-plugins/management-jmx/MANIFEST.MF
deleted file mode 100644
index b18ec1ace7..0000000000
--- a/java/broker-plugins/management-jmx/MANIFEST.MF
+++ /dev/null
@@ -1,66 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Management JMX
-Bundle-SymbolicName: broker-plugins-management-jmx
-Bundle-Description: JMX management plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.jmx.JMXActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.common,
- org.apache.qpid.management.common.mbeans,
- org.apache.qpid.management.common.mbeans.annotations,
- org.apache.qpid.server.security.auth,
- org.apache.qpid.server.security.auth.manager,
- org.apache.qpid.server.security.auth.rmi,
- org.apache.qpid.server.security.auth.sasl,
- org.apache.qpid.server.binding,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.logging,
- org.apache.qpid.server.logging.log4j,
- org.apache.qpid.server.logging.actors,
- org.apache.qpid.server.logging.messages,
- org.apache.qpid.server.message,
- org.apache.qpid.server.model,
- org.apache.qpid.server.model.adapter,
- org.apache.qpid.server.model.impl,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.connection,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.protocol,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.registry,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.stats,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.codec;version=1.3.0,
- org.apache.commons.codec.binary;version=1.3.0,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.commons.lang.time;version=1.0.0,
- org.apache.log4j;version=1.2.16,
- org.codehaus.jackson;version=1.9.0,
- org.codehaus.jackson.map;version=1.9.0,
- javax.management.remote.rmi,
- javax.management.remote,
- javax.servlet,
- javax.servlet.http,
- javax.management;version=1.0.0,
- javax.management.monitor;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- javax.security.auth.login;version=1.0.0,
- javax.security.auth;version=1.0.0,
- javax.rmi.ssl;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Export-Package: org.apache.qpid.server.jmx;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/management-jmx/build.xml b/java/broker-plugins/management-jmx/build.xml
index fa50b8467d..9d212cf39a 100644
--- a/java/broker-plugins/management-jmx/build.xml
+++ b/java/broker-plugins/management-jmx/build.xml
@@ -17,28 +17,14 @@
- under the License.
-->
<project name="Qpid Broker-Plugins Management JMX" default="build">
-
- <condition property="systests.optional.depends" value="bdbstore" else="">
- <or>
- <and>
- <contains string="${modules.opt}" substring="bdbstore"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- <and>
- <istrue value="${optional}"/>
- <contains string="${profile}" substring="bdb"/>
- </and>
- </or>
- </condition>
-
<property name="module.depends" value="common broker management/common" />
- <property name="module.test.depends" value="systests test broker/test common/test management/common client ${systests.optional.depends}" />
+ <property name="module.test.depends" value="broker/tests common/tests management/common client" />
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided -Sqpid-management-common=provided"/>
+ <property name="broker.plugin" value="true"/>
+
<property name="broker-plugins-management-jmx.libs" value=""/>
<import file="../../module.xml" />
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
new file mode 100644
index 0000000000..b7aab78e45
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/CustomRMIServerSocketFactory.java
@@ -0,0 +1,68 @@
+/*
+ * 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.jmx;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.rmi.server.RMIServerSocketFactory;
+
+/**
+ * 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.
+ */
+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;
+ }
+ }
+} \ No newline at end of file
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java
deleted file mode 100644
index c588b40de7..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXActivator.java
+++ /dev/null
@@ -1,136 +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.jmx;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-public class JMXActivator implements BundleActivator
-{
- private static final Logger LOGGER = Logger.getLogger(JMXActivator.class);
-
- private String _bundleName;
- private JMXService _jmxService;
-
- private List<ServiceRegistration> _registeredServices;
-
-
- public void start(final BundleContext ctx) throws Exception
- {
- boolean jmxManagementEnabled = ApplicationRegistry.getInstance().getConfiguration().getJMXManagementEnabled();
-
- if (jmxManagementEnabled)
- {
- _jmxService = new JMXService();
- startJmsService(_jmxService);
-
- _bundleName = ctx.getBundle().getSymbolicName();
-
- _registeredServices = registerServices(ctx);
- }
- else
- {
- LOGGER.debug("Skipping registration of JMX plugin as JMX Management disabled in config. ");
- }
- }
-
- public void stop(final BundleContext bundleContext) throws Exception
- {
- try
- {
- if (_jmxService != null)
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Stopping jmx plugin: " + _bundleName);
- }
- _jmxService.close();
- }
-
- if (_registeredServices != null)
- {
- unregisterServices();
- }
- }
- finally
- {
- _jmxService = null;
- _registeredServices = null;
- }
- }
-
-
- private List<ServiceRegistration> registerServices(BundleContext ctx)
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Registering jmx plugin: " + _bundleName);
- }
-
- List<ServiceRegistration> serviceRegistrations = new ArrayList<ServiceRegistration>();
-
- ServiceRegistration jmxServiceRegistration = ctx.registerService(JMXService.class.getName(), _jmxService, null);
- ServiceRegistration jmxConfigFactoryRegistration = ctx.registerService(ConfigurationPluginFactory.class.getName(), JMXConfiguration.FACTORY, null);
-
- serviceRegistrations.add(jmxServiceRegistration);
- serviceRegistrations.add(jmxConfigFactoryRegistration);
- return serviceRegistrations;
- }
-
- private void startJmsService(JMXService jmxService) throws Exception
- {
- if (LOGGER.isInfoEnabled())
- {
- LOGGER.info("Starting JMX service");
- }
- boolean startedSuccessfully = false;
- try
- {
- jmxService.start();
- startedSuccessfully = true;
- }
- finally
- {
- if (!startedSuccessfully)
- {
- LOGGER.error("JMX failed to start normally, closing service");
- jmxService.close();
- }
- }
- }
-
- private void unregisterServices()
- {
- for (Iterator<ServiceRegistration> iterator = _registeredServices.iterator(); iterator.hasNext();)
- {
- ServiceRegistration service = iterator.next();
- service.unregister();
- }
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java
deleted file mode 100644
index dc9a712f90..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXConfiguration.java
+++ /dev/null
@@ -1,76 +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.jmx;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-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.configuration.plugins.ConfigurationPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class JMXConfiguration extends ConfigurationPlugin
-{
- CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new JMXConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("jmx");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
index 0648235077..a045683de1 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
@@ -20,171 +20,114 @@
*/
package org.apache.qpid.server.jmx;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
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.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
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.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
import java.net.UnknownHostException;
import java.rmi.AlreadyBoundException;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
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
+ * 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 static final String OPERATIONAL_LOGGING_NAME = "JMX";
+
private final MBeanServer _mbeanServer;
+
private JMXConnectorServer _cs;
private Registry _rmiRegistry;
- private boolean _useCustomSocketFactory;
- private final int _jmxPortRegistryServer;
- private final int _jmxPortConnectorServer;
+ private final Broker _broker;
+ private final Port _registryPort;
+ private final Port _connectorPort;
- public JMXManagedObjectRegistry() throws AMQException
+ public JMXManagedObjectRegistry(
+ Broker broker,
+ Port connectorPort, Port registryPort,
+ JMXManagement jmxManagement)
{
- _log.info("Initialising managed object registry using platform MBean server");
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
+ _broker = broker;
+ _registryPort = registryPort;
+ _connectorPort = connectorPort;
- // Retrieve the config parameters
- _useCustomSocketFactory = appRegistry.getConfiguration().getUseCustomRMISocketFactory();
- boolean platformServer = appRegistry.getConfiguration().getPlatformMbeanserver();
+ boolean usePlatformServer = (Boolean)jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER);
_mbeanServer =
- platformServer ? ManagementFactory.getPlatformMBeanServer()
+ usePlatformServer ? ManagementFactory.getPlatformMBeanServer()
: MBeanServerFactory.createMBeanServer(ManagedObject.DOMAIN);
+ }
- _jmxPortRegistryServer = appRegistry.getConfiguration().getJMXPortRegistryServer();
- _jmxPortConnectorServer = appRegistry.getConfiguration().getJMXConnectorServerPort();
-
- }
-
- public void start() throws IOException, ConfigurationException
+ @Override
+ public void start() throws IOException
{
-
- CurrentActor.get().message(ManagementConsoleMessages.STARTUP());
+ CurrentActor.get().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
//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;
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
}
+ else
+ {
+ startRegistryAndConnector();
+ }
+ }
- IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
-
-
- //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
+ private void startRegistryAndConnector() throws IOException
+ {
+ //Socket factories for the RMIConnectorServer, either default or SSL 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();
+ //check ssl enabled option on connector port (note we don't provide ssl for registry server at
+ //moment).
+ boolean connectorSslEnabled = _connectorPort.getTransports().contains(Transport.SSL);
- if (sslEnabled)
+ if (connectorSslEnabled)
{
- //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;
+ String keyStorePath = System.getProperty("javax.net.ssl.keyStore");
+ String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
- if(System.getProperty("javax.net.ssl.keyStore") != null)
- {
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
- }
- else
- {
- keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
- }
+ validateKeyStoreProperties(keyStorePath, keyStorePassword);
- //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());
- }
- }
+ CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(keyStorePath));
//create the SSL RMI socket factories
csf = new SslRMIClientSocketFactory();
@@ -197,27 +140,23 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
ssf = null;
}
+ int jmxPortRegistryServer = _registryPort.getPort();
+ int jmxPortConnectorServer = _connectorPort.getPort();
+
//add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
- RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(_jmxPortRegistryServer));
- HashMap<String,Object> env = new HashMap<String,Object>();
- env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+ RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator(_broker, new InetSocketAddress(jmxPortConnectorServer));
+ HashMap<String,Object> connectorEnv = new HashMap<String,Object>();
+ connectorEnv.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+
+ System.setProperty("java.rmi.server.randomIDs", "true");
+ boolean useCustomSocketFactory = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, Boolean.TRUE.toString()));
/*
* 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));
+ _rmiRegistry = createRmiRegistry(jmxPortRegistryServer, useCustomSocketFactory);
/*
* We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls
@@ -225,57 +164,16 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
* 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.
+ * The registry is exported on the defined management port 'port'.
*/
- 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(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()
- {
-
- public void handleNotification(Notification notification, Object handback)
- {
- final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
- connectionIdUsernameMap.remove(connectionId);
- }
- };
+ final UsernameCachingRMIJRMPServer usernameCachingRmiServer = new UsernameCachingRMIJRMPServer(jmxPortConnectorServer, csf, ssf, connectorEnv);
- String localHost;
- try
- {
- localHost = InetAddress.getLocalHost().getHostName();
- }
- catch(UnknownHostException ex)
- {
- localHost="127.0.0.1";
- }
- final String hostname = localHost;
+ final String localHostName = getLocalhost();
final JMXServiceURL externalUrl = new JMXServiceURL(
- "service:jmx:rmi://"+hostname+":"+(_jmxPortConnectorServer)+"/jndi/rmi://"+hostname+":"+_jmxPortRegistryServer+"/jmxrmi");
+ "service:jmx:rmi://"+localHostName+":"+(jmxPortConnectorServer)+"/jndi/rmi://"+localHostName+":"+jmxPortRegistryServer+"/jmxrmi");
- final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, _jmxPortConnectorServer);
- _cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
+ final JMXServiceURL internalUrl = new JMXServiceURL("rmi", localHostName, jmxPortConnectorServer);
+ _cs = new RMIConnectorServer(internalUrl, connectorEnv, usernameCachingRmiServer, _mbeanServer)
{
@Override
public synchronized void start() throws IOException
@@ -283,7 +181,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
try
{
//manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent
- _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
+ _rmiRegistry.bind("jmxrmi", usernameCachingRmiServer);
}
catch (AlreadyBoundException abe)
{
@@ -311,7 +209,6 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
}
catch (NotBoundException nbe)
{
- // TODO consider if we want to keep new logging
_log.error("Failed to unbind jmxrmi", nbe);
//ignore
}
@@ -326,97 +223,100 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
//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();
+ MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(_broker);
_cs.setMBeanServerForwarder(mbsf);
+ // Install a ManagementLogonLogoffReporter so we can report as users logon/logoff
+ ManagementLogonLogoffReporter jmxManagementUserLogonLogoffReporter = new ManagementLogonLogoffReporter(_broker.getRootMessageLogger(), usernameCachingRmiServer);
+ _cs.addNotificationListener(jmxManagementUserLogonLogoffReporter, jmxManagementUserLogonLogoffReporter, null);
- // 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);
+ // Install the usernameCachingRmiServer as a listener so it may cleanup as clients disconnect
+ _cs.addNotificationListener(usernameCachingRmiServer, usernameCachingRmiServer, null);
_cs.start();
- String connectorServer = (sslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
- CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, _jmxPortConnectorServer));
-
- CurrentActor.get().message(ManagementConsoleMessages.READY(false));
+ String connectorServer = (connectorSslEnabled ? "SSL " : "") + "JMX RMIConnectorServer";
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING(connectorServer, jmxPortConnectorServer));
+ CurrentActor.get().message(ManagementConsoleMessages.READY(OPERATIONAL_LOGGING_NAME));
}
- /*
- * 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
+ private Registry createRmiRegistry(int jmxPortRegistryServer, boolean useCustomRmiRegistry)
+ throws RemoteException
{
-
- public ServerSocket createServerSocket(int port) throws IOException
+ Registry rmiRegistry;
+ if(useCustomRmiRegistry)
{
- return new NoLocalAddressServerSocket(port);
+ _log.debug("Using custom RMIServerSocketFactory");
+ rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, new CustomRMIServerSocketFactory());
}
-
- private static class NoLocalAddressServerSocket extends ServerSocket
+ else
{
- NoLocalAddressServerSocket(int port) throws IOException
- {
- super(port);
- }
+ _log.debug("Using default RMIServerSocketFactory");
+ rmiRegistry = LocateRegistry.createRegistry(jmxPortRegistryServer, null, null);
+ }
- @Override
- public Socket accept() throws IOException
- {
- Socket s = new NoLocalAddressSocket();
- super.implAccept(s);
- return s;
- }
+ CurrentActor.get().message(ManagementConsoleMessages.LISTENING("RMI Registry", jmxPortRegistryServer));
+ return rmiRegistry;
+ }
+
+ private void validateKeyStoreProperties(String keyStorePath, String keyStorePassword) throws FileNotFoundException
+ {
+ if (keyStorePath == null)
+ {
+ throw new IllegalConfigurationException("JVM system property 'javax.net.ssl.keyStore' is not set, "
+ + "unable to start requested SSL protected JMX connector");
+ }
+ if (keyStorePassword == null)
+ {
+ throw new IllegalConfigurationException( "JVM system property 'javax.net.ssl.keyStorePassword' is not set, "
+ + "unable to start requested SSL protected JMX connector");
}
- private static class NoLocalAddressSocket extends Socket
+ File ksf = new File(keyStorePath);
+ if (!ksf.exists())
{
- @Override
- public InetAddress getInetAddress()
- {
- return null;
- }
+ 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.");
}
}
-
+ @Override
public void registerObject(ManagedObject managedObject) throws JMException
{
_mbeanServer.registerMBean(managedObject, managedObject.getObjectName());
}
+ @Override
public void unregisterObject(ManagedObject managedObject) throws JMException
{
_mbeanServer.unregisterMBean(managedObject.getObjectName());
}
+ @Override
+ public void close()
+ {
+ _log.debug("close() called");
+
+ closeConnectorAndRegistryServers();
+
+ unregisterAllMbeans();
+
+ CurrentActor.get().message(ManagementConsoleMessages.STOPPED(OPERATIONAL_LOGGING_NAME));
+ }
+
+ private void closeConnectorAndRegistryServers()
+ {
+ closeConnectorServer();
+ closeRegistryServer();
+ }
+
// checks if the system properties are set which enable the JVM's out-of-the-box JMXAgent.
private boolean areOutOfTheBoxJMXOptionsSet()
{
@@ -433,29 +333,26 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
return false;
}
- //Stops the JMXConnectorServer and RMIRegistry, then unregisters any remaining MBeans from the MBeanServer
- public void close()
+ private String getLocalhost()
{
- _log.debug("close() called");
-
- if (_cs != null)
+ String localHost;
+ try
{
- // 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);
- }
+ localHost = InetAddress.getLocalHost().getHostName();
}
-
+ catch(UnknownHostException ex)
+ {
+ localHost="127.0.0.1";
+ }
+ return localHost;
+ }
+
+ private void closeRegistryServer()
+ {
if (_rmiRegistry != null)
{
// Stopping the RMI registry
- CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("RMI Registry", _jmxPortRegistryServer));
+ CurrentActor.get().message(ManagementConsoleMessages.SHUTTING_DOWN("RMI Registry", _registryPort.getPort()));
try
{
boolean success = UnicastRemoteObject.unexportObject(_rmiRegistry, false);
@@ -468,8 +365,36 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
{
_log.error("Exception while closing the RMI Registry: ", e);
}
+ finally
+ {
+ _rmiRegistry = null;
+ }
+ }
+ }
+
+ private void closeConnectorServer()
+ {
+ 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);
+ }
+ finally
+ {
+ _cs = null;
+ }
}
-
+ }
+
+ private void unregisterAllMbeans()
+ {
//ObjectName query to gather all Qpid related MBeans
ObjectName mbeanNameQuery = null;
try
@@ -492,8 +417,6 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
_log.error("Exception unregistering MBean '"+ name +"': " + e.getMessage());
}
}
-
- CurrentActor.get().message(ManagementConsoleMessages.STOPPED());
}
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
new file mode 100644
index 0000000000..8f087ba50c
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagement.java
@@ -0,0 +1,343 @@
+/*
+ *
+ * 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.jmx;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.JMException;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean;
+import org.apache.qpid.server.jmx.mbeans.UserManagementMBean;
+import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean;
+import org.apache.qpid.server.jmx.mbeans.Shutdown;
+import org.apache.qpid.server.jmx.mbeans.VirtualHostMBean;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
+import org.apache.qpid.server.model.Plugin;
+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.VirtualHost;
+import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class JMXManagement extends AbstractPluginAdapter implements ConfigurationChangeListener
+{
+ private static final Logger LOGGER = Logger.getLogger(JMXManagement.class);
+
+ public static final String PLUGIN_TYPE = "MANAGEMENT-JMX";
+
+ // attributes
+ public static final String USE_PLATFORM_MBEAN_SERVER = "usePlatformMBeanServer";
+ public static final String NAME = "name";
+
+ // default values
+ public static final String DEFAULT_NAME = "JMXManagement";
+ public static final boolean DEFAULT_USE_PLATFORM_MBEAN_SERVER = true;
+
+ @SuppressWarnings("serial")
+ private static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableCollection(new HashSet<String>(Plugin.AVAILABLE_ATTRIBUTES){{
+ add(NAME);
+ add(USE_PLATFORM_MBEAN_SERVER);
+ add(PluginFactory.PLUGIN_TYPE);
+ }});
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Object> DEFAULTS = new HashMap<String, Object>(){{
+ put(USE_PLATFORM_MBEAN_SERVER, DEFAULT_USE_PLATFORM_MBEAN_SERVER);
+ put(NAME, DEFAULT_NAME);
+ put(PluginFactory.PLUGIN_TYPE, PLUGIN_TYPE);
+ }};
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Class<?>> ATTRIBUTE_TYPES = new HashMap<String, Class<?>>(){{
+ put(USE_PLATFORM_MBEAN_SERVER, Boolean.class);
+ put(NAME, String.class);
+ put(PluginFactory.PLUGIN_TYPE, String.class);
+ }};
+
+ private final Broker _broker;
+ private JMXManagedObjectRegistry _objectRegistry;
+
+ private final Map<ConfiguredObject, AMQManagedObject> _children = new HashMap<ConfiguredObject, AMQManagedObject>();
+
+ public JMXManagement(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), broker.getTaskExecutor());
+ _broker = broker;
+ addParent(Broker.class, broker);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if(desiredState == State.ACTIVE)
+ {
+ try
+ {
+ start();
+ }
+ catch (JMException e)
+ {
+ throw new RuntimeException("Couldn't start JMX management", e);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Couldn't start JMX management", e);
+ }
+ return true;
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ stop();
+ return true;
+ }
+ return false;
+ }
+
+ private void start() throws JMException, IOException
+ {
+ Port connectorPort = null;
+ Port registryPort = null;
+ Collection<Port> ports = _broker.getPorts();
+ for (Port port : ports)
+ {
+ if (State.QUIESCED.equals(port.getActualState()))
+ {
+ continue;
+ }
+
+ if(isRegistryPort(port))
+ {
+ registryPort = port;
+ }
+ else if(isConnectorPort(port))
+ {
+ connectorPort = port;
+ }
+ }
+ if(connectorPort == null)
+ {
+ throw new IllegalStateException("No JMX connector port found supporting protocol " + Protocol.JMX_RMI);
+ }
+ if(registryPort == null)
+ {
+ throw new IllegalStateException("No JMX RMI port found supporting protocol " + Protocol.RMI);
+ }
+
+ _objectRegistry = new JMXManagedObjectRegistry(_broker, connectorPort, registryPort, this);
+
+ _broker.addChangeListener(this);
+
+ synchronized (_children)
+ {
+ for(VirtualHost virtualHost : _broker.getVirtualHosts())
+ {
+ if(!_children.containsKey(virtualHost))
+ {
+ LOGGER.debug("Create MBean for virtual host:" + virtualHost.getName());
+ VirtualHostMBean mbean = new VirtualHostMBean(virtualHost, _objectRegistry);
+ LOGGER.debug("Check for additional MBeans for virtual host:" + virtualHost.getName());
+ createAdditionalMBeansFromProviders(virtualHost, mbean);
+ }
+ }
+ Collection<AuthenticationProvider> authenticationProviders = _broker.getAuthenticationProviders();
+ for (AuthenticationProvider authenticationProvider : authenticationProviders)
+ {
+ if(authenticationProvider instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ UserManagementMBean mbean = new UserManagementMBean(
+ (PasswordCredentialManagingAuthenticationProvider) authenticationProvider,
+ _objectRegistry);
+ _children.put(authenticationProvider, mbean);
+ }
+ }
+ }
+ new Shutdown(_objectRegistry);
+ new ServerInformationMBean(_objectRegistry, _broker);
+ if (LoggingManagementFacade.getCurrentInstance() != null)
+ {
+ new LoggingManagementMBean(LoggingManagementFacade.getCurrentInstance(), _objectRegistry);
+ }
+ _objectRegistry.start();
+ }
+
+ private boolean isConnectorPort(Port port)
+ {
+ return port.getProtocols().contains(Protocol.JMX_RMI);
+ }
+
+ private boolean isRegistryPort(Port port)
+ {
+ return port.getProtocols().contains(Protocol.RMI);
+ }
+
+ private void stop()
+ {
+ synchronized (_children)
+ {
+ for(ConfiguredObject object : _children.keySet())
+ {
+ AMQManagedObject mbean = _children.get(object);
+ if (mbean instanceof ConfigurationChangeListener)
+ {
+ object.removeChangeListener((ConfigurationChangeListener)mbean);
+ }
+ try
+ {
+ mbean.unregister();
+ }
+ catch (JMException e)
+ {
+ LOGGER.error("Error unregistering mbean", e);
+ }
+ }
+ _children.clear();
+ }
+ _broker.removeChangeListener(this);
+ _objectRegistry.close();
+ }
+
+ @Override
+ public void stateChanged(ConfiguredObject object, State oldState, State newState)
+ {
+ // no-op
+ }
+
+ @Override
+ public void childAdded(ConfiguredObject object, ConfiguredObject child)
+ {
+ synchronized (_children)
+ {
+ try
+ {
+ AMQManagedObject mbean;
+ if(child instanceof VirtualHost)
+ {
+ VirtualHost vhostChild = (VirtualHost)child;
+ mbean = new VirtualHostMBean(vhostChild, _objectRegistry);
+ }
+ else if(child instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ mbean = new UserManagementMBean((PasswordCredentialManagingAuthenticationProvider) child, _objectRegistry);
+ }
+ else
+ {
+ mbean = null;
+ }
+
+ if (mbean != null)
+ {
+ createAdditionalMBeansFromProviders(child, mbean);
+ }
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Error creating mbean", e);
+ // TODO - Implement error reporting on mbean creation
+ }
+ }
+ }
+
+ @Override
+ public void childRemoved(ConfiguredObject object, ConfiguredObject child)
+ {
+ // TODO - implement vhost removal (possibly just removing the instanceof check below)
+
+ synchronized (_children)
+ {
+ if(child instanceof PasswordCredentialManagingAuthenticationProvider)
+ {
+ AMQManagedObject mbean = _children.remove(child);
+ if(mbean != null)
+ {
+ try
+ {
+ mbean.unregister();
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Error creating mbean", e);
+ //TODO - report error on removing child MBean
+ }
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ // no-op
+ }
+
+ private void createAdditionalMBeansFromProviders(ConfiguredObject child, AMQManagedObject mbean) throws JMException
+ {
+ _children.put(child, mbean);
+
+ QpidServiceLoader<MBeanProvider> qpidServiceLoader = new QpidServiceLoader<MBeanProvider>();
+ for (MBeanProvider provider : qpidServiceLoader.instancesOf(MBeanProvider.class))
+ {
+ LOGGER.debug("Consulting mbean provider : " + provider + " for child : " + child);
+ if (provider.isChildManageableByMBean(child))
+ {
+ LOGGER.debug("Provider will create mbean ");
+ provider.createMBean(child, mbean);
+ // TODO track the mbeans that have been created on behalf of a child in a map, then
+ // if the child is ever removed, destroy these beans too.
+ }
+ }
+ }
+
+ /** Added for testing purposes */
+ Broker getBroker()
+ {
+ return _broker;
+ }
+
+ @Override
+ public String getName()
+ {
+ return (String)getAttribute(NAME);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
new file mode 100644
index 0000000000..c2186c372b
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.jmx;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
+
+public class JMXManagementFactory implements PluginFactory
+{
+ private static final Logger LOGGER = Logger.getLogger(JMXManagementFactory.class);
+
+ @Override
+ public Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker)
+ {
+ if (JMXManagement.PLUGIN_TYPE.equals(attributes.get(PLUGIN_TYPE)))
+ {
+ return new JMXManagement(id, broker, attributes);
+ }
+ else
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Skipping registration of JMX plugin as JMX Management disabled in config.");
+ }
+ return null;
+ }
+ }
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java
deleted file mode 100644
index 7a232d2584..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXService.java
+++ /dev/null
@@ -1,193 +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.jmx;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import javax.management.JMException;
-import javax.management.StandardMBean;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.UserManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.ConfigurationManagementMBean;
-import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean;
-import org.apache.qpid.server.jmx.mbeans.Shutdown;
-import org.apache.qpid.server.jmx.mbeans.VirtualHostMBean;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
-import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.ConfigurationChangeListener;
-import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
-import org.apache.qpid.server.model.State;
-import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-
-public class JMXService implements ConfigurationChangeListener
-{
- private static final ClassLoader BUNDLE_CLASSLOADER = JMXService.class.getClassLoader();
-
- private static final Logger LOGGER = Logger.getLogger(JMXService.class);
-
- private final Broker _broker;
- private final JMXManagedObjectRegistry _objectRegistry;
- private final Shutdown _shutdown;
- private final ServerInformationMBean _serverInfo;
- private final ConfigurationManagementMBean _configManagement;
- private final LoggingManagementMBean _loggingManagement;
-
- private final Map<ConfiguredObject, AMQManagedObject> _children = new HashMap<ConfiguredObject, AMQManagedObject>();
-
- public JMXService() throws AMQException, JMException
- {
- _broker = ApplicationRegistry.getInstance().getBroker();
- _objectRegistry = new JMXManagedObjectRegistry();
-
- _broker.addChangeListener(this);
- synchronized (_children)
- {
- for(VirtualHost virtualHost : _broker.getVirtualHosts())
- {
- if(!_children.containsKey(virtualHost))
- {
- _children.put(virtualHost, new VirtualHostMBean(virtualHost, _objectRegistry));
- }
- }
- }
- _shutdown = new Shutdown(_objectRegistry);
- _serverInfo = new ServerInformationMBean(_objectRegistry, _broker);
- _configManagement = new ConfigurationManagementMBean(_objectRegistry);
- _loggingManagement = new LoggingManagementMBean(LoggingFacade.getCurrentInstance(), _objectRegistry);
- }
-
- public void start() throws IOException, ConfigurationException
- {
- _objectRegistry.start();
- }
-
- public void close()
- {
- _broker.removeChangeListener(this);
-
- _objectRegistry.close();
- }
-
- public void stateChanged(ConfiguredObject object, State oldState, State newState)
- {
-
- }
-
- public void childAdded(ConfiguredObject object, ConfiguredObject child)
- {
- synchronized (_children)
- {
- try
- {
- AMQManagedObject mbean;
- if(child instanceof VirtualHost)
- {
- VirtualHost vhostChild = (VirtualHost)child;
- mbean = new VirtualHostMBean(vhostChild, _objectRegistry);
- }
- else if(child instanceof PasswordCredentialManagingAuthenticationProvider)
- {
- mbean = new UserManagementMBean((PasswordCredentialManagingAuthenticationProvider) child, _objectRegistry);
- }
- else
- {
- mbean = null;
- }
-
- if (mbean != null)
- {
- createAdditionalMBeansFromProviders(child, mbean);
- }
- }
- catch(JMException e)
- {
- LOGGER.error("Error creating mbean", e);
- // TODO - Implement error reporting on mbean creation
- }
- }
- }
-
-
- public void childRemoved(ConfiguredObject object, ConfiguredObject child)
- {
- // TODO - implement vhost removal (possibly just removing the instanceof check below)
-
- synchronized (_children)
- {
- if(child instanceof PasswordCredentialManagingAuthenticationProvider)
- {
- AMQManagedObject mbean = _children.remove(child);
- if(mbean != null)
- {
- try
- {
- mbean.unregister();
- }
- catch(JMException e)
- {
- LOGGER.error("Error creating mbean", e);
- //TODO - report error on removing child MBean
- }
- }
- }
-
- }
- }
-
- private void createAdditionalMBeansFromProviders(ConfiguredObject child, AMQManagedObject mbean) throws JMException
- {
- _children.put(child, mbean);
-
- for (Iterator<MBeanProvider> iterator = getMBeanProviderIterator(); iterator.hasNext();)
- {
- MBeanProvider provider = iterator.next();
- LOGGER.debug("Consulting mbean provider : " + provider + " for child : " + child);
- if (provider.isChildManageableByMBean(child))
- {
- LOGGER.debug("Provider will create mbean ");
- StandardMBean bean = provider.createMBean(child, mbean);
- // TODO track the mbeans that have been created on behalf of a child in a map, then
- // if the child is ever removed, destroy these beans too.
- }
- }
- }
-
- /**
- * Finds all classes implementing the {@link MBeanProvider} interface. This will find
- * <b>only</b> those classes which are visible to the classloader of this OSGI bundle.
- */
- private Iterator<MBeanProvider> getMBeanProviderIterator()
- {
- return ServiceLoader.load(MBeanProvider.class, BUNDLE_CLASSLOADER).iterator();
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
index a2a0d2d093..8bc2afb176 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
@@ -22,26 +22,22 @@ package org.apache.qpid.server.jmx;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.logging.actors.CurrentActor;
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.model.Broker;
+import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
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.RuntimeErrorException;
-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;
@@ -51,27 +47,32 @@ import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.Arrays;
-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
+public class MBeanInvocationHandlerImpl implements InvocationHandler
{
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();
+ private final ManagementActor _logActor;
- public static MBeanServerForwarder newProxyInstance()
+ private final boolean _managementRightsInferAllAccess;
+ private final Broker _broker;
+
+ MBeanInvocationHandlerImpl(Broker broker)
+ {
+ _managementRightsInferAllAccess = Boolean.valueOf(System.getProperty(BrokerProperties.PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS, "true"));
+ _broker = broker;
+ _logActor = new ManagementActor(broker.getRootMessageLogger());
+ }
+
+ public static MBeanServerForwarder newProxyInstance(Broker broker)
{
- final InvocationHandler handler = new MBeanInvocationHandlerImpl();
+ final InvocationHandler handler = new MBeanInvocationHandlerImpl(broker);
final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler);
@@ -101,7 +102,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
{
ObjectName mbean = (ObjectName) args[0];
- if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
+ if(!ManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
{
return true;
}
@@ -151,11 +152,13 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
return method.invoke(_mbs, args);
}
- // Retrieve JMXPrincipal from Subject
- Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
- if (principals == null || principals.isEmpty())
+ try
+ {
+ AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ }
+ catch(Exception e)
{
- throw new SecurityException("Access denied: no JMX principal");
+ throw new SecurityException("Access denied: no authenticated principal", e);
}
// Save the subject
@@ -211,11 +214,16 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
SecurityManager security;
if (vhost == null)
{
- security = _appRegistry.getSecurityManager();
+ security = _broker.getSecurityManager();
}
else
{
- security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
+ VirtualHost virtualHost = _broker.findVirtualHostByName(vhost);
+ if (virtualHost == null)
+ {
+ throw new IllegalArgumentException("Virtual host with name '" + vhost + "' is not found.");
+ }
+ security = virtualHost.getSecurityManager();
}
methodName = getMethodName(method, args);
@@ -360,50 +368,5 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
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];
- }
-
- // use a separate instance of actor as subject is not set on connect/disconnect
- // we need to pass principal name explicitly into log actor
- LogActor logActor = new ManagementActor(_appRegistry.getRootMessageLogger(), user);
- 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-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
index 83909dbe72..b80ddc7fac 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java
@@ -21,17 +21,16 @@
package org.apache.qpid.server.jmx;
-import java.util.ServiceLoader;
-
import javax.management.JMException;
import javax.management.StandardMBean;
import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
/**
* A provider of an mbean implementation.
*
- * Provider implementations are advertised as services and loaded via {@link ServiceLoader}.
+ * Provider implementations are advertised as services and loaded by a {@link QpidServiceLoader}.
*/
public interface MBeanProvider
{
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
new file mode 100644
index 0000000000..ae0574dc21
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporter.java
@@ -0,0 +1,95 @@
+/*
+ * 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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+import static javax.management.remote.JMXConnectionNotification.OPENED;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+
+public class ManagementLogonLogoffReporter implements NotificationListener, NotificationFilter
+{
+ private static final Logger LOGGER = Logger.getLogger(ManagementLogonLogoffReporter.class);
+ private final RootMessageLogger _rootMessageLogger;
+ private final UsernameAccessor _usernameAccessor;
+
+ public ManagementLogonLogoffReporter(RootMessageLogger rootMessageLogger, UsernameAccessor usernameAccessor)
+ {
+ _rootMessageLogger = rootMessageLogger;
+ _usernameAccessor = usernameAccessor;
+ }
+
+ @Override
+ public void handleNotification(final Notification notification, final Object handback)
+ {
+ final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
+ final String type = notification.getType();
+
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Notification connectionId : " + connectionId + " type : " + type);
+ }
+
+ String user = _usernameAccessor.getUsernameForConnectionId(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];
+ }
+
+ // use a separate instance of actor as subject is not set on connect/disconnect
+ // we need to pass principal name explicitly into log actor
+ LogActor logActor = new ManagementActor(_rootMessageLogger, user);
+ 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));
+ }
+ }
+
+ @Override
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return notification instanceof JMXConnectionNotification && isLogonTypeEvent(notification);
+ }
+
+ private boolean isLogonTypeEvent(Notification notification)
+ {
+ final String type = notification.getType();
+ return CLOSED.equals(type) || FAILED.equals(type) || OPENED.equals(type);
+ }
+
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
new file mode 100644
index 0000000000..0cbb0d2687
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameAccessor.java
@@ -0,0 +1,26 @@
+/*
+ * 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.jmx;
+
+public interface UsernameAccessor
+{
+ public String getUsernameForConnectionId(String connectionId);
+
+}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
new file mode 100644
index 0000000000..838e9e5664
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/UsernameCachingRMIJRMPServer.java
@@ -0,0 +1,100 @@
+/*
+ * 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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+
+import java.io.IOException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.rmi.RMIConnection;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+/**
+ * An implementation of RMIJRMPServerImpl that caches the usernames of users as they log-on
+ * and makes the same available via {@link UsernameAccessor#getUsernameForConnectionId(String)}.
+ *
+ * Caller is responsible for installing this object as a {@link NotificationListener} of the
+ * {@link JMXConnectorServer} so the cache entries are removed as the clients disconnect.
+ *
+ */
+public class UsernameCachingRMIJRMPServer extends RMIJRMPServerImpl implements NotificationListener, NotificationFilter, UsernameAccessor
+{
+ // ConnectionId is guaranteed to be unique per client connection, according to the JMX spec.
+ private final Map<String, String> _connectionIdUsernameMap = new ConcurrentHashMap<String, String>();
+
+ UsernameCachingRMIJRMPServer(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf,
+ Map<String, ?> env) throws IOException
+ {
+ super(port, csf, ssf, env);
+ }
+
+ @Override
+ protected RMIConnection makeClient(String connectionId, Subject subject) throws IOException
+ {
+ final RMIConnection makeClient = super.makeClient(connectionId, subject);
+ final AuthenticatedPrincipal authenticatedPrincipalFromSubject = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ _connectionIdUsernameMap.put(connectionId, authenticatedPrincipalFromSubject.getName());
+ return makeClient;
+ }
+
+ @Override
+ public String getUsernameForConnectionId(String connectionId)
+ {
+ return _connectionIdUsernameMap.get(connectionId);
+ }
+
+ @Override
+ public void handleNotification(Notification notification, Object handback)
+ {
+ final String connectionId = ((JMXConnectionNotification) notification).getConnectionId();
+ removeConnectionIdFromCache(connectionId);
+ }
+
+ @Override
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return isClientDisconnectEvent(notification);
+ }
+
+ private void removeConnectionIdFromCache(String connectionId)
+ {
+ _connectionIdUsernameMap.remove(connectionId);
+ }
+
+ private boolean isClientDisconnectEvent(Notification notification)
+ {
+ final String type = notification.getType();
+ return CLOSED.equals(type) || FAILED.equals(type);
+ }
+
+} \ No newline at end of file
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java
deleted file mode 100644
index beffb4eaa9..0000000000
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/ConfigurationManagementMBean.java
+++ /dev/null
@@ -1,56 +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.jmx.mbeans;
-
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
-import org.apache.qpid.server.jmx.AMQManagedObject;
-import org.apache.qpid.server.jmx.ManagedObject;
-import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import javax.management.JMException;
-import javax.management.NotCompliantMBeanException;
-
-public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement
-{
-
- public ConfigurationManagementMBean(ManagedObjectRegistry registry) throws JMException
- {
- super(ConfigurationManagement.class, ConfigurationManagement.TYPE, registry);
- register();
- }
-
- public String getObjectInstanceName()
- {
- return ConfigurationManagement.TYPE;
- }
-
- public void reloadSecurityConfiguration() throws Exception
- {
- ApplicationRegistry.getInstance().getConfiguration().reparseConfigFileSecuritySections();
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return null;
- }
-}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
index 0dac8ebe37..d6f4b5d8c9 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBean.java
@@ -26,7 +26,7 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.server.jmx.AMQManagedObject;
import org.apache.qpid.server.jmx.ManagedObject;
import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
import org.apache.qpid.server.logging.log4j.LoggingFacadeException;
import javax.management.JMException;
@@ -55,7 +55,8 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
private static final TabularType LOGGER_LEVEL_TABULAR_TYE;
private static final CompositeType LOGGER_LEVEL_COMPOSITE_TYPE;
- private final LoggingFacade _configurator;
+ private final LoggingManagementFacade _loggingManagementFacade;
+ private final String[] _allAvailableLogLevels;
static
{
@@ -77,12 +78,13 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
throw new ExceptionInInitializerError(e);
}
}
-
- public LoggingManagementMBean(LoggingFacade configurator, ManagedObjectRegistry registry) throws JMException
+
+ public LoggingManagementMBean(LoggingManagementFacade loggingManagementFacade, ManagedObjectRegistry registry) throws JMException
{
super(LoggingManagement.class, LoggingManagement.TYPE, registry);
register();
- _configurator = configurator;
+ _loggingManagementFacade = loggingManagementFacade;
+ _allAvailableLogLevels = buildAllAvailableLoggerLevelsWithInheritedPsuedoLogLevel(_loggingManagementFacade);
}
@Override
@@ -100,30 +102,26 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
@Override
public Integer getLog4jLogWatchInterval()
{
- return _configurator.getLog4jLogWatchInterval();
+ return _loggingManagementFacade.getLog4jLogWatchInterval();
}
@Override
public String[] getAvailableLoggerLevels()
{
- List<String> levels = _configurator.getAvailableLoggerLevels();
- List<String> mbeanLevels = new ArrayList<String>(levels);
- mbeanLevels.add(INHERITED_PSUEDO_LOG_LEVEL);
-
- return mbeanLevels.toArray(new String[mbeanLevels.size()]);
+ return _allAvailableLogLevels;
}
@Override
public TabularData viewEffectiveRuntimeLoggerLevels()
{
- Map<String, String> levels = _configurator.retrieveRuntimeLoggersLevels();
+ Map<String, String> levels = _loggingManagementFacade.retrieveRuntimeLoggersLevels();
return createTabularDataFromLevelsMap(levels);
}
@Override
public String getRuntimeRootLoggerLevel()
{
- return _configurator.retrieveRuntimeRootLoggerLevel();
+ return _loggingManagementFacade.retrieveRuntimeRootLoggerLevel();
}
@Override
@@ -139,7 +137,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
return false;
}
- _configurator.setRuntimeRootLoggerLevel(level);
+ _loggingManagementFacade.setRuntimeRootLoggerLevel(level);
return true;
}
@@ -159,7 +157,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setRuntimeLoggerLevel(logger, validatedLevel);
+ _loggingManagementFacade.setRuntimeLoggerLevel(logger, validatedLevel);
}
catch (LoggingFacadeException e)
{
@@ -175,7 +173,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
Map<String,String> levels;
try
{
- levels = _configurator.retrieveConfigFileLoggersLevels();
+ levels = _loggingManagementFacade.retrieveConfigFileLoggersLevels();
}
catch (LoggingFacadeException e)
{
@@ -191,7 +189,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
{
try
{
- return _configurator.retrieveConfigFileRootLoggerLevel().toUpperCase();
+ return _loggingManagementFacade.retrieveConfigFileRootLoggerLevel().toUpperCase();
}
catch (LoggingFacadeException e)
{
@@ -216,7 +214,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setConfigFileLoggerLevel(logger, validatedLevel);
+ _loggingManagementFacade.setConfigFileLoggerLevel(logger, validatedLevel);
}
catch (LoggingFacadeException e)
{
@@ -241,7 +239,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.setConfigFileRootLoggerLevel(level);
+ _loggingManagementFacade.setConfigFileRootLoggerLevel(level);
return true;
}
catch (LoggingFacadeException e)
@@ -257,7 +255,7 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
try
{
- _configurator.reload();
+ _loggingManagementFacade.reload();
}
catch (LoggingFacadeException e)
{
@@ -283,9 +281,8 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
private void validateLevelNotAllowingInherited(String level)
{
- final List<String> availableLoggerLevels = _configurator.getAvailableLoggerLevels();
- if (!availableLoggerLevels.contains(level)
- && !availableLoggerLevels.contains(String.valueOf(level).toUpperCase()))
+ final List<String> availableLoggerLevels = _loggingManagementFacade.getAvailableLoggerLevels();
+ if (level == null || !availableLoggerLevels.contains(level.toUpperCase()))
{
throw new IllegalArgumentException(level + " not known");
}
@@ -305,7 +302,6 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
return loggerLevelList;
}
-
private CompositeData createRow(String loggerName, String level)
{
Object[] itemData = {loggerName, level.toUpperCase()};
@@ -321,4 +317,13 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM
throw new RuntimeException(ode);
}
}
+
+ private String[] buildAllAvailableLoggerLevelsWithInheritedPsuedoLogLevel(LoggingManagementFacade loggingManagementFacade)
+ {
+ List<String> levels = loggingManagementFacade.getAvailableLoggerLevels();
+ List<String> mbeanLevels = new ArrayList<String>(levels);
+ mbeanLevels.add(INHERITED_PSUEDO_LOG_LEVEL);
+
+ return mbeanLevels.toArray(new String[mbeanLevels.size()]);
+ }
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
index 5c8b0f7194..94fac218ff 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/QueueMBean.java
@@ -513,7 +513,6 @@ public class QueueMBean extends AMQManagedObject implements ManagedQueue, QueueN
{
_queue.visit(new QueueEntryVisitor()
{
-
public boolean visit(final QueueEntry entry)
{
final ServerMessage message = entry.getMessage();
@@ -525,11 +524,9 @@ public class QueueMBean extends AMQManagedObject implements ManagedQueue, QueueN
&& (messageId <= toMessageId))
{
txn.dequeue(entry);
- return true;
}
- return false;
}
- return true;
+ return false;
}
});
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
index 6990a40dee..51dea92775 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostMBean.java
@@ -65,7 +65,7 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
_managerMBean = new VirtualHostManagerMBean(this);
}
- private void initQueues() throws JMException
+ private void initQueues()
{
synchronized (_children)
{
@@ -73,13 +73,20 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(queue))
{
- _children.put(queue, new QueueMBean(queue, this));
+ try
+ {
+ _children.put(queue, new QueueMBean(queue, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create queue mbean for queue " + queue.getName(), e);
+ }
}
}
}
}
- private void initExchanges() throws JMException
+ private void initExchanges()
{
synchronized (_children)
{
@@ -87,13 +94,20 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(exchange))
{
- _children.put(exchange, new ExchangeMBean(exchange, this));
+ try
+ {
+ _children.put(exchange, new ExchangeMBean(exchange, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create exchange mbean for exchange " + exchange.getName(), e);
+ }
}
}
}
}
- private void initConnections() throws JMException
+ private void initConnections()
{
synchronized (_children)
{
@@ -101,7 +115,14 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
{
if(!_children.containsKey(conn))
{
- _children.put(conn, new ConnectionMBean(conn, this));
+ try
+ {
+ _children.put(conn, new ConnectionMBean(conn, this));
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Cannot create connection mbean for connection " + conn.getName(), e);
+ }
}
}
}
@@ -119,7 +140,7 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
public void stateChanged(ConfiguredObject object, State oldState, State newState)
{
- // ignore
+ // no-op
}
public void childAdded(ConfiguredObject object, ConfiguredObject child)
@@ -208,4 +229,35 @@ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtual
return queues;
}
+
+ @Override
+ public void unregister() throws JMException
+ {
+ synchronized (_children)
+ {
+ for (AMQManagedObject mbean : _children.values())
+ {
+ if(mbean != null)
+ {
+ try
+ {
+ mbean.unregister();
+ }
+ catch(JMException e)
+ {
+ LOGGER.error("Failed to remove mbean for child : " + mbean, e);
+ }
+ }
+ }
+ _children.clear();
+ }
+ _managerMBean.unregister();
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ // no-op
+ }
+
}
diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
index b3dbbc424a..67ac1bdc7c 100644
--- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
+++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/mbeans/VirtualHostManagerMBean.java
@@ -229,10 +229,9 @@ public class VirtualHostManagerMBean extends AbstractStatisticsGatheringMBean<Vi
return getObjectNameForSingleInstanceMBean();
}
- public synchronized boolean isStatisticsEnabled()
+ public boolean isStatisticsEnabled()
{
- updateStats();
- return false; //TODO - implement isStatisticsEnabled
+ return true;
}
}
diff --git a/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory b/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
new file mode 100644
index 0000000000..8fa778269e
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.PluginFactory
@@ -0,0 +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.
+#
+org.apache.qpid.server.jmx.JMXManagementFactory
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.java
new file mode 100644
index 0000000000..5af1369239
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/JMXManagementFactoryTest.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.jmx;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class JMXManagementFactoryTest extends QpidTestCase
+{
+ private final JMXManagementFactory _jmxManagementFactory = new JMXManagementFactory();
+ private final Map<String, Object> _attributes = new HashMap<String, Object>();
+ private final Broker _broker = mock(Broker.class);
+ private UUID _id = UUID.randomUUID();
+
+ public void testJMXConfigured() throws Exception
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, JMXManagement.PLUGIN_TYPE);
+
+ JMXManagement jmxManagement = (JMXManagement) _jmxManagementFactory.createInstance(_id, _attributes, _broker);
+
+ assertNotNull(jmxManagement);
+ assertEquals("Unexpected plugin type", JMXManagement.PLUGIN_TYPE, jmxManagement.getAttribute(JMXManagementFactory.PLUGIN_TYPE));
+ assertEquals("Unexpected default mbean platform", JMXManagement.DEFAULT_USE_PLATFORM_MBEAN_SERVER, jmxManagement.getAttribute(JMXManagement.USE_PLATFORM_MBEAN_SERVER));
+ assertEquals("Unexpected default name", JMXManagement.DEFAULT_NAME, jmxManagement.getAttribute(JMXManagement.NAME));
+ }
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeMissing()
+ {
+ assertNull(_jmxManagementFactory.createInstance(_id, _attributes, _broker));
+ }
+
+ public void testCreateInstanceReturnsNullWhenPluginTypeNotJmx()
+ {
+ _attributes.put(PluginFactory.PLUGIN_TYPE, "notJmx");
+ assertNull(_jmxManagementFactory.createInstance(_id, _attributes, _broker));
+ }
+}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java
deleted file mode 100644
index c1df9afc5d..0000000000
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogActorTest.java
+++ /dev/null
@@ -1,170 +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.jmx;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.management.JMException;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-
-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.logging.actors.CurrentActor;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPlugin;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class ManagementLogActorTest extends QpidTestCase
-{
- private ApplicationRegistry _registry;
- private JMXManagedObjectRegistry _objectRegistry;
- private int _registryPort;
- private int _connectorPort;
- private TestPlugin _plugin;
-
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- _registryPort = findFreePort();
- _connectorPort = getNextAvailable(_registryPort + 1);
- XMLConfiguration config = new XMLConfiguration();
- config.addProperty(ServerConfiguration.MGMT_JMXPORT_REGISTRYSERVER, _registryPort + "");
- config.addProperty(ServerConfiguration.MGMT_JMXPORT_CONNECTORSERVER, _connectorPort + "");
- _registry = new TestApplicationRegistry(new ServerConfiguration(config));
- ApplicationRegistry.initialise(_registry);
-
- _plugin = new TestPlugin();
- _registry.getSecurityManager().addHostPlugin(_plugin);
-
- _objectRegistry = new JMXManagedObjectRegistry();
- new TestMBean(_objectRegistry);
- _objectRegistry.start();
- }
-
- public void tearDown() throws Exception
- {
- _objectRegistry.close();
- ApplicationRegistry.remove();
- super.tearDown();
- }
-
- public void testPrincipalInLogMessage() throws Throwable
- {
- Map<String, Object> environment = new HashMap<String, Object>();
- environment.put(JMXConnector.CREDENTIALS, new String[] { "admin", "admin" });
- String urlString = "service:jmx:rmi:///jndi/rmi://localhost:" + _registryPort + "/jmxrmi";
- JMXServiceURL url = new JMXServiceURL(urlString);
- JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment);
- MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
- ObjectName mbeanObject = new ObjectName("org.apache.qpid:type=TestMBean,name=test");
-
- String actorLogMessage = (String) mbsc.getAttribute(mbeanObject, "ActorLogMessage");
-
- assertTrue("Unexpected log principal in security plugin", _plugin.getLogMessage().startsWith("[mng:admin"));
- assertTrue("Unexpected log principal in MBean", actorLogMessage.startsWith("[mng:admin"));
- }
-
- public static class TestMBean extends DefaultManagedObject implements CurrentActorRetriever
- {
-
- public TestMBean(ManagedObjectRegistry registry) throws JMException
- {
- super(CurrentActorRetriever.class, "TestMBean", registry);
- register();
- }
-
- @Override
- public String getObjectInstanceName()
- {
- return "test";
- }
-
- @Override
- public ManagedObject getParentObject()
- {
- return null;
- }
-
- @Override
- public String getActorLogMessage()
- {
- return CurrentActor.get().getLogMessage();
- }
-
- }
-
- public static interface CurrentActorRetriever
- {
- String getActorLogMessage();
- }
-
- public static class TestPlugin implements SecurityPlugin
- {
- private String _logMessage;
-
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
- {
- }
-
- @Override
- public Result getDefault()
- {
- return Result.ALLOWED;
- }
-
- @Override
- public Result access(ObjectType objectType, Object instance)
- {
- return Result.ALLOWED;
- }
-
- @Override
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- // set thread name to work around logic in MangementActor
- Thread.currentThread().setName("RMI TCP Connection(1)-" + System.currentTimeMillis());
- _logMessage = CurrentActor.get().getLogMessage();
- return Result.ALLOWED;
- }
-
- public String getLogMessage()
- {
- return _logMessage;
- }
-
- }
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.java
new file mode 100644
index 0000000000..ba9c2cdaa5
--- /dev/null
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/ManagementLogonLogoffReporterTest.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.jmx;
+
+import static javax.management.remote.JMXConnectionNotification.OPENED;
+import static javax.management.remote.JMXConnectionNotification.CLOSED;
+import static javax.management.remote.JMXConnectionNotification.FAILED;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+
+import javax.management.remote.JMXConnectionNotification;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.RootMessageLogger;
+
+import junit.framework.TestCase;
+
+public class ManagementLogonLogoffReporterTest extends TestCase
+{
+ private static final String TEST_JMX_UNIQUE_CONNECTION_ID = "jmxconnectionid1 jmxuser,group";
+ private static final String TEST_USER = "jmxuser";
+
+ private ManagementLogonLogoffReporter _reporter;
+ private UsernameAccessor _usernameAccessor;
+ private RootMessageLogger _rootMessageLogger;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _usernameAccessor = mock(UsernameAccessor.class);
+ _rootMessageLogger = mock(RootMessageLogger.class);
+ // Enable messaging so we can valid the generated strings
+ when(_rootMessageLogger.isMessageEnabled(any(LogActor.class), anyString())).thenReturn(true);
+
+ _reporter = new ManagementLogonLogoffReporter(_rootMessageLogger, _usernameAccessor);
+ }
+
+ public void testOpenedNotification()
+ {
+ when(_usernameAccessor.getUsernameForConnectionId(TEST_JMX_UNIQUE_CONNECTION_ID)).thenReturn(TEST_USER);
+ JMXConnectionNotification openNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, OPENED);
+
+ _reporter.handleNotification(openNotification, null);
+
+ verify(_rootMessageLogger).rawMessage("[main] MNG-1007 : Open : User jmxuser", "qpid.message.managementconsole.open");
+ }
+
+ public void testClosedNotification()
+ {
+ when(_usernameAccessor.getUsernameForConnectionId(TEST_JMX_UNIQUE_CONNECTION_ID)).thenReturn(TEST_USER);
+ JMXConnectionNotification closeNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, CLOSED);
+
+ _reporter.handleNotification(closeNotification, null);
+
+ verify(_rootMessageLogger).rawMessage("[main] MNG-1008 : Close : User jmxuser", "qpid.message.managementconsole.close");
+ }
+
+ public void tesNotifiedForLogOnTypeEvents()
+ {
+ JMXConnectionNotification openNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, OPENED);
+ JMXConnectionNotification closeNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, CLOSED);
+ JMXConnectionNotification failedNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, FAILED);
+
+ assertTrue(_reporter.isNotificationEnabled(openNotification));
+ assertTrue(_reporter.isNotificationEnabled(closeNotification));
+ assertTrue(_reporter.isNotificationEnabled(failedNotification));
+
+ JMXConnectionNotification otherNotification = createMockNotification(TEST_JMX_UNIQUE_CONNECTION_ID, "other");
+ assertFalse(_reporter.isNotificationEnabled(otherNotification));
+ }
+
+ private JMXConnectionNotification createMockNotification(String connectionId, String notificationType)
+ {
+ JMXConnectionNotification notification = mock(JMXConnectionNotification.class);
+ when(notification.getConnectionId()).thenReturn(connectionId);
+ when(notification.getType()).thenReturn(notificationType);
+ return notification;
+ }
+}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
index ae1be5db00..0f33e78d03 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
+++ b/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/server/jmx/mbeans/LoggingManagementMBeanTest.java
@@ -39,7 +39,7 @@ import junit.framework.TestCase;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
import org.apache.qpid.server.jmx.ManagedObjectRegistry;
-import org.apache.qpid.server.logging.log4j.LoggingFacade;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
public class LoggingManagementMBeanTest extends TestCase
{
@@ -47,13 +47,13 @@ public class LoggingManagementMBeanTest extends TestCase
private static final String TEST_LEVEL2 = "LEVEL2";
private LoggingManagementMBean _loggingMBean;
- private LoggingFacade _mockLoggingFacade;
+ private LoggingManagementFacade _mockLoggingFacade;
private ManagedObjectRegistry _mockManagedObjectRegistry;
@Override
protected void setUp() throws Exception
{
- _mockLoggingFacade = mock(LoggingFacade.class);
+ _mockLoggingFacade = mock(LoggingManagementFacade.class);
final List<String> listOfLevels = new ArrayList<String>()
{{
add(TEST_LEVEL1);
diff --git a/java/broker/bin/qpid-server b/java/broker/bin/qpid-server
index 382004c9f5..206ae6a225 100755
--- a/java/broker/bin/qpid-server
+++ b/java/broker/bin/qpid-server
@@ -33,8 +33,8 @@ if [ -z "$QPID_PNAME" ]; then
export QPID_PNAME=" -DPNAME=QPBRKR"
fi
-# Set classpath to include the qpid-all manifest jar, and any jars supplied in lib/opt
-QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*"
+# Set classpath to include the qpid-all manifest jar, plus jars in lib/plugins and lib/opt
+QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/plugins/*:$QPID_HOME/lib/opt/*"
# Set other variables used by the qpid-run script before calling
export JAVA=java \
diff --git a/java/broker/bin/qpid-server.bat b/java/broker/bin/qpid-server.bat
index 6b7bbcb96e..0d0355c44a 100644
--- a/java/broker/bin/qpid-server.bat
+++ b/java/broker/bin/qpid-server.bat
@@ -76,8 +76,8 @@ echo Using CLASSPATH: %CLASSPATH%
goto afterQpidClasspath
:noQpidClasspath
-echo Warning: Qpid classpath not set. CLASSPATH set to %QPID_HOME%\lib\qpid-all.jar
-set CLASSPATH=%QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\opt\*
+echo Warning: Qpid classpath not set. CLASSPATH set to %QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\plugins\*;%QPID_HOME%\lib\opt\*
+set CLASSPATH=%QPID_HOME%\lib\qpid-all.jar;%QPID_HOME%\lib\plugins\*;%QPID_HOME%\lib\opt\*
:afterQpidClasspath
REM start parsing -run arguments
diff --git a/java/broker/build.xml b/java/broker/build.xml
index 938066728e..8581b7c639 100644
--- a/java/broker/build.xml
+++ b/java/broker/build.xml
@@ -20,7 +20,7 @@
-->
<project name="AMQ Broker" default="build">
<property name="module.depends" value="management/common common amqp-1-0-common"/>
- <property name="module.test.depends" value="common/test" />
+ <property name="module.test.depends" value="common/tests" />
<property name="module.main" value="org.apache.qpid.server.Main"/>
<property name="module.genpom" value="true"/>
@@ -28,23 +28,7 @@
<property name="output.dir" value="${module.precompiled}/org/apache/qpid/server/filter/jms/selector"/>
- <property name="qmf.input.file" value="${project.root}/../specs/management-schema.xml"/>
- <property name="qmf.xsl.file" value="${project.root}/broker/src/xsl/qmf.xsl"/>
- <property name="qmf.output.dir" value="${module.precompiled}/org/apache/qpid/qmf/schema"/>
- <property name="qmf.output.file" value="BrokerSchema.java"/>
-
- <target name="precompile" depends="gen_logging,gen_qmf"/>
-
- <target name="check_qmf_deps">
- <uptodate property="gen_qmf.notRequired" targetfile="${qmf.output.dir}/${qmf.output.file}">
- <srcfiles file="${qmf.input.file}"/>
- <srcfiles file="${qmf.xsl.file}"/>
- </uptodate>
- </target>
-
- <target name="gen_qmf" depends="check_qmf_deps" unless="gen_qmf.notRequired">
- <xslt in="${qmf.input.file}" out="${qmf.output.dir}/${qmf.output.file}" style="${qmf.xsl.file}"/>
- </target>
+ <target name="precompile" depends="gen_logging"/>
<target name="copy-etc-release" if="module.etc.exists" description="copy etc directory if it exists to build tree">
<copy todir="${module.release}/etc" failonerror="false" flatten="true">
@@ -64,9 +48,15 @@
<fixcrlf srcdir="${module.release}/bin" fixlast="true" eol="dos" includes="*.bat"/>
</target>
- <target name="release-bin-other" depends="release-bin-other-bdbstore" description="copy broker-plugins into module release">
+ <target name="release-bin-other" depends="release-bin-other-lib-opt,release-bin-other-bdbstore,release-bin-copy-broker-plugins"/>
+
+ <target name="release-bin-other-lib-opt" depends="release-bin-other-bdbstore" description="make lib/opt dir in the module release">
+ <mkdir dir="${module.release}/lib/opt"/>
+ </target>
+
+ <target name="release-bin-copy-broker-plugins" description="copy broker-plugins into module release">
<copy todir="${module.release}/lib/plugins" failonerror="true">
- <fileset dir="${build.lib}/plugins"/>
+ <fileset dir="${build.scratch.broker.plugins.lib}"/>
</copy>
</target>
diff --git a/java/broker/etc/broker_example.acl b/java/broker/etc/broker_example.acl
index 45a48bda09..fc650801c8 100644
--- a/java/broker/etc/broker_example.acl
+++ b/java/broker/etc/broker_example.acl
@@ -19,24 +19,20 @@
### EXAMPLE ACL V2 FILE
### NOTE: Rules are considered from top to bottom, and the first matching rule governs the decision.
-
-### DEFINE GROUPS ###
-
-#Define a 'messaging-users' group with users 'client' and 'server' in it
-GROUP messaging-users client server
-
-#Define a group for management web console users
-GROUP webadmins webadmin
+### Rules may refer to users or groups. Groups are currently defined in the etc/groups file.
### JMX MANAGEMENT ####
-# Allow everyone to perform read operations on the ServerInformation mbean
-# This is used for items such as querying the management API and broker release versions.
-ACL ALLOW ALL ACCESS METHOD component="ServerInformation"
+# To use JMX management, first give the user/group ACCESS MANAGEMENT permission
+ACL ALLOW administrators ACCESS MANAGEMENT
+ACL ALLOW guest ACCESS MANAGEMENT
-# Allow 'admin' all management operations. To reduce log file noise, only non-read-only operations are logged.
-ACL ALLOW admin ACCESS METHOD
-ACL ALLOW-LOG admin ALL METHOD
+# Allow guest to perform read operations on the ServerInformation mbean
+ACL ALLOW guest ACCESS METHOD component="ServerInformation"
+
+# Allow 'administrators' all management operations. To reduce log file noise, only non-read-only operations are logged.
+ACL ALLOW administrators ACCESS METHOD
+ACL ALLOW-LOG administrators ALL METHOD
# Allow 'guest' to view logger levels, and use getter methods on LoggingManagement
ACL ALLOW guest ACCESS METHOD component="LoggingManagement" name="viewEffectiveRuntimeLoggerLevels"
@@ -49,17 +45,61 @@ ACL DENY-LOG ALL ACCESS METHOD component="UserManagement"
ACL DENY-LOG ALL ACCESS METHOD component="ConfigurationManagement"
ACL DENY-LOG ALL ACCESS METHOD component="LoggingManagement"
-# Allow everyone to perform all read operations (using ALLOW rather than ALLOW-LOG to reduce log file noise)
-# on the mbeans not listed in the DENY rules above
+# Allow everyone to perform all read operations on the mbeans not listed in the DENY rules above
ACL ALLOW ALL ACCESS METHOD
+### WEB MANAGEMENT ####
+
+# To use web management, first give the user/group ACCESS MANAGEMENT permission
+ACL ALLOW webadmins ACCESS MANAGEMENT
+
+# ACL for web management console admins
+# All rules below are required for console admin users
+# to perform create/update/delete operations
+ACL ALLOW-LOG webadmins CREATE QUEUE
+ACL ALLOW-LOG webadmins DELETE QUEUE
+ACL ALLOW-LOG webadmins PURGE QUEUE
+ACL ALLOW-LOG webadmins CREATE EXCHANGE
+ACL ALLOW-LOG webadmins DELETE EXCHANGE
+ACL ALLOW-LOG webadmins BIND EXCHANGE
+ACL ALLOW-LOG webadmins UNBIND EXCHANGE
+ACL ALLOW-LOG webadmins CREATE GROUP
+ACL ALLOW-LOG webadmins DELETE GROUP
+ACL ALLOW-LOG webadmins UPDATE GROUP
+ACL ALLOW-LOG webadmins CREATE USER
+ACL ALLOW-LOG webadmins DELETE USER
+ACL ALLOW-LOG webadmins UPDATE USER
+
+ACL ALLOW-LOG webadmins UPDATE METHOD
+
+# at the moment only the following UPDATE METHOD rules are supported by web management console
+#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="moveMessages"
+#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="copyMessages"
+#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="deleteMessages"
+
### MESSAGING ###
+# The 'ACCESS VIRTUALHOST' rules below apply to messaging operations (as opposed to management operations)
+
+# Firewall examples
+
+# Deny access to all users from *.example.company1.com and *.example.company2.com
+ACL DENY-LOG all ACCESS VIRTUALHOST from_hostname=".*\.example\.company1.com,.*\.example\.company2.com"
-#Example permissions for request-response based messaging.
+# Deny access to all users in the IP ranges 192.168.1.0-192.168.1.255 and 192.168.2.0-192.168.2.255,
+# using the notation specified in RFC 4632, "Classless Inter-domain Routing (CIDR)"
+ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.168.1.0/24,192.168.2.0/24"
-#Allow 'messaging-users' group to connect to the virtualhost
+# Deny access to all users in the IP ranges 192.169.1.0-192.169.1.255 and 192.169.2.0-192.169.2.255,
+# using wildcard notation.
+ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.169.1.*,192.169.2.*"
+
+# Allow 'messaging-users' group to connect to all virtualhosts
ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST
+# Deny messaging-users management
+ACL DENY-LOG messaging-users ACCESS MANAGEMENT
+
+
# Client side
# Allow the 'client' user to publish requests to the request queue and create, consume from, and delete temporary reply queues.
ACL ALLOW-LOG client CREATE QUEUE temporary="true"
@@ -77,24 +117,8 @@ ACL ALLOW-LOG server CONSUME QUEUE name="example.RequestQueue"
ACL ALLOW-LOG server BIND EXCHANGE
ACL ALLOW-LOG server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*"
-# ACL for web management console admins
-# All rules below are required for console admin users
-# to perform create/update/delete operations
-ACL ALLOW-LOG webadmins CREATE QUEUE
-ACL ALLOW-LOG webadmins DELETE QUEUE
-ACL ALLOW-LOG webadmins PURGE QUEUE
-ACL ALLOW-LOG webadmins CREATE EXCHANGE
-ACL ALLOW-LOG webadmins DELETE EXCHANGE
-ACL ALLOW-LOG webadmins BIND EXCHANGE
-ACL ALLOW-LOG webadmins UNBIND EXCHANGE
-ACL ALLOW-LOG webadmins UPDATE METHOD
-
-# at the moment only the following UPDATE METHOD rules are supported by web management console
-#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="moveMessages"
-#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="copyMessages"
-#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="deleteMessages"
### DEFAULT ###
-#Deny all users from performing all operations
+# Deny all users from performing all operations
ACL DENY-LOG all all
diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml
deleted file mode 100644
index 08c7c23d13..0000000000
--- a/java/broker/etc/config.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
-
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
-
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disable Non-SSL port set sslOnly to true -->
- <ssl>
- <enabled>false</enabled>
- <port>5671</port>
- <sslOnly>false</sslOnly>
- <keyStorePath>/path/to/keystore.ks</keyStorePath>
- <keyStorePassword>keystorepass</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>true</enabled>
- <jmxport>
- <registryServer>8999</registryServer>
- <!--
- If unspecified, connectorServer defaults to 100 + registryServer port.
- <connectorServer>9099</connectionServer>
- -->
- </jmxport>
- <ssl>
- <enabled>false</enabled>
- <!-- Update below path to your keystore location. -->
- <keyStorePath>${conf}/qpid.keystore</keyStorePath>
- <keyStorePassword>password</keyStorePassword>
- </ssl>
- <https>
- <enabled>false</enabled>
- </https>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <!-- By default, all authenticated users have permissions to perform all actions -->
-
- <!-- ACL Example
- This example illustrates securing the both Management (JMX) and Messaging.
- <acl>${conf}/broker_example.acl</acl>
- -->
-
- <msg-auth>false</msg-auth>
- </security>
-
- <virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
-
-
diff --git a/java/broker/etc/groups b/java/broker/etc/groups
new file mode 100644
index 0000000000..e3912ece99
--- /dev/null
+++ b/java/broker/etc/groups
@@ -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.
+#
+
+#
+# To define a group, use the format:
+#
+# <groupname>.users=<user1>,<user2>,...,<usern>
+#
+
+messaging-users.users=guest,client,server
+administrators.users=admin
+webadmins.users=webadmin
+
diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml
index b1b31248c1..71a13875a1 100644
--- a/java/broker/etc/log4j.xml
+++ b/java/broker/etc/log4j.xml
@@ -68,7 +68,7 @@
<param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/>
</layout>
</appender>
@@ -77,20 +77,20 @@
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/>
</layout>
</appender>
<appender class="org.apache.log4j.ConsoleAppender" name="STDOUT">
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/>
</layout>
</appender>
<!-- Provide warnings to standard output -->
- <category additivity="true" name="org.apache.qpid">
- <priority value="warn"/>
- </category>
+ <logger additivity="true" name="org.apache.qpid">
+ <level value="warn"/>
+ </logger>
<!-- Enable info messages for the status-logging hierarchy -->
<logger additivity="true" name="qpid.message">
@@ -108,21 +108,14 @@
<level value="info"/>
</logger>
- <!-- Examples of additional logging settings -->
- <!-- Used to generate extra debug. See debug.log4j.xml -->
-
- <!--<category additivity="true" name="org.apache.qpid.server.store">
- <priority value="debug"/>
- </category-->
-
<!-- Set the commons logging that the XML parser uses to WARN, it is very chatty at debug -->
<logger name="org.apache.commons">
- <level value="WARN"/>
+ <level value="warn"/>
</logger>
<!-- Log all info events to file -->
<root>
- <priority value="info"/>
+ <level value="info"/>
<appender-ref ref="FileAppender"/>
<!--appender-ref ref="ArchivingFileAppender"/-->
</root>
diff --git a/java/broker/src/main/java/broker.bnd b/java/broker/src/main/java/broker.bnd
index 4e799a1609..bf338543f7 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.19.0
+ver: 0.21.0
Bundle-SymbolicName: qpid-broker
Bundle-Version: ${ver}
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
deleted file mode 100644
index 27ab580642..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java
+++ /dev/null
@@ -1,586 +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.qmf;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ExchangeConfigType;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.ExchangeReferrer;
-import org.apache.qpid.server.exchange.ExchangeType;
-import org.apache.qpid.server.exchange.topic.TopicExchangeResult;
-import org.apache.qpid.server.exchange.topic.TopicMatcherResult;
-import org.apache.qpid.server.exchange.topic.TopicNormalizer;
-import org.apache.qpid.server.exchange.topic.TopicParser;
-import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.model.UUIDGenerator;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.HouseKeepingTask;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicLong;
-
-public class ManagementExchange implements Exchange, QMFService.Listener
-{
- private static final AMQShortString QPID_MANAGEMENT = new AMQShortString("qpid.management");
- private static final AMQShortString QPID_MANAGEMENT_TYPE = new AMQShortString("management");
-
- private VirtualHost _virtualHost;
-
- private final TopicParser _parser = new TopicParser();
-
- private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults =
- new ConcurrentHashMap<AMQShortString, TopicExchangeResult>();
-
- private final Set<Binding> _bindingSet = new CopyOnWriteArraySet<Binding>();
- private UUID _id;
- private UUID _qmfId;
- private static final String AGENT_BANK = "0";
-
- private int _bindingCountHigh;
- private final AtomicLong _msgReceived = new AtomicLong();
- private final AtomicLong _bytesReceived = new AtomicLong();
-
- private final CopyOnWriteArrayList<BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>();
-
- //TODO : persist creation time
- private long _createTime = System.currentTimeMillis();
-
-
- private class ManagementQueue implements BaseQueue
- {
- 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);
-
- public void enqueue(ServerMessage message) throws AMQException
- {
- long size = message.getSize();
-
- ByteBuffer buf = ByteBuffer.allocate((int) size);
-
- int offset = 0;
-
- while(offset < size)
- {
- offset += message.getContent(buf,offset);
- }
-
- buf.flip();
- QMFCommandDecoder commandDecoder = new QMFCommandDecoder(getQMFService(),buf);
- QMFCommand cmd;
- while((cmd = commandDecoder.decode()) != null)
- {
- cmd.process(_virtualHost, message);
- }
-
- }
-
- public void enqueue(ServerMessage message, boolean sync, PostEnqueueAction action) throws AMQException
- {
- enqueue(message);
- }
-
- public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException
- {
- enqueue(message);
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public AMQShortString getNameShortString()
- {
- return NAME_AS_SHORT_STRING;
- }
-
- @Override
- public UUID getId()
- {
- return QUEUE_ID;
- }
- }
-
-
- private final ManagementQueue _mgmtQueue = new ManagementQueue();
-
- public ManagementExchange()
- {
- }
-
- public static final ExchangeType<ManagementExchange> TYPE = new ExchangeType<ManagementExchange>()
- {
-
- public AMQShortString getName()
- {
- return QPID_MANAGEMENT_TYPE;
- }
-
- public Class<ManagementExchange> getExchangeClass()
- {
- return ManagementExchange.class;
- }
-
- public ManagementExchange newInstance(UUID id, VirtualHost host,
- AMQShortString name,
- boolean durable,
- int ticket,
- boolean autoDelete) throws AMQException
- {
- ManagementExchange exch = new ManagementExchange();
- exch.initialise(id, host, name, durable, ticket, autoDelete);
- return exch;
- }
-
- public AMQShortString getDefaultExchangeName()
- {
- return QPID_MANAGEMENT;
- }
- };
-
-
- public AMQShortString getNameShortString()
- {
- return QPID_MANAGEMENT;
- }
-
- public AMQShortString getTypeShortString()
- {
- return QPID_MANAGEMENT_TYPE;
- }
-
- public void initialise(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete)
- throws AMQException
- {
- if(!QPID_MANAGEMENT.equals(name))
- {
- throw new AMQException("Can't create more than one Management exchange");
- }
- _virtualHost = host;
- _id = id;
- _virtualHost.scheduleHouseKeepingTask(_virtualHost.getBroker().getManagementPublishInterval(), new UpdateTask(_virtualHost));
- _qmfId = getConfigStore().createId();
- getConfigStore().addConfiguredObject(this);
- getQMFService().addListener(this);
- }
-
- public UUID getId()
- {
- return _id;
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public ExchangeConfigType getConfigType()
- {
- return ExchangeConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return _virtualHost;
- }
-
- public boolean isDurable()
- {
- return true;
- }
-
- public VirtualHost getVirtualHost()
- {
- return _virtualHost;
- }
-
- public String getName()
- {
- return QPID_MANAGEMENT.toString();
- }
-
- public ExchangeType getType()
- {
- return TYPE;
- }
-
- public boolean isAutoDelete()
- {
- return false;
- }
-
- public int getTicket()
- {
- return 0;
- }
-
- public void close() throws AMQException
- {
- getConfigStore().removeConfiguredObject(this);
- }
-
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
- public synchronized void addBinding(final Binding b)
- {
-
- if(_bindingSet.add(b))
- {
- AMQShortString routingKey = TopicNormalizer.normalize(new AMQShortString(b.getBindingKey()));
-
- TopicExchangeResult result = _topicExchangeResults.get(routingKey);
- if(result == null)
- {
- result = new TopicExchangeResult();
- result.addUnfilteredQueue(b.getQueue());
- _parser.addBinding(routingKey, result);
- _topicExchangeResults.put(routingKey,result);
- }
- else
- {
- result.addUnfilteredQueue(b.getQueue());
- }
-
- result.addBinding(b);
- }
-
- for(BindingListener listener : _listeners)
- {
- listener.bindingAdded(this, b);
- }
-
- if(_bindingSet.size() > _bindingCountHigh)
- {
- _bindingCountHigh = _bindingSet.size();
- }
-
- String bindingKey = b.getBindingKey();
-
- if(bindingKey.startsWith("schema.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#."))
- {
- publishAllSchema();
- }
- if(bindingKey.startsWith("console.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#."))
- {
- publishAllConsole();
- }
-
- }
-
- void publishAllConsole()
- {
- QMFService qmfService = getQMFService();
-
- long sampleTime = System.currentTimeMillis();
-
- for(QMFPackage pkg : qmfService.getSupportedSchemas())
- {
- for(QMFClass qmfClass : pkg.getClasses())
- {
- Collection<QMFObject> qmfObjects = qmfService.getObjects(qmfClass);
-
- publishObjectsToConsole(sampleTime, qmfObjects);
- }
-
- }
-
- }
-
- private QMFService getQMFService()
- {
- return _virtualHost.getApplicationRegistry().getQMFService();
- }
-
- void publishObjectsToConsole(final long sampleTime,
- final Collection<QMFObject> qmfObjects)
- {
- if(!qmfObjects.isEmpty() && hasBindings())
- {
- QMFClass qmfClass = qmfObjects.iterator().next().getQMFClass();
- ArrayList<QMFCommand> commands = new ArrayList<QMFCommand>();
-
-
- for(QMFObject obj : qmfObjects)
- {
- commands.add(obj.asConfigInfoCmd(sampleTime));
- commands.add(obj.asInstrumentInfoCmd(sampleTime));
- }
-
- publishToConsole(qmfClass, commands);
- }
- }
-
- private void publishToConsole(final QMFClass qmfClass, final ArrayList<QMFCommand> commands)
- {
- if(!commands.isEmpty() && hasBindings())
- {
- String routingKey = "console.obj.1." + AGENT_BANK + "." + qmfClass.getPackage().getName() + "." + qmfClass.getName();
- QMFMessage message = new QMFMessage(routingKey,commands.toArray(new QMFCommand[commands.size()]));
-
- Collection<TopicMatcherResult> results = _parser.parse(new AMQShortString(routingKey));
- HashSet<AMQQueue> queues = new HashSet<AMQQueue>();
- for(TopicMatcherResult result : results)
- {
- TopicExchangeResult res = (TopicExchangeResult)result;
-
- for(Binding b : res.getBindings())
- {
- b.incrementMatches();
- }
-
- queues.addAll(((TopicExchangeResult)result).getUnfilteredQueues());
- }
- for(AMQQueue queue : queues)
- {
- try
- {
- queue.enqueue(message);
- }
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
- }
- }
- }
-
- void publishAllSchema()
- {
-
- }
-
- public synchronized void removeBinding(final Binding binding)
- {
- if(_bindingSet.remove(binding))
- {
- AMQShortString bindingKey = TopicNormalizer.normalize(new AMQShortString(binding.getBindingKey()));
- TopicExchangeResult result = _topicExchangeResults.get(bindingKey);
- result.removeBinding(binding);
- result.removeUnfilteredQueue(binding.getQueue());
- }
-
- for(BindingListener listener : _listeners)
- {
- listener.bindingRemoved(this, binding);
- }
- }
-
- public synchronized Collection<Binding> getBindings()
- {
- return new ArrayList<Binding>(_bindingSet);
- }
-
- public ArrayList<BaseQueue> route(InboundMessage message)
- {
- ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(1);
- _msgReceived.incrementAndGet();
- _bytesReceived.addAndGet(message.getSize());
- queues.add(_mgmtQueue);
- return queues;
- }
-
- public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue)
- {
- return false; //TODO
- }
-
- public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isBound(AMQShortString routingKey, AMQQueue queue)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isBound(AMQShortString routingKey)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isBound(AMQQueue queue)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean hasBindings()
- {
- return !_bindingSet.isEmpty();
- }
-
- public boolean isBound(String bindingKey, AMQQueue queue)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean isBound(String bindingKey)
- {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void addCloseTask(final Task task)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void removeCloseTask(final Task task)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
-
-
- public Exchange getAlternateExchange()
- {
- return null;
- }
-
- public Map<String, Object> getArguments()
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void setAlternateExchange(Exchange exchange)
- {
-
- }
-
- public void removeReference(ExchangeReferrer exchange)
- {
- }
-
- public void addReference(ExchangeReferrer exchange)
- {
- }
-
- public boolean hasReferrers()
- {
- return true;
- }
-
-
-
- private class UpdateTask extends HouseKeepingTask
- {
- public UpdateTask(VirtualHost vhost)
- {
- super(vhost);
- }
-
- public void execute()
- {
- publishAllConsole();
- publishAllSchema();
- }
-
- }
-
- public void objectCreated(final QMFObject obj)
- {
- publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj));
- }
-
- public void objectDeleted(final QMFObject obj)
- {
- publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj));
- }
-
- public long getBindingCount()
- {
- return getBindings().size();
- }
-
- public long getBindingCountHigh()
- {
- return _bindingCountHigh;
- }
-
- public long getMsgReceives()
- {
- return _msgReceived.get();
- }
-
- public long getMsgRoutes()
- {
- return getMsgReceives();
- }
-
- public long getMsgDrops()
- {
- return 0l;
- }
-
- public long getByteReceives()
- {
- return _bytesReceived.get();
- }
-
- public long getByteRoutes()
- {
- return getByteReceives();
- }
-
- public long getByteDrops()
- {
- return 0l;
- }
-
- public long getCreateTime()
- {
- return _createTime;
- }
-
- public void addBindingListener(final BindingListener listener)
- {
- _listeners.add(listener);
- }
-
- public void removeBindingListener(final BindingListener listener)
- {
- _listeners.remove(listener);
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
deleted file mode 100644
index 69284abc48..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java
+++ /dev/null
@@ -1,82 +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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.List;
-
-public class QMFBrokerRequestCommand extends QMFCommand
-{
-
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
-
- public QMFBrokerRequestCommand(QMFCommandHeader header, BBDecoder buf)
- {
- super(header);
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String queueName = message.getMessageHeader().getReplyToRoutingKey();
-
- _qmfLogger.debug("Execute: " + this);
-
- QMFCommand[] commands = new QMFCommand[2];
- commands[0] = new QMFBrokerResponseCommand(this, virtualHost);
- commands[1] = new QMFCommandCompletionCommand(this);
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- for(QMFCommand cmd : commands)
- {
- QMFMessage responseMessage = new QMFMessage(queueName, cmd);
-
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java
deleted file mode 100644
index 7d566567a1..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java
+++ /dev/null
@@ -1,156 +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.qmf;
-
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-abstract public class QMFClass
-{
-
-
- public enum Type
- {
- OBJECT((byte)1),
- EVENT((byte)2);
-
- private final byte _value;
-
- Type(byte value)
- {
- _value = value;
- }
-
- public byte getValue()
- {
- return _value;
- }
- }
-
- private final Type _type;
- private QMFPackage _package;
- private final String _name;
- private byte[] _schemaHash;
-
- private Map<String, QMFProperty> _properties = new LinkedHashMap<String, QMFProperty>();
- private Map<String, QMFStatistic> _statistics = new LinkedHashMap<String, QMFStatistic>();
- private Map<String, QMFMethod> _methods = new LinkedHashMap<String, QMFMethod>();
-
-
-
- public QMFClass(Type type, String name, byte[] schemaHash, List<QMFProperty> properties,
- List<QMFStatistic> statistics, List<QMFMethod> methods)
- {
- this(type, name, schemaHash);
- setProperties(properties);
- setStatistics(statistics);
- setMethods(methods);
- }
-
-
- public QMFClass(Type type, String name, byte[] schemaHash)
-
- {
- _type = type;
- _name = name;
- _schemaHash = schemaHash;
-
- }
-
- protected void setProperties(List<QMFProperty> properties)
- {
- for(QMFProperty prop : properties)
- {
- _properties.put(prop.getName(), prop);
- }
- }
-
- protected void setStatistics(List<QMFStatistic> statistics)
- {
- for(QMFStatistic stat : statistics)
- {
- _statistics.put(stat.getName(), stat);
- }
- }
-
-
- protected void setMethods(List<QMFMethod> methods)
- {
- for(QMFMethod method : methods)
- {
- _methods.put(method.getName(), method);
- }
- }
-
- public void setPackage(QMFPackage aPackage)
- {
- _package = aPackage;
- for(QMFProperty prop : _properties.values())
- {
- prop.setQMFClass(this);
- }
- // TODO Statisics, Methods
- }
-
- public Type getType()
- {
- return _type;
- }
-
- public QMFPackage getPackage()
- {
- return _package;
- }
-
- public String getName()
- {
- return _name;
- }
-
- public byte[] getSchemaHash()
- {
- return _schemaHash;
- }
-
- public Collection<QMFProperty> getProperties()
- {
- return _properties.values();
- }
-
- public Collection<QMFStatistic> getStatistics()
- {
- return _statistics.values();
- }
-
- public Collection<QMFMethod> getMethods()
- {
- return _methods.values();
- }
-
- public QMFMethod getMethod(String methodName)
- {
- return _methods.get(methodName);
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java
deleted file mode 100644
index 5676bb7306..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.Collection;
-import java.util.List;
-
-public class QMFClassQueryCommand extends QMFCommand
-{
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
-
- private final String _package;
-
- public QMFClassQueryCommand(QMFCommandHeader header, BBDecoder decoder)
- {
- super(header);
- _package = decoder.readStr8();
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String routingKey = message.getMessageHeader().getReplyToRoutingKey();
-
- _qmfLogger.debug("Execute: " + this);
-
- IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
- QMFService service = appRegistry.getQMFService();
-
- QMFPackage qmfPackage = service.getPackage(_package);
- Collection<QMFClass> qmfClasses = qmfPackage.getClasses();
-
- QMFCommand[] commands = new QMFCommand[ qmfClasses.size() + 1 ];
-
- int i = 0;
- for(QMFClass qmfClass : qmfClasses)
- {
- commands[i++] = new QMFClassIndicationCommand(this, qmfClass);
- }
- commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this);
-
-
- for(QMFCommand cmd : commands)
- {
-
-
- QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
-
- @Override
- public String toString()
- {
- return "QMFClassQueryCommand{" +
- "package='" + _package + '\'' +
- '}';
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
deleted file mode 100644
index 397ad4090e..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java
+++ /dev/null
@@ -1,63 +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.qmf;
-
-import org.apache.qpid.transport.codec.BBEncoder;
-
-public class QMFCommandCompletionCommand extends QMFCommand
-{
-
- private final CompletionCode _status;
- private final String _text;
-
- public QMFCommandCompletionCommand(QMFCommand command)
- {
- this(command, CompletionCode.OK, "");
- }
- public QMFCommandCompletionCommand(QMFCommand command, CompletionCode status, String text)
- {
- super( new QMFCommandHeader(command.getHeader().getVersion(),
- command.getHeader().getSeq(),
- QMFOperation.COMMAND_COMPLETION));
-
- _status = status;
- _text = text;
- }
-
-
- @Override
- public void encode(BBEncoder encoder)
- {
- super.encode(encoder);
- encoder.writeInt32(_status.ordinal());
- encoder.writeStr8(_text);
- }
-
- @Override
- public String toString()
- {
- return "QMFCommandCompletionCommand{" +
- "status=" + _status +
- ",text='" + _text + '\'' +
- '}';
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java
deleted file mode 100644
index ac036dfa19..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java
+++ /dev/null
@@ -1,98 +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.qmf;
-
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.nio.ByteBuffer;
-
-public class QMFCommandDecoder
-{
- private BBDecoder _decoder;
-
-
- private static final QMFOperation[] OP_CODES = new QMFOperation[256];
- private final QMFService _qmfService;
-
- static
- {
- for(QMFOperation op : QMFOperation.values())
- {
- OP_CODES[op.getOpcode()] = op;
- }
- }
-
- public QMFCommandDecoder(final QMFService qmfService, ByteBuffer buf)
- {
- _qmfService = qmfService;
- _decoder = new BBDecoder();
- _decoder.init(buf);
- }
-
- public QMFCommand decode()
- {
- if(_decoder.hasRemaining())
- {
- QMFCommandHeader header = readQMFHeader();
-
- switch(header.getOperation())
- {
- case BROKER_REQUEST:
- return new QMFBrokerRequestCommand(header, _decoder);
- case PACKAGE_QUERY:
- return new QMFPackageQueryCommand(header, _decoder);
- case CLASS_QUERY:
- return new QMFClassQueryCommand(header, _decoder);
- case SCHEMA_REQUEST:
- return new QMFSchemaRequestCommand(header, _decoder);
- case METHOD_REQUEST:
- return new QMFMethodRequestCommand(header, _decoder, _qmfService);
- case GET_QUERY:
- return new QMFGetQueryCommand(header, _decoder);
- default:
- System.out.println("Unknown command");
-
- }
-
- return null;
- }
- else
- {
- return null;
- }
- }
-
- private QMFCommandHeader readQMFHeader()
- {
- if(_decoder.readInt8() == (byte) 'A'
- && _decoder.readInt8() == (byte) 'M')
- {
- byte version = _decoder.readInt8();
- short opCode = _decoder.readUint8();
- int seq = _decoder.readInt32();
-
- return new QMFCommandHeader(version, seq, OP_CODES[opCode]);
-
- }
- return null;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java
deleted file mode 100644
index c4d771317f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java
+++ /dev/null
@@ -1,63 +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.qmf;
-
-import org.apache.qpid.transport.codec.BBEncoder;
-
-public class QMFCommandHeader
-{
- private final byte _version;
- private final int _seq;
-
- private final QMFOperation _operation;
-
- public QMFCommandHeader(byte version, int seq, QMFOperation operation)
- {
- _version = version;
- _seq = seq;
- _operation = operation;
- }
-
- public byte getVersion()
- {
- return _version;
- }
-
- public int getSeq()
- {
- return _seq;
- }
-
- public QMFOperation getOperation()
- {
- return _operation;
- }
-
- public void encode(BBEncoder encoder)
- {
- encoder.writeUint8((short)'A');
- encoder.writeUint8((short)'M');
- encoder.writeInt8(_version);
- encoder.writeUint8((short)_operation.getOpcode());
- encoder.writeInt32(_seq);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
deleted file mode 100644
index b1f958d4ba..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java
+++ /dev/null
@@ -1,205 +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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-public class QMFGetQueryCommand extends QMFCommand
-{
-
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
- private String _className;
- private String _packageName;
- private UUID _objectId;
-
- public QMFGetQueryCommand(QMFCommandHeader header, BBDecoder decoder)
- {
- super(header);
-
- Map<String, Object> _map = decoder.readMap();
- _className = (String) _map.get("_class");
- _packageName = (String) _map.get("_package");
- byte[] objectIdBytes = (byte[]) _map.get("_objectId");
-
- if(objectIdBytes != null)
- {
- long msb = 0;
- long lsb = 0;
-
- for (int i = 0; i != 8; i++)
- {
- msb = (msb << 8) | (objectIdBytes[i] & 0xff);
- }
- for (int i = 8; i != 16; i++)
- {
- lsb = (lsb << 8) | (objectIdBytes[i] & 0xff);
- }
- _objectId = new UUID(msb, lsb);
- }
- else
- {
- _objectId = null;
- }
-
-
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String routingKey = message.getMessageHeader().getReplyToRoutingKey();
-
- IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
- QMFService service = appRegistry.getQMFService();
-
- _qmfLogger.debug("Execute: " + this);
-
- List<QMFCommand> commands = new ArrayList<QMFCommand>();
- final long sampleTime = System.currentTimeMillis() * 1000000l;
-
- Collection<QMFPackage> packages;
-
- if(_packageName != null && _packageName.length() != 0)
- {
- QMFPackage qmfPackage = service.getPackage(_packageName);
- if(qmfPackage == null)
- {
- packages = Collections.EMPTY_LIST;
- }
- else
- {
- packages = Collections.singleton(qmfPackage);
- }
- }
- else
- {
- packages = service.getSupportedSchemas();
- }
-
- for(QMFPackage qmfPackage : packages)
- {
-
- Collection<QMFClass> qmfClasses;
-
- if(_className != null && _className.length() != 0)
- {
- QMFClass qmfClass = qmfPackage.getQMFClass(_className);
- if(qmfClass == null)
- {
- qmfClasses = Collections.EMPTY_LIST;
- }
- else
- {
- qmfClasses = Collections.singleton(qmfClass);
- }
- }
- else
- {
- qmfClasses = qmfPackage.getClasses();
- }
-
-
- for(QMFClass qmfClass : qmfClasses)
- {
- Collection<QMFObject> objects;
-
- if(_objectId != null)
- {
- QMFObject obj = service.getObjectById(qmfClass, _objectId);
- if(obj == null)
- {
- objects = Collections.EMPTY_LIST;
- }
- else
- {
- objects = Collections.singleton(obj);
- }
- }
- else
- {
- objects = service.getObjects(qmfClass);
- }
-
- for(QMFObject object : objects)
- {
-
- commands.add(object.asGetQueryResponseCmd(this, sampleTime));
- }
- }
-
-
- }
-
-
- commands.add( new QMFCommandCompletionCommand(this));
-
-
- for(QMFCommand cmd : commands)
- {
-
- _qmfLogger.debug("Respond: " + cmd);
- QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
- @Override
- public String toString()
- {
- return "QMFGetQueryCommand{" +
- "packageName='" + _packageName + '\'' +
- ", className='" + _className + '\'' +
- ", objectId=" + _objectId +
- '}';
- }
-} \ No newline at end of file
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
deleted file mode 100644
index 1b173c7e11..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java
+++ /dev/null
@@ -1,256 +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.qmf;
-
-import java.util.Collection;
-import java.util.Collections;
-import org.apache.commons.lang.NotImplementedException;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.message.AMQMessageHeader;
-import org.apache.qpid.server.message.InboundMessage;
-import org.apache.qpid.server.message.MessageReference;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.transport.codec.BBEncoder;
-
-import java.nio.ByteBuffer;
-import java.util.Set;
-
-public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHeader
-{
-
- private ByteBuffer _content;
- private String _routingKey;
-
- public QMFMessage(String routingKey, QMFCommand command)
- {
- this(routingKey, new QMFCommand[] { command });
- }
-
-
- public QMFMessage(String routingKey, QMFCommand[] commands)
- {
- _routingKey = routingKey;
- BBEncoder encoder = new BBEncoder(256);
-
- for(QMFCommand cmd : commands)
- {
- cmd.encode(encoder);
- }
-
-
- _content = encoder.buffer();
- }
-
- public String getRoutingKey()
- {
- return _routingKey;
- }
-
- public AMQShortString getRoutingKeyShortString()
- {
- return AMQShortString.valueOf(_routingKey);
- }
-
- public AMQMessageHeader getMessageHeader()
- {
- return this;
- }
-
- public StoredMessage getStoredMessage()
- {
- throw new NotImplementedException();
- }
-
- public boolean isPersistent()
- {
- return false;
- }
-
- public boolean isRedelivered()
- {
- return false;
- }
-
- public long getSize()
- {
- return _content.limit();
- }
-
- public boolean isImmediate()
- {
- return false;
- }
-
- public String getCorrelationId()
- {
- return null;
- }
-
- public long getExpiration()
- {
- return 0;
- }
-
- public String getUserId()
- {
- return null;
- }
-
- public String getAppId()
- {
- return null;
- }
-
- public String getMessageId()
- {
- return null;
- }
-
- public String getMimeType()
- {
- return null;
- }
-
- public String getEncoding()
- {
- return null;
- }
-
- public byte getPriority()
- {
- return 4;
- }
-
- public long getTimestamp()
- {
- return 0;
- }
-
- public String getType()
- {
- return null;
- }
-
- public String getReplyTo()
- {
- return null;
- }
-
- public String getReplyToExchange()
- {
- return null;
- }
-
- public String getReplyToRoutingKey()
- {
- return null;
- }
-
- public Object getHeader(String name)
- {
- return null;
- }
-
- public boolean containsHeaders(Set<String> names)
- {
- return false;
- }
-
- @Override
- public Collection<String> getHeaderNames()
- {
- return Collections.EMPTY_SET;
- }
-
- public boolean containsHeader(String name)
- {
- return false;
- }
-
- public MessageReference newReference()
- {
- return new QMFMessageReference(this);
- }
-
- public long getMessageNumber()
- {
- return 0l;
- }
-
- public long getArrivalTime()
- {
- return 0;
- }
-
- public int getContent(ByteBuffer buf, int offset)
- {
- ByteBuffer src = _content.duplicate();
- src.position(offset);
- src = src.slice();
- int len = src.remaining();
- if(len > buf.remaining())
- {
- len = buf.remaining();
- }
-
- buf.put(src);
-
- return len;
- }
-
-
- public ByteBuffer getContent(int offset, int size)
- {
- ByteBuffer src = _content.duplicate();
- src.position(offset);
- src = src.slice();
- src.limit(size);
- return src;
- }
-
- private static class QMFMessageReference extends MessageReference<QMFMessage>
- {
- public QMFMessageReference(QMFMessage message)
- {
- super(message);
- }
-
- protected void onReference(QMFMessage message)
- {
-
- }
-
- protected void onRelease(QMFMessage message)
- {
-
- }
- }
-
- public SessionConfig getSessionConfig()
- {
- return null;
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java
deleted file mode 100644
index 1d1cd24724..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java
+++ /dev/null
@@ -1,157 +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.qmf;
-
-import org.apache.qpid.transport.codec.BBDecoder;
-import org.apache.qpid.transport.codec.Encoder;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-
-public abstract class QMFMethod<T extends QMFObject>
-{
- private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
- private final List<Argument> _arguments = new ArrayList<Argument>();
-
- private static final String NAME = "name";
- private static final String TYPE = "type";
- private static final String REF_PACKAGE = "refPackage";
- private static final String REF_CLASS = "refClass";
- private static final String UNIT = "unit";
- private static final String MIN = "min";
- private static final String MAX = "max";
- private static final String MAX_LENGTH = "maxlen";
- private static final String DESCRIPTION = "desc";
- private static final String DEFAULT = "default";
- private static final String DIRECTION = "dir";
- private static final String ARG_COUNT = "argCount";
-
-
-
- public enum Direction
- {
- I,
- O,
- IO;
- }
-
- public class Argument
- {
- private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
-
- public Argument(String name, QMFType type)
- {
- _map.put(NAME, name);
- _map.put(TYPE, type.codeValue());
- }
-
- public void setRefPackage(String refPackage)
- {
- _map.put(REF_PACKAGE, refPackage);
- }
-
- public void setRefClass(String refClass)
- {
- _map.put(REF_CLASS, refClass);
- }
-
- public void setUnit(String unit)
- {
- _map.put(UNIT, unit);
- }
-
- public void setMax(Number max)
- {
- _map.put(MAX, max);
- }
-
- public void setMin(Number min)
- {
- _map.put(MIN, min);
- }
-
- public void setMaxLength(int len)
- {
- _map.put(MAX_LENGTH, len);
- }
-
- public void setDefault(Object dflt)
- {
- _map.put(DEFAULT, dflt);
- }
-
- public void setDescription(String desc)
- {
- _map.put(DESCRIPTION, desc);
- }
-
- public void setDirection(Direction direction)
- {
- _map.put(DIRECTION, direction.toString());
- }
-
- public void encode(Encoder encoder)
- {
- encoder.writeMap(_map);
- }
-
- public String getName()
- {
- return (String) _map.get(NAME);
- }
- }
-
- public QMFMethod(String name, String description)
- {
- _map.put(NAME, name);
- _map.put(ARG_COUNT, 0);
- if(description != null)
- {
- _map.put(DESCRIPTION, description);
- }
-
- }
-
- abstract public QMFMethodInvocation<T> parse(final BBDecoder decoder);
-
- protected void addArgument(Argument arg)
- {
- _arguments.add(arg);
- _map.put(ARG_COUNT, _arguments.size());
- }
-
-
- public void encode(Encoder encoder)
- {
- encoder.writeMap(_map);
- for(Argument arg : _arguments)
- {
- arg.encode(encoder);
- }
- }
-
- public String getName()
- {
- return (String) _map.get(NAME);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
deleted file mode 100644
index 1a4ce228b5..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java
+++ /dev/null
@@ -1,95 +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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.List;
-import java.util.UUID;
-
-public class QMFMethodRequestCommand extends QMFCommand
-{
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
- private QMFMethodInvocation _methodInstance;
- private QMFObject _object;
-
- public QMFMethodRequestCommand(final QMFCommandHeader header, final BBDecoder decoder, final QMFService qmfService)
- {
- super(header);
- UUID objectId = decoder.readUuid();
- String packageName = decoder.readStr8();
- String className = decoder.readStr8();
- byte[] hash = decoder.readBin128();
- String methodName = decoder.readStr8();
-
- QMFPackage qmfPackage = qmfService.getPackage(packageName);
- QMFClass qmfClass = qmfPackage.getQMFClass(className);
- _object = qmfService.getObjectById(qmfClass, objectId);
- QMFMethod method = qmfClass.getMethod(methodName);
- _methodInstance = method.parse(decoder);
-
- }
-
- public void process(final VirtualHost virtualHost, final ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String queueName = message.getMessageHeader().getReplyToRoutingKey();
-
- QMFCommand[] commands = new QMFCommand[2];
-
- _qmfLogger.debug("Execute: " + _methodInstance + " on " + _object);
-
- commands[0] = _methodInstance.execute(_object, this);
- commands[1] = new QMFCommandCompletionCommand(this);
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- for(QMFCommand cmd : commands)
- {
- QMFMessage responseMessage = new QMFMessage(queueName, cmd);
-
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
-
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java
deleted file mode 100644
index 5fea014ad8..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java
+++ /dev/null
@@ -1,76 +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.qmf;
-
-import org.apache.qpid.transport.codec.BBEncoder;
-
-public class QMFMethodResponseCommand extends QMFCommand
-{
- private CompletionCode _status = null;
- private String _msg = null;
-
- public QMFMethodResponseCommand(final QMFMethodRequestCommand cmd,
- CompletionCode status,
- String msg)
- {
- super( new QMFCommandHeader(cmd.getHeader().getVersion(),
- cmd.getHeader().getSeq(),
- QMFOperation.METHOD_RESPONSE));
-
- if(status == null)
- {
- _status = CompletionCode.OK;
- }
- else
- {
- _status = status;
- }
-
- _msg = msg;
- }
-
- public CompletionCode getStatus()
- {
- return _status;
- }
-
- public String getStatusText()
- {
- return _msg;
- }
-
- @Override
- public void encode(final BBEncoder encoder)
- {
- super.encode(encoder);
-
- encoder.writeUint32(_status.ordinal());
-
- if(_msg == null)
- {
- encoder.writeStr16(_status.toString());
- }
- else
- {
- encoder.writeStr16(_msg);
- }
- }
-}
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
deleted file mode 100644
index c3604dca44..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.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.qmf;
-
-import java.util.UUID;
-
-public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate>
-{
- private long _deleteTime;
-
- public interface Delegate
- {
- UUID getQMFId();
- long getCreateTime();
- }
-
-
- private D _delegate;
-
- protected QMFObject(D delegate)
- {
- _delegate = delegate;
- }
-
- public D getDelegate()
- {
- return _delegate;
- }
-
- abstract public C getQMFClass();
-
- public final UUID getId()
- {
- return _delegate.getQMFId();
- }
-
- public final long getCreateTime()
- {
- return _delegate.getCreateTime();
- }
-
- public final void setDeleteTime()
- {
- _deleteTime = System.currentTimeMillis();
- }
-
- public final long getDeleteTime()
- {
- return _deleteTime;
- }
-
-
-
- abstract public QMFCommand asConfigInfoCmd(long sampleTime);
- abstract public QMFCommand asInstrumentInfoCmd(long sampleTime);
- abstract public QMFCommand asGetQueryResponseCmd(final QMFGetQueryCommand queryCommand, long sampleTime);
-
- @Override
- public String toString()
- {
- return _delegate.toString();
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java
deleted file mode 100644
index 6736b5d460..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java
+++ /dev/null
@@ -1,67 +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.qmf;
-
-public enum QMFOperation
-{
-
-
- BROKER_REQUEST('B'),
- BROKER_RESPONSE('b'), // This message contains a broker response, sent from the broker in response to a broker request message.
- COMMAND_COMPLETION('z'), // This message is sent to indicate the completion of a request.
- CLASS_QUERY('Q'), // Class query messages are used by a management console to request a list of schema classes that are known by the management broker.
- CLASS_INDICATION('q'), // Sent by the management broker, a class indication notifies the peer of the existence of a schema class.
- SCHEMA_REQUEST('S'), // Schema request messages are used to request the full schema details for a class.
- SCHEMA_RESPONSE('s'), // Schema response message contain a full description of the schema for a class.
- HEARTBEAT_INDEICATION('h'), // This message is published once per publish-interval. It can be used by a client to positively determine which objects did not change during the interval (since updates are not published for objects with no changes).
- CONFIG_INDICATION('c'),
- INSTRUMENTATION_INDICATION('i'),
- GET_QUERY_RESPONSE('g'), // This message contains a content record. Content records contain the values of all properties or statistics in an object. Such records are broadcast on a periodic interval if 1) a change has been made in the value of one of the elements, or 2) if a new management client has bound a queue to the management exchange.
- GET_QUERY('G'), // Sent by a management console, a get query requests that the management broker provide content indications for all objects that match the query criteria.
- METHOD_REQUEST('M'), // This message contains a method request.
- METHOD_RESPONSE('m'), // This message contains a method result.
- PACKAGE_QUERY('P'), // This message contains a schema package query request, requesting that the broker dump the list of known packages
- PACKAGE_INDICATION('p'), // This message contains a schema package indication, identifying a package known by the broker
- AGENT_ATTACH_REUQEST('A'), // This message is sent by a remote agent when it wishes to attach to a management broker
- AGENT_ATTACH_RESPONSE('a'), // The management broker sends this response if an attaching remote agent is permitted to join
- CONSOLE_ADDED_INDICATION('x'), // This message is sent to all remote agents by the management broker when a new console binds to the management exchange
- EVENT('e')
- ;
-
-
- private final char _opcode;
-
- private static final QMFOperation[] OP_CODES = new QMFOperation[256];
-
-
- QMFOperation(char opcode)
- {
- _opcode = opcode;
- }
-
-
- public char getOpcode()
- {
- return _opcode;
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
deleted file mode 100644
index c74c7da252..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java
+++ /dev/null
@@ -1,98 +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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.Collection;
-import java.util.List;
-
-public class QMFPackageQueryCommand extends QMFCommand
-{
-
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
- public QMFPackageQueryCommand(QMFCommandHeader header, BBDecoder decoder)
- {
- super(header);
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String routingKey = message.getMessageHeader().getReplyToRoutingKey();
-
-
- IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
- QMFService service = appRegistry.getQMFService();
-
- Collection<QMFPackage> supportedSchemas = service.getSupportedSchemas();
-
- QMFCommand[] commands = new QMFCommand[ supportedSchemas.size() + 1 ];
-
- _qmfLogger.debug("Exectuting " + this);
-
- int i = 0;
- for(QMFPackage p : supportedSchemas)
- {
- commands[i++] = new QMFPackageIndicationCommand(this, p.getName());
- }
- commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this);
-
-
- for(QMFCommand cmd : commands)
- {
-
- QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
- public String toString()
- {
- return "QMFPackageQueryCommand";
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java
deleted file mode 100644
index 5314466e2a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java
+++ /dev/null
@@ -1,120 +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.qmf;
-
-import org.apache.qpid.transport.codec.Encoder;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class QMFProperty
-{
- private final Map<String, Object> _map = new LinkedHashMap<String, Object>();
- private static final String NAME = "name";
- private static final String TYPE = "type";
- private static final String ACCESS = "access";
- private static final String INDEX = "index";
- private static final String OPTIONAL = "optional";
- private static final String REF_PACKAGE = "refPackage";
- private static final String REF_CLASS = "refClass";
- private static final String UNIT = "unit";
- private static final String MIN = "min";
- private static final String MAX = "max";
- private static final String MAX_LENGTH = "maxlen";
- private static final String DESCRIPTION = "desc";
-
-
- public static enum AccessCode
- {
- RC,
- RW,
- RO;
-
- public int codeValue()
- {
- return ordinal()+1;
- }
- }
-
- public QMFProperty(String name, QMFType type, AccessCode accessCode, boolean index, boolean optional)
- {
- _map.put(NAME, name);
- _map.put(TYPE, type.codeValue());
- _map.put(ACCESS, accessCode.codeValue());
- _map.put(INDEX, index ? 1 : 0);
- _map.put(OPTIONAL, optional ? 1 :0);
- }
-
-
- public void setQMFClass(QMFClass qmfClass)
- {
- }
-
- public void setReferencedClass(String refClass)
- {
- _map.put(REF_CLASS, refClass);
- }
-
- public void setReferencedPackage(String refPackage)
- {
- _map.put(REF_CLASS, refPackage);
- }
-
-
- public String getName()
- {
- return (String) _map.get(NAME);
- }
-
-
- public void setUnit(String unit)
- {
- _map.put(UNIT, unit);
- }
-
- public void setMin(Number min)
- {
- _map.put(MIN, min);
- }
-
- public void setMax(Number max)
- {
- _map.put(MAX, max);
- }
-
- public void setMaxLength(int maxlen)
- {
- _map.put(MAX_LENGTH, maxlen);
- }
-
-
- public void setDescription(String description)
- {
- _map.put(DESCRIPTION, description);
- }
-
- public void encode(Encoder encoder)
- {
- encoder.writeMap(_map);
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
deleted file mode 100644
index 57c67fa7f6..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java
+++ /dev/null
@@ -1,102 +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.qmf;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBDecoder;
-
-import java.util.List;
-
-public class QMFSchemaRequestCommand extends QMFCommand
-{
- private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf");
-
- private final String _packageName;
- private final String _className;
- private final byte[] _hash;
-
- public QMFSchemaRequestCommand(QMFCommandHeader header, BBDecoder decoder)
- {
- super(header);
- _packageName = decoder.readStr8();
- _className = decoder.readStr8();
- _hash = decoder.readBin128();
- }
-
- public void process(VirtualHost virtualHost, ServerMessage message)
- {
- _qmfLogger.debug("Execute: " + this);
-
- String exchangeName = message.getMessageHeader().getReplyToExchange();
- String routingKey = message.getMessageHeader().getReplyToRoutingKey();
-
- IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry();
- QMFService service = appRegistry.getQMFService();
-
- QMFPackage qmfPackage = service.getPackage(_packageName);
- QMFClass qmfClass = qmfPackage.getQMFClass( _className );
-
- QMFCommand[] commands = new QMFCommand[2];
- commands[0] = new QMFSchemaResponseCommand(this, qmfClass);
- commands[ 1 ] = new QMFCommandCompletionCommand(this);
-
-
-
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName);
-
- for(QMFCommand cmd : commands)
- {
- QMFMessage responseMessage = new QMFMessage(routingKey, cmd);
-
-
- List<? extends BaseQueue> queues = exchange.route(responseMessage);
-
- for(BaseQueue q : queues)
- {
- try
- {
- q.enqueue(responseMessage);
- }
- catch (AMQException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
- @Override
- public String toString()
- {
- return "QMFSchemaRequestCommand{" +
- " packageName='" + _packageName + '\'' +
- ", className='" + _className + '\'' +
- '}';
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java
deleted file mode 100644
index 4bd0e41989..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.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.qmf;
-
-import org.apache.qpid.transport.codec.BBEncoder;
-
-import java.util.Collection;
-
-public class QMFSchemaResponseCommand extends QMFCommand
-{
- private final QMFClass _qmfClass;
-
-
- public QMFSchemaResponseCommand(QMFSchemaRequestCommand qmfSchemaRequestCommand, QMFClass qmfClass)
- {
- super(new QMFCommandHeader(qmfSchemaRequestCommand.getHeader().getVersion(),
- qmfSchemaRequestCommand.getHeader().getSeq(),
- QMFOperation.SCHEMA_RESPONSE));
- _qmfClass = qmfClass;
- }
-
- @Override
- public void encode(BBEncoder encoder)
- {
- super.encode(encoder);
- encoder.writeUint8(_qmfClass.getType().getValue());
- encoder.writeStr8(_qmfClass.getPackage().getName());
- encoder.writeStr8(_qmfClass.getName());
- encoder.writeBin128(_qmfClass.getSchemaHash());
-
- Collection<QMFProperty> props = _qmfClass.getProperties();
- Collection<QMFStatistic> stats = _qmfClass.getStatistics();
- Collection<QMFMethod> methods = _qmfClass.getMethods();
-
- encoder.writeUint16(props.size());
- if(_qmfClass.getType() == QMFClass.Type.OBJECT)
- {
- encoder.writeUint16(stats.size());
- encoder.writeUint16(methods.size());
- }
-
- for(QMFProperty prop : props)
- {
- prop.encode(encoder);
- }
-
- if(_qmfClass.getType() == QMFClass.Type.OBJECT)
- {
-
- for(QMFStatistic stat : stats)
- {
- stat.encode(encoder);
- }
-
- for(QMFMethod method : methods)
- {
- method.encode(encoder);
- }
- }
-
- }
-}
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
deleted file mode 100644
index d713976919..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ /dev/null
@@ -1,2086 +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.qmf;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.common.Closeable;
-import org.apache.qpid.qmf.schema.BrokerSchema;
-import org.apache.qpid.server.configuration.*;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-public class QMFService implements ConfigStore.ConfigEventListener, Closeable
-{
-
-
- private IApplicationRegistry _applicationRegistry;
- private ConfigStore _configStore;
-
-
- private final Map<String, QMFPackage> _supportedSchemas = new HashMap<String, QMFPackage>();
- private static final Map<String, ConfigObjectType> _qmfClassMapping = new HashMap<String, ConfigObjectType>();
-
- static
- {
- _qmfClassMapping.put("system", SystemConfigType.getInstance());
- _qmfClassMapping.put("broker", BrokerConfigType.getInstance());
- _qmfClassMapping.put("vhost", VirtualHostConfigType.getInstance());
- _qmfClassMapping.put("exchange", ExchangeConfigType.getInstance());
- _qmfClassMapping.put("queue", QueueConfigType.getInstance());
- _qmfClassMapping.put("binding", BindingConfigType.getInstance());
- _qmfClassMapping.put("connection", ConnectionConfigType.getInstance());
- _qmfClassMapping.put("session", SessionConfigType.getInstance());
- _qmfClassMapping.put("subscription", SubscriptionConfigType.getInstance());
- _qmfClassMapping.put("link", LinkConfigType.getInstance());
- _qmfClassMapping.put("bridge", BridgeConfigType.getInstance());
- }
-
- private final Map<ConfigObjectType, ConfigObjectAdapter> _adapterMap =
- new HashMap<ConfigObjectType, ConfigObjectAdapter>();
- private final Map<ConfigObjectType,QMFClass> _classMap =
- new HashMap<ConfigObjectType,QMFClass>();
-
-
- private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>> _managedObjects =
- new ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>>();
-
- private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>> _managedObjectsById =
- new ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>>();
-
- private static final BrokerSchema PACKAGE = BrokerSchema.getPackage();
-
- public static interface Listener
- {
- public void objectCreated(QMFObject obj);
- public void objectDeleted(QMFObject obj);
- }
-
- private final CopyOnWriteArrayList<Listener> _listeners = new CopyOnWriteArrayList<Listener>();
-
- abstract class ConfigObjectAdapter<Q extends QMFObject<S,D>, S extends QMFObjectClass<Q,D>, D extends QMFObject.Delegate, T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>>
- {
- private final T _type;
- private final S _qmfClass;
-
-
- protected ConfigObjectAdapter(final T type, final S qmfClass)
- {
- _type = type;
- _qmfClass = qmfClass;
- _adapterMap.put(type,this);
- _classMap.put(type,qmfClass);
- }
-
- public T getType()
- {
- return _type;
- }
-
- public S getQMFClass()
- {
- return _qmfClass;
- }
-
- protected final Q newInstance(D delegate)
- {
- return _qmfClass.newInstance(delegate);
- }
-
- public abstract Q createQMFObject(C configObject);
- }
-
- private ConfigObjectAdapter<BrokerSchema.SystemObject,
- BrokerSchema.SystemClass,
- BrokerSchema.SystemDelegate,
- SystemConfigType,
- SystemConfig> _systemObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.SystemObject,
- BrokerSchema.SystemClass,
- BrokerSchema.SystemDelegate,
- SystemConfigType,
- SystemConfig>(SystemConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.SystemClass.class))
- {
-
-
- public BrokerSchema.SystemObject createQMFObject(
- final SystemConfig configObject)
- {
- return newInstance(new SystemDelegate(configObject));
- }
- };
-
- private ConfigObjectAdapter<BrokerSchema.BrokerObject,
- BrokerSchema.BrokerClass,
- BrokerSchema.BrokerDelegate,
- BrokerConfigType,
- BrokerConfig> _brokerObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.BrokerObject,
- BrokerSchema.BrokerClass,
- BrokerSchema.BrokerDelegate,
- BrokerConfigType,
- BrokerConfig>(BrokerConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.BrokerClass.class))
- {
-
- public BrokerSchema.BrokerObject createQMFObject(
- final BrokerConfig configObject)
- {
- return newInstance(new BrokerDelegate(configObject));
- }
- };
-
- private ConfigObjectAdapter<BrokerSchema.VhostObject,
- BrokerSchema.VhostClass,
- BrokerSchema.VhostDelegate,
- VirtualHostConfigType,
- VirtualHostConfig> _vhostObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.VhostObject,
- BrokerSchema.VhostClass,
- BrokerSchema.VhostDelegate,
- VirtualHostConfigType,
- VirtualHostConfig>(VirtualHostConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.VhostClass.class))
- {
-
- public BrokerSchema.VhostObject createQMFObject(
- final VirtualHostConfig configObject)
- {
- return newInstance(new VhostDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.ExchangeObject,
- BrokerSchema.ExchangeClass,
- BrokerSchema.ExchangeDelegate,
- ExchangeConfigType,
- ExchangeConfig> _exchangeObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.ExchangeObject,
- BrokerSchema.ExchangeClass,
- BrokerSchema.ExchangeDelegate,
- ExchangeConfigType,
- ExchangeConfig>(ExchangeConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.ExchangeClass.class))
- {
-
- public BrokerSchema.ExchangeObject createQMFObject(
- final ExchangeConfig configObject)
- {
- return newInstance(new ExchangeDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.QueueObject,
- BrokerSchema.QueueClass,
- BrokerSchema.QueueDelegate,
- QueueConfigType,
- QueueConfig> _queueObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.QueueObject,
- BrokerSchema.QueueClass,
- BrokerSchema.QueueDelegate,
- QueueConfigType,
- QueueConfig>(QueueConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.QueueClass.class))
- {
-
- public BrokerSchema.QueueObject createQMFObject(
- final QueueConfig configObject)
- {
- return newInstance(new QueueDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.BindingObject,
- BrokerSchema.BindingClass,
- BrokerSchema.BindingDelegate,
- BindingConfigType,
- BindingConfig> _bindingObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.BindingObject,
- BrokerSchema.BindingClass,
- BrokerSchema.BindingDelegate,
- BindingConfigType,
- BindingConfig>(BindingConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.BindingClass.class))
- {
-
- public BrokerSchema.BindingObject createQMFObject(
- final BindingConfig configObject)
- {
- return newInstance(new BindingDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.ConnectionObject,
- BrokerSchema.ConnectionClass,
- BrokerSchema.ConnectionDelegate,
- ConnectionConfigType,
- ConnectionConfig> _connectionObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.ConnectionObject,
- BrokerSchema.ConnectionClass,
- BrokerSchema.ConnectionDelegate,
- ConnectionConfigType,
- ConnectionConfig>(ConnectionConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.ConnectionClass.class))
- {
-
- public BrokerSchema.ConnectionObject createQMFObject(
- final ConnectionConfig configObject)
- {
- return newInstance(new ConnectionDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.SessionObject,
- BrokerSchema.SessionClass,
- BrokerSchema.SessionDelegate,
- SessionConfigType,
- SessionConfig> _sessionObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.SessionObject,
- BrokerSchema.SessionClass,
- BrokerSchema.SessionDelegate,
- SessionConfigType,
- SessionConfig>(SessionConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.SessionClass.class))
- {
-
- public BrokerSchema.SessionObject createQMFObject(
- final SessionConfig configObject)
- {
- return newInstance(new SessionDelegate(configObject));
- }
- };
-
- private ConfigObjectAdapter<BrokerSchema.SubscriptionObject,
- BrokerSchema.SubscriptionClass,
- BrokerSchema.SubscriptionDelegate,
- SubscriptionConfigType,
- SubscriptionConfig> _subscriptionObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.SubscriptionObject,
- BrokerSchema.SubscriptionClass,
- BrokerSchema.SubscriptionDelegate,
- SubscriptionConfigType,
- SubscriptionConfig>(SubscriptionConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.SubscriptionClass.class))
- {
-
- public BrokerSchema.SubscriptionObject createQMFObject(
- final SubscriptionConfig configObject)
- {
- return newInstance(new SubscriptionDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.LinkObject,
- BrokerSchema.LinkClass,
- BrokerSchema.LinkDelegate,
- LinkConfigType,
- LinkConfig> _linkObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.LinkObject,
- BrokerSchema.LinkClass,
- BrokerSchema.LinkDelegate,
- LinkConfigType,
- LinkConfig>(LinkConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.LinkClass.class))
- {
-
- public BrokerSchema.LinkObject createQMFObject(
- final LinkConfig configObject)
- {
- return newInstance(new LinkDelegate(configObject));
- }
- };
-
-
- private ConfigObjectAdapter<BrokerSchema.BridgeObject,
- BrokerSchema.BridgeClass,
- BrokerSchema.BridgeDelegate,
- BridgeConfigType,
- BridgeConfig> _bridgeObjectAdapter =
- new ConfigObjectAdapter<BrokerSchema.BridgeObject,
- BrokerSchema.BridgeClass,
- BrokerSchema.BridgeDelegate,
- BridgeConfigType,
- BridgeConfig>(BridgeConfigType.getInstance(),
- PACKAGE.getQMFClassInstance(BrokerSchema.BridgeClass.class))
- {
-
- public BrokerSchema.BridgeObject createQMFObject(
- final BridgeConfig configObject)
- {
- return newInstance(new BridgeDelegate(configObject));
- }
- };
-
-
-
- public QMFService(ConfigStore configStore, IApplicationRegistry applicationRegistry)
- {
- _configStore = configStore;
- _applicationRegistry = applicationRegistry;
- registerSchema(PACKAGE);
-
- for(ConfigObjectType v : _qmfClassMapping.values())
- {
- configStore.addConfigEventListener(v, this);
- }
- init();
- }
-
- public void close()
- {
- for(ConfigObjectType v : _qmfClassMapping.values())
- {
- _configStore.removeConfigEventListener(v, this);
- }
- _listeners.clear();
-
- _managedObjects.clear();
- _managedObjectsById.clear();
- _classMap.clear();
- _adapterMap.clear();
- _supportedSchemas.clear();
- }
-
-
- public void registerSchema(QMFPackage qmfPackage)
- {
- _supportedSchemas.put(qmfPackage.getName(), qmfPackage);
- }
-
-
- public Collection<QMFPackage> getSupportedSchemas()
- {
- return _supportedSchemas.values();
- }
-
- public QMFPackage getPackage(String aPackage)
- {
- return _supportedSchemas.get(aPackage);
- }
-
- public void onEvent(final ConfiguredObject object, final ConfigStore.Event evt)
- {
-
- switch (evt)
- {
- case CREATED:
- manageObject(object);
- break;
-
- case DELETED:
- unmanageObject(object);
- break;
- }
- }
-
- public QMFObject getObjectById(QMFClass qmfclass, UUID id)
- {
- ConcurrentHashMap<UUID, QMFObject> map = _managedObjectsById.get(qmfclass);
- if(map != null)
- {
-
- UUID key = new UUID(id.getMostSignificantBits() & (0xFFFl << 48), id.getLeastSignificantBits());
- return map.get(key);
-
- }
- else
- {
- return null;
- }
- }
-
- private void unmanageObject(final ConfiguredObject object)
- {
- final QMFClass qmfClass = _classMap.get(object.getConfigType());
-
- if(qmfClass == null)
- {
- return;
- }
-
- ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
- if(classObjects != null)
- {
- QMFObject qmfObject = classObjects.remove(object);
- if(qmfObject != null)
- {
- _managedObjectsById.get(qmfClass).remove(object.getQMFId());
- objectRemoved(qmfObject);
- }
- }
- }
-
- private void manageObject(final ConfiguredObject object)
- {
- ConfigObjectAdapter adapter = _adapterMap.get(object.getConfigType());
- QMFObject qmfObject = adapter.createQMFObject(object);
- final QMFClass qmfClass = qmfObject.getQMFClass();
- ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
-
- if(classObjects == null)
- {
- classObjects = new ConcurrentHashMap<ConfiguredObject, QMFObject>();
- if(_managedObjects.putIfAbsent(qmfClass, classObjects) != null)
- {
- classObjects = _managedObjects.get(qmfClass);
- }
- }
-
- ConcurrentHashMap<UUID, QMFObject> classObjectsById = _managedObjectsById.get(qmfClass);
- if(classObjectsById == null)
- {
- classObjectsById = new ConcurrentHashMap<UUID, QMFObject>();
- if(_managedObjectsById.putIfAbsent(qmfClass, classObjectsById) != null)
- {
- classObjectsById = _managedObjectsById.get(qmfClass);
- }
- }
-
- classObjectsById.put(object.getQMFId(),qmfObject);
-
- if(classObjects.putIfAbsent(object, qmfObject) == null)
- {
- objectAdded(qmfObject);
- }
- }
-
- private void objectRemoved(final QMFObject qmfObject)
- {
- qmfObject.setDeleteTime();
- for(Listener l : _listeners)
- {
- l.objectDeleted(qmfObject);
- }
- }
-
- private void objectAdded(final QMFObject qmfObject)
- {
- for(Listener l : _listeners)
- {
- l.objectCreated(qmfObject);
- }
- }
-
- public void addListener(Listener l)
- {
- _listeners.add(l);
- }
-
- public void removeListener(Listener l)
- {
- _listeners.remove(l);
- }
-
-
- private void init()
- {
- for(QMFClass qmfClass : PACKAGE.getClasses())
- {
- ConfigObjectType configType = getConfigType(qmfClass);
- if(configType != null)
- {
- Collection<ConfiguredObject> objects = _configStore.getConfiguredObjects(configType);
- for(ConfiguredObject object : objects)
- {
- manageObject(object);
- }
- }
- }
- }
-
- public Collection<QMFObject> getObjects(QMFClass qmfClass)
- {
- ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
- if(classObjects != null)
- {
- return classObjects.values();
- }
- else
- {
- return Collections.EMPTY_SET;
- }
- }
-
- private QMFObject adapt(final ConfiguredObject object)
- {
- if(object == null)
- {
- return null;
- }
-
- QMFClass qmfClass = _classMap.get(object.getConfigType());
- ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass);
- if(classObjects != null)
- {
- QMFObject qmfObject = classObjects.get(object);
- if(qmfObject != null)
- {
- return qmfObject;
- }
- }
-
- return _adapterMap.get(object.getConfigType()).createQMFObject(object);
- }
-
- private ConfigObjectType getConfigType(final QMFClass qmfClass)
- {
- return _qmfClassMapping.get(qmfClass.getName());
- }
-
- private static class SystemDelegate implements BrokerSchema.SystemDelegate
- {
- private final SystemConfig _obj;
-
- public SystemDelegate(final SystemConfig obj)
- {
- _obj = obj;
- }
-
- public UUID getSystemId()
- {
- return _obj.getQMFId();
- }
-
- public String getOsName()
- {
- return _obj.getOperatingSystemName();
- }
-
- public String getNodeName()
- {
- return _obj.getNodeName();
- }
-
- public String getRelease()
- {
- return _obj.getOSRelease();
- }
-
- public String getVersion()
- {
- return _obj.getOSVersion();
- }
-
- public String getMachine()
- {
- return _obj.getOSArchitecture();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class BrokerDelegate implements BrokerSchema.BrokerDelegate
- {
- private final BrokerConfig _obj;
-
- public BrokerDelegate(final BrokerConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.SystemObject getSystemRef()
- {
- return (BrokerSchema.SystemObject) adapt(_obj.getSystem());
- }
-
- public String getName()
- {
- return "amqp-broker";
- }
-
- public Integer getPort()
- {
- return _obj.getPort();
- }
-
- public Integer getWorkerThreads()
- {
- return _obj.getWorkerThreads();
- }
-
- public Integer getMaxConns()
- {
- return _obj.getMaxConnections();
- }
-
- public Integer getConnBacklog()
- {
- return _obj.getConnectionBacklogLimit();
- }
-
- public Long getStagingThreshold()
- {
- return _obj.getStagingThreshold();
- }
-
- public Boolean getMgmtPublish()
- {
- return true;
- }
-
- public Integer getMgmtPubInterval()
- {
- return _obj.getManagementPublishInterval();
- }
-
- public String getVersion()
- {
- return _obj.getVersion();
- }
-
- public String getDataDir()
- {
- return _obj.getDataDirectory();
- }
-
- public Long getUptime()
- {
- return (System.currentTimeMillis() - _obj.getCreateTime()) * 1000000L;
- }
-
- public Long getQueueCount()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgTotalEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgTotalDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteTotalEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteTotalDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgPersistEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgPersistDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getBytePersistEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getBytePersistDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgTxnEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgTxnDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteTxnEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteTxnDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgFtdEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgFtdDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgFtdDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getReleases()
- {
- // TODO
- return 0L;
- }
-
- public Long getAcquires()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsNoRoute()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsTtl()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsRing()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsLvq()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsOverflow()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsSubscriber()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsPurge()
- {
- // TODO
- return 0L;
- }
-
- public Long getReroutes()
- {
- // TODO
- return 0L;
- }
-
- public Long getAbandoned()
- {
- // TODO
- return 0L;
- }
-
- public Long getAbandonedViaAlt()
- {
- // TODO
- return 0L;
- }
-
- public BrokerSchema.BrokerClass.EchoMethodResponseCommand echo(final BrokerSchema.BrokerClass.EchoMethodResponseCommandFactory factory,
- final Long sequence,
- final String body)
- {
- return factory.createResponseCommand(sequence, body);
- }
-
- public BrokerSchema.BrokerClass.ConnectMethodResponseCommand connect(final BrokerSchema.BrokerClass.ConnectMethodResponseCommandFactory factory,
- final String host,
- final Long port,
- final Boolean durable,
- final String authMechanism,
- final String username,
- final String password,
- final String transport)
- {
- _obj.createBrokerConnection(transport, host, port.intValue(), durable, authMechanism, username, password);
-
- return factory.createResponseCommand();
- }
-
- public BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommand queueMoveMessages(final BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommandFactory factory,
- final String srcQueue,
- final String destQueue,
- final Long qty,
- final Map filter) // TODO: move based on group identifier
- {
- // TODO
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommand getLogLevel(final BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommandFactory factory)
- {
- // TODO: The Java broker has numerous loggers, so we can't really implement this method properly.
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommand setLogLevel(final BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommandFactory factory, String level)
- {
- // TODO: The Java broker has numerous loggers, so we can't really implement this method properly.
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommand getTimestampConfig(final BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommandFactory factory)
- {
- // TODO: timestamp support
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommand setTimestampConfig(final BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommandFactory factory,
- final java.lang.Boolean receive)
- {
- // TODO: timestamp support
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.CreateMethodResponseCommand create(final BrokerSchema.BrokerClass.CreateMethodResponseCommandFactory factory,
- final String type,
- final String name,
- final Map properties,
- final java.lang.Boolean lenient)
- {
- //TODO:
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.DeleteMethodResponseCommand delete(final BrokerSchema.BrokerClass.DeleteMethodResponseCommandFactory factory,
- final String type,
- final String name,
- final Map options)
- {
- //TODO:
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.BrokerClass.QueryMethodResponseCommand query(final BrokerSchema.BrokerClass.QueryMethodResponseCommandFactory factory,
- final String type,
- final String name)
- {
- //TODO:
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class VhostDelegate implements BrokerSchema.VhostDelegate
- {
- private final VirtualHostConfig _obj;
-
- public VhostDelegate(final VirtualHostConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.BrokerObject getBrokerRef()
- {
- return (BrokerSchema.BrokerObject) adapt(_obj.getBroker());
- }
-
- public String getName()
- {
- return _obj.getName();
- }
-
- public String getFederationTag()
- {
- return _obj.getFederationTag();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class ExchangeDelegate implements BrokerSchema.ExchangeDelegate
- {
- private final ExchangeConfig _obj;
-
- public ExchangeDelegate(final ExchangeConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.VhostObject getVhostRef()
- {
- return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
- }
-
- public String getName()
- {
- return _obj.getName();
- }
-
- public String getType()
- {
- return _obj.getType().getName().toString();
- }
-
- public Boolean getDurable()
- {
- return _obj.isDurable();
- }
-
- public Boolean getAutoDelete()
- {
- return _obj.isAutoDelete();
- }
-
- public BrokerSchema.ExchangeObject getAltExchange()
- {
- if(_obj.getAlternateExchange() != null)
- {
- return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange());
- }
- else
- {
- return null;
- }
- }
-
- public Map getArguments()
- {
- return _obj.getArguments();
- }
-
- public Long getProducerCount()
- {
- // TODO
- return 0l;
- }
-
- public Long getProducerCountHigh()
- {
- // TODO
- return 0l;
- }
-
- public Long getProducerCountLow()
- {
- // TODO
- return 0l;
- }
-
- public Long getBindingCount()
- {
- return _obj.getBindingCount();
- }
-
- public Long getBindingCountHigh()
- {
- return _obj.getBindingCountHigh();
- }
-
- public Long getBindingCountLow()
- {
- // TODO
- return 0l;
- }
-
- public Long getMsgReceives()
- {
- return _obj.getMsgReceives();
- }
-
- public Long getMsgDrops()
- {
- return getMsgReceives() - getMsgRoutes();
- }
-
- public Long getMsgRoutes()
- {
- return _obj.getMsgRoutes();
- }
-
- public Long getByteReceives()
- {
- return _obj.getByteReceives();
- }
-
- public Long getByteDrops()
- {
- return getByteReceives() - getByteRoutes();
- }
-
- public Long getByteRoutes()
- {
- return _obj.getByteRoutes();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class QueueDelegate implements BrokerSchema.QueueDelegate
- {
- private final QueueConfig _obj;
-
- public QueueDelegate(final QueueConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.VhostObject getVhostRef()
- {
- return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
- }
-
- public String getName()
- {
- return _obj.getName();
- }
-
- public Boolean getDurable()
- {
- return _obj.isDurable();
- }
-
- public Boolean getAutoDelete()
- {
- return _obj.isAutoDelete();
- }
-
- public Boolean getExclusive()
- {
- return _obj.isExclusive();
- }
-
- public BrokerSchema.ExchangeObject getAltExchange()
- {
- if(_obj.getAlternateExchange() != null)
- {
- return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange());
- }
- else
- {
- return null;
- }
- }
-
- public Long getMsgTotalEnqueues()
- {
- return _obj.getReceivedMessageCount();
- }
-
- public Long getMsgTotalDequeues()
- {
- return _obj.getMessageDequeueCount();
- }
-
- public Long getMsgTxnEnqueues()
- {
- return _obj.getMsgTxnEnqueues();
- }
-
- public Long getMsgTxnDequeues()
- {
- return _obj.getMsgTxnDequeues();
- }
-
- public Long getMsgPersistEnqueues()
- {
- return _obj.getPersistentMsgEnqueues();
- }
-
- public Long getMsgPersistDequeues()
- {
- return _obj.getPersistentMsgDequeues();
- }
-
- public Long getMsgDepth()
- {
- return (long) _obj.getMessageCount();
- }
-
- public Long getByteDepth()
- {
- return _obj.getQueueDepth();
- }
-
- public Long getByteTotalEnqueues()
- {
- return _obj.getTotalEnqueueSize();
- }
-
- public Long getByteTotalDequeues()
- {
- return _obj.getTotalDequeueSize();
- }
-
- public Long getByteTxnEnqueues()
- {
- return _obj.getByteTxnEnqueues();
- }
-
- public Long getByteTxnDequeues()
- {
- return _obj.getByteTxnDequeues();
- }
-
- public Long getBytePersistEnqueues()
- {
- return _obj.getPersistentByteEnqueues();
- }
-
- public Long getBytePersistDequeues()
- {
- return _obj.getPersistentByteDequeues();
- }
-
- public Long getMsgFtdEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgFtdDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdEnqueues()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdDequeues()
- {
- // TODO
- return 0L;
- }
-
- public Long getMsgFtdDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getByteFtdDepth()
- {
- // TODO
- return 0L;
- }
-
- public Long getReleases()
- {
- // TODO
- return 0L;
- }
-
- public Long getAcquires()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsTtl()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsRing()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsLvq()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsOverflow()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsSubscriber()
- {
- // TODO
- return 0L;
- }
-
- public Long getDiscardsPurge()
- {
- // TODO
- return 0L;
- }
-
- public Long getReroutes()
- {
- // TODO
- return 0L;
- }
-
- public Long getConsumerCount()
- {
- return (long) _obj.getConsumerCount();
- }
-
- public Long getConsumerCountHigh()
- {
- return (long) _obj.getConsumerCountHigh();
- }
-
- public Long getConsumerCountLow()
- {
- // TODO
- return 0l;
- }
-
- public Long getBindingCount()
- {
- return (long) _obj.getBindingCount();
- }
-
- public Long getBindingCountHigh()
- {
- return (long) _obj.getBindingCountHigh();
- }
-
- public Long getBindingCountLow()
- {
- // TODO
- return 0l;
- }
-
- public Long getUnackedMessages()
- {
- return _obj.getUnackedMessageCount();
- }
-
- public Long getUnackedMessagesHigh()
- {
- return _obj.getUnackedMessageCountHigh();
- }
-
- public Long getUnackedMessagesLow()
- {
- // TODO
- return 0l;
- }
-
- public Long getMessageLatencySamples()
- {
- // TODO
- return 0l;
- }
-
- public Long getMessageLatencyMin()
- {
- // TODO
- return 0l;
- }
-
- public Long getMessageLatencyMax()
- {
- // TODO
- return 0l;
- }
-
- public Long getMessageLatencyAverage()
- {
- // TODO
- return 0l;
- }
-
- public Boolean getFlowStopped()
- {
- return Boolean.FALSE;
- }
-
- public Long getFlowStoppedCount()
- {
- return 0L;
- }
-
- public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory,
- final Long request,
- final Map filter) // TODO: support for purge-by-group-identifier
- {
- try
- {
- _obj.purge(request);
- } catch (AMQException e)
- {
- // TODO
- throw new RuntimeException();
- }
- return factory.createResponseCommand();
- }
-
- public BrokerSchema.QueueClass.RerouteMethodResponseCommand reroute(final BrokerSchema.QueueClass.RerouteMethodResponseCommandFactory factory,
- final Long request,
- final Boolean useAltExchange,
- final String exchange,
- final Map filter) // TODO: support for re-route-by-group-identifier
- {
- //TODO
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
-
- public Map getArguments()
- {
- return _obj.getArguments();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class BindingDelegate implements BrokerSchema.BindingDelegate
- {
- private final BindingConfig _obj;
-
- public BindingDelegate(final BindingConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.ExchangeObject getExchangeRef()
- {
- return (BrokerSchema.ExchangeObject) adapt(_obj.getExchange());
- }
-
- public BrokerSchema.QueueObject getQueueRef()
- {
- return (BrokerSchema.QueueObject) adapt(_obj.getQueue());
- }
-
- public String getBindingKey()
- {
- return _obj.getBindingKey();
- }
-
- public Map getArguments()
- {
- return _obj.getArguments();
- }
-
- public String getOrigin()
- {
- return _obj.getOrigin();
- }
-
- public Long getMsgMatched()
- {
- // TODO
- return _obj.getMatches();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class ConnectionDelegate implements BrokerSchema.ConnectionDelegate
- {
- private final ConnectionConfig _obj;
-
- public ConnectionDelegate(final ConnectionConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.VhostObject getVhostRef()
- {
- return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
- }
-
- public String getAddress()
- {
- return _obj.getAddress();
- }
-
- public Boolean getIncoming()
- {
- return _obj.isIncoming();
- }
-
- public Boolean getSystemConnection()
- {
- return _obj.isSystemConnection();
- }
-
- public Boolean getFederationLink()
- {
- return _obj.isFederationLink();
- }
-
- public String getAuthIdentity()
- {
- return _obj.getAuthId();
- }
-
- public String getRemoteProcessName()
- {
- return _obj.getRemoteProcessName();
- }
-
- public Long getRemotePid()
- {
- Integer remotePID = _obj.getRemotePID();
- return remotePID == null ? null : (long) remotePID;
- }
-
- public Long getRemoteParentPid()
- {
- Integer remotePPID = _obj.getRemoteParentPID();
- return remotePPID == null ? null : (long) remotePPID;
-
- }
-
- public Boolean getClosing()
- {
- return false;
- }
-
- public Long getFramesFromClient()
- {
- // TODO
- return 0l;
- }
-
- public Long getFramesToClient()
- {
- // TODO
- return 0l;
- }
-
- public Long getBytesFromClient()
- {
- // TODO
- return 0l;
- }
-
- public Long getBytesToClient()
- {
- // TODO
- return 0l;
- }
-
- public Long getMsgsFromClient()
- {
- // TODO
- return 0l;
- }
-
- public Long getMsgsToClient()
- {
- // TODO
- return 0l;
- }
-
- public BrokerSchema.ConnectionClass.CloseMethodResponseCommand close(final BrokerSchema.ConnectionClass.CloseMethodResponseCommandFactory factory)
- {
- _obj.mgmtClose();
-
- return factory.createResponseCommand();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public Boolean getShadow()
- {
- return _obj.isShadow();
- }
-
- public Boolean getUserProxyAuth()
- {
- // TODO
- return false;
- }
-
- public String getSaslMechanism()
- {
- // TODO
- return null;
- }
- public Integer getSaslSsf()
- {
- // TODO
- return 0;
- }
-
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class SessionDelegate implements BrokerSchema.SessionDelegate
- {
- private final SessionConfig _obj;
-
- public SessionDelegate(final SessionConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.VhostObject getVhostRef()
- {
- return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
- }
-
- public String getName()
- {
- return _obj.getSessionName();
- }
-
- public Integer getChannelId()
- {
- return _obj.getChannel();
- }
-
- public BrokerSchema.ConnectionObject getConnectionRef()
- {
- return (BrokerSchema.ConnectionObject) adapt(_obj.getConnectionConfig());
- }
-
- public Long getDetachedLifespan()
- {
- return _obj.getDetachedLifespan();
- }
-
- public Boolean getAttached()
- {
- return _obj.isAttached();
- }
-
- public Long getExpireTime()
- {
- return _obj.getExpiryTime();
- }
-
- public Long getMaxClientRate()
- {
- return _obj.getMaxClientRate();
- }
-
- public Long getFramesOutstanding()
- {
- // TODO
- return 0l;
- }
-
- public Long getUnackedMessages()
- {
- // TODO
- return 0l;
- }
-
- public Long getTxnStarts()
- {
- return _obj.getTxnStarts();
- }
-
- public Long getTxnCommits()
- {
- return _obj.getTxnCommits();
- }
-
- public Long getTxnRejects()
- {
- return _obj.getTxnRejects();
- }
-
- public Long getTxnCount()
- {
- return _obj.getTxnCount();
- }
-
- public Long getClientCredit()
- {
- // TODO
- return 0l;
- }
-
- public BrokerSchema.SessionClass.SolicitAckMethodResponseCommand solicitAck(final BrokerSchema.SessionClass.SolicitAckMethodResponseCommandFactory factory)
- {
- //TODO
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.SessionClass.DetachMethodResponseCommand detach(final BrokerSchema.SessionClass.DetachMethodResponseCommandFactory factory)
- {
- //TODO
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.SessionClass.ResetLifespanMethodResponseCommand resetLifespan(final BrokerSchema.SessionClass.ResetLifespanMethodResponseCommandFactory factory)
- {
- //TODO
- return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED);
- }
-
- public BrokerSchema.SessionClass.CloseMethodResponseCommand close(final BrokerSchema.SessionClass.CloseMethodResponseCommandFactory factory)
- {
- try
- {
- _obj.mgmtClose();
- }
- catch (AMQException e)
- {
- return factory.createResponseCommand(CompletionCode.EXCEPTION, e.getMessage());
- }
-
- return factory.createResponseCommand();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class SubscriptionDelegate implements BrokerSchema.SubscriptionDelegate
- {
- private final SubscriptionConfig _obj;
-
- private SubscriptionDelegate(final SubscriptionConfig obj)
- {
- _obj = obj;
- }
-
-
- public BrokerSchema.SessionObject getSessionRef()
- {
- return (BrokerSchema.SessionObject) adapt(_obj.getSessionConfig());
- }
-
- public BrokerSchema.QueueObject getQueueRef()
- {
- return (BrokerSchema.QueueObject) adapt(_obj.getQueue());
- }
-
- public String getName()
- {
- return _obj.getName();
- }
-
- public Boolean getBrowsing()
- {
- return _obj.isBrowsing();
- }
-
- public Boolean getAcknowledged()
- {
- return _obj.isExplicitAcknowledge();
- }
-
- public Boolean getExclusive()
- {
- return _obj.isExclusive();
- }
-
- public String getCreditMode()
- {
- return _obj.getCreditMode();
- }
-
- public Map getArguments()
- {
- return _obj.getArguments();
- }
-
- public Long getDelivered()
- {
- return _obj.getDelivered();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class BridgeDelegate implements BrokerSchema.BridgeDelegate
- {
- private final BridgeConfig _obj;
-
- private BridgeDelegate(final BridgeConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.LinkObject getLinkRef()
- {
- return (BrokerSchema.LinkObject) adapt(_obj.getLink());
- }
-
- public Integer getChannelId()
- {
- return _obj.getChannelId();
- }
-
- public Boolean getDurable()
- {
- return _obj.isDurable();
- }
-
- public String getSrc()
- {
- return _obj.getSource();
- }
-
- public String getDest()
- {
- return _obj.getDestination();
- }
-
- public String getKey()
- {
- return _obj.getKey();
- }
-
- public Boolean getSrcIsQueue()
- {
- return _obj.isQueueBridge();
- }
-
- public Boolean getSrcIsLocal()
- {
- return _obj.isLocalSource();
- }
-
- public String getTag()
- {
- return _obj.getTag();
- }
-
- public String getExcludes()
- {
- return _obj.getExcludes();
- }
-
- public Boolean getDynamic()
- {
- return _obj.isDynamic();
- }
-
- public Integer getSync()
- {
- return _obj.getAckBatching();
- }
-
- /* support TBD */
- public String getName()
- {
- return null;
- }
-
- public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory)
- {
- return null;
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- public String toString()
- {
- return _obj.toString();
- }
- }
-
- private class LinkDelegate implements BrokerSchema.LinkDelegate
- {
- private final LinkConfig _obj;
-
- private LinkDelegate(final LinkConfig obj)
- {
- _obj = obj;
- }
-
- public BrokerSchema.VhostObject getVhostRef()
- {
- return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost());
- }
-
- public String getHost()
- {
- return _obj.getHost();
- }
-
- public Integer getPort()
- {
- return _obj.getPort();
- }
-
- public String getTransport()
- {
- return _obj.getTransport();
- }
-
- public Boolean getDurable()
- {
- return _obj.isDurable();
- }
-
- public String getState()
- {
- return _obj.getState();
- }
-
- public String getLastError()
- {
- 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();
- return factory.createResponseCommand();
- }
-
- public BrokerSchema.LinkClass.BridgeMethodResponseCommand bridge(final BrokerSchema.LinkClass.BridgeMethodResponseCommandFactory factory,
- final Boolean durable,
- final String src,
- final String dest,
- final String key,
- final String tag,
- final String excludes,
- final Boolean srcIsQueue,
- final Boolean srcIsLocal,
- final Boolean dynamic,
- final Integer sync)
- {
- _obj.createBridge(durable, dynamic, srcIsQueue, srcIsLocal, src, dest, key, tag, excludes);
- return factory.createResponseCommand();
- }
-
- public UUID getQMFId()
- {
- return _obj.getQMFId();
- }
-
- public long getCreateTime()
- {
- return _obj.getCreateTime();
- }
-
- @Override
- public String toString()
- {
- return _obj.toString();
- }
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java
deleted file mode 100644
index 89d650e03b..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java
+++ /dev/null
@@ -1,61 +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.qmf;
-
-import org.apache.qpid.transport.codec.Encoder;
-
-import java.util.LinkedHashMap;
-
-public class QMFStatistic
-{
- private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>();
- private static final String NAME = "name";
- private static final String TYPE = "type";
- private static final String UNIT = "unit";
- private static final String DESCRIPTION = "desc";
-
-
- public QMFStatistic(String name, QMFType type, String unit, String description)
- {
- _map.put(NAME, name);
- _map.put(TYPE, type.codeValue());
- if(unit != null)
- {
- _map.put(UNIT, unit);
- }
- if(description != null)
- {
- _map.put(DESCRIPTION, description);
- }
-
- }
-
- public void encode(Encoder encoder)
- {
- encoder.writeMap(_map);
- }
-
- public String getName()
- {
- return (String) _map.get(NAME);
- }
-}
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 e197dddfde..ab4ca81d05 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
@@ -51,13 +51,10 @@ import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction;
import org.apache.qpid.server.ack.UnacknowledgedMessageMap;
import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ConnectionConfig;
-import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.configuration.SessionConfigType;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.flow.FlowCreditManager;
import org.apache.qpid.server.flow.Pre0_10CreditManager;
@@ -75,7 +72,6 @@ import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.protocol.AMQProtocolEngine;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
@@ -83,7 +79,6 @@ import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.InboundMessageAdapter;
import org.apache.qpid.server.queue.IncomingMessage;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StoreFuture;
import org.apache.qpid.server.store.StoredMessage;
@@ -93,19 +88,19 @@ import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.txn.AsyncAutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
+import org.apache.qpid.server.txn.LocalTransaction.ActivityTimeAccessor;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.TransportException;
-public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder
+public class AMQChannel implements AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder
{
public static final int DEFAULT_PREFETCH = 4096;
private static final Logger _logger = Logger.getLogger(AMQChannel.class);
- private static final boolean MSG_AUTH =
- ApplicationRegistry.getInstance().getConfiguration().getMsgAuth();
-
+ //TODO use Broker property to configure message authorization requirements
+ private boolean _messageAuthorizationRequired = Boolean.getBoolean(BrokerProperties.PROPERTY_MSG_AUTH);
private final int _channelId;
@@ -118,7 +113,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
*/
private long _deliveryTag = 0;
- /** A channel has a default queue (the last declared) that is used when no queue name is explictily set */
+ /** A channel has a default queue (the last declared) that is used when no queue name is explicitly set */
private AMQQueue _defaultQueue;
/** This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. */
@@ -151,7 +146,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
private final AtomicLong _txnCommits = new AtomicLong(0);
private final AtomicLong _txnRejects = new AtomicLong(0);
private final AtomicLong _txnCount = new AtomicLong(0);
- private final AtomicLong _txnUpdateTime = new AtomicLong(0);
private final AMQProtocolSession _session;
private AtomicBoolean _closing = new AtomicBoolean(false);
@@ -169,12 +163,12 @@ 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 _qmfId;
private long _createTime = System.currentTimeMillis();
private final ClientDeliveryMethod _clientDeliveryMethod;
private final TransactionTimeoutHelper _transactionTimeoutHelper;
+ private final UUID _id = UUID.randomUUID();
public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore)
throws AMQException
@@ -184,30 +178,36 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_actor = new AMQPChannelActor(this, session.getLogActor().getRootMessageLogger());
_logSubject = new ChannelLogSubject(this);
- _qmfId = getConfigStore().createId();
_actor.message(ChannelMessages.CREATE());
- getConfigStore().addConfiguredObject(this);
-
_messageStore = messageStore;
// by default the session is non-transactional
_transaction = new AsyncAutoCommitTransaction(_messageStore, this);
- _clientDeliveryMethod = session.createDeliveryMethod(_channelId);
-
- _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
- }
+ _clientDeliveryMethod = session.createDeliveryMethod(_channelId);
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction()
+ {
+ @Override
+ public void doTimeoutAction(String reason) throws AMQException
+ {
+ closeConnection(reason);
+ }
+ });
}
/** Sets this channel to be part of a local transaction */
public void setLocalTransactional()
{
- _transaction = new LocalTransaction(_messageStore);
+ _transaction = new LocalTransaction(_messageStore, new ActivityTimeAccessor()
+ {
+ @Override
+ public long getActivityTime()
+ {
+ return _session.getLastReceivedTime();
+ }
+ });
_txnStarts.incrementAndGet();
}
@@ -221,12 +221,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
sync();
}
-
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
-
private void incrementOutstandingTxnsIfNecessary()
{
if(isTransactional())
@@ -247,11 +241,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
}
}
- public Long getTxnStarts()
- {
- return _txnStarts.get();
- }
-
public Long getTxnCommits()
{
return _txnCommits.get();
@@ -369,9 +358,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
}
});
- _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues), getProtocolSession().getLastReceivedTime());
+ _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues));
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
_currentMessage.getStoredMessage().flushToStore();
}
}
@@ -396,7 +384,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
if (_logger.isDebugEnabled())
{
- _logger.debug(debugIdentity() + "Content body received on channel " + _channelId);
+ _logger.debug(debugIdentity() + " content body received on channel " + _channelId);
}
try
@@ -556,9 +544,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
{
_logger.error("Caught TransportException whilst attempting to requeue:" + e);
}
-
- getConfigStore().removeConfiguredObject(this);
-
}
private void unsubscribeAllConsumers() throws AMQException
@@ -860,7 +845,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
{
Collection<QueueEntry> ackedMessages = getAckedMessages(deliveryTag, multiple);
_transaction.dequeue(ackedMessages, new MessageAcknowledgeAction(ackedMessages));
- updateTransactionalActivity();
}
private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple)
@@ -1054,19 +1038,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
}
}
-
-
- }
-
- /**
- * Update last transaction activity timestamp
- */
- private void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(getProtocolSession().getLastReceivedTime());
- }
}
public String toString()
@@ -1149,10 +1120,16 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
? ((BasicContentHeaderProperties) header.getProperties()).getUserId()
: null;
- return (!MSG_AUTH || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString()));
+ return (!_messageAuthorizationRequired || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString()));
}
+ @Override
+ public UUID getId()
+ {
+ return _id;
+ }
+
public AMQConnectionModel getConnectionModel()
{
return _session;
@@ -1168,6 +1145,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return _logSubject;
}
+ @Override
+ public int compareTo(AMQSessionModel o)
+ {
+ return getId().compareTo(o.getId());
+ }
+
private class MessageDeliveryAction implements ServerTransaction.Action
{
private IncomingMessage _incommingMessage;
@@ -1221,11 +1204,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
// TODO
throw new RuntimeException(e);
}
-
-
-
-
-
}
public void onRollback()
@@ -1375,7 +1353,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
public void onRollback()
{
- //To change body of implemented methods use File | Settings | File Templates.
}
}
@@ -1469,97 +1446,24 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
return getProtocolSession().getVirtualHost();
}
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
- public SessionConfigType getConfigType()
- {
- return SessionConfigType.getInstance();
- }
-
public int getChannel()
{
return getChannelId();
}
- public boolean isAttached()
- {
- return true;
- }
-
- public long getDetachedLifespan()
- {
- return 0;
- }
-
- public ConnectionConfig getConnectionConfig()
- {
- return (AMQProtocolEngine)getProtocolSession();
- }
-
- public Long getExpiryTime()
- {
- return null;
- }
-
- public Long getMaxClientRate()
- {
- return null;
- }
-
public boolean isDurable()
{
return false;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public String getSessionName()
- {
- return getConnectionConfig().getAddress() + "/" + getChannelId();
- }
-
public long getCreateTime()
{
return _createTime;
}
- public void mgmtClose() throws AMQException
- {
- _session.mgmtCloseChannel(_channelId);
- }
-
public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
{
- if (inTransaction())
- {
- long currentTime = System.currentTimeMillis();
- long openTime = currentTime - _transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
-
- _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime),
- TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT);
- if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose))
- {
- closeConnection("Idle transaction timed out");
- return;
- }
-
- _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime),
- TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT);
- if (_transactionTimeoutHelper.isTimedOut(openTime, openClose))
- {
- closeConnection("Open transaction timed out");
- return;
- }
- }
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose);
}
/**
@@ -1637,6 +1541,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
public void sync()
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("sync() called on channel " + debugIdentity());
+ }
+
AsyncCommand cmd;
while((cmd = _unfinishedCommandsQueue.poll()) != null)
{
@@ -1674,16 +1583,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm
_action.postCommit();
_action = null;
}
-
- boolean isReadyForCompletion()
- {
- return _future.isComplete();
- }
- }
-
- public int compareTo(AMQSessionModel session)
- {
- return getQMFId().compareTo(session.getQMFId());
}
@Override
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 d58a0d5bb4..54dcf0543d 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
@@ -23,37 +23,31 @@ 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 java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator;
+import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
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.log4j.LoggingFacade;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacade;
import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.protocol.AmqpProtocolVersion;
-import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.transport.QpidAcceptor;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
+import org.apache.qpid.server.registry.IApplicationRegistry;
public class Broker
{
private static final Logger LOGGER = Logger.getLogger(Broker.class);
private volatile Thread _shutdownHookThread;
+ private volatile IApplicationRegistry _applicationRegistry;
protected static class InitException extends RuntimeException
{
@@ -73,7 +67,17 @@ public class Broker
}
finally
{
- ApplicationRegistry.remove();
+ try
+ {
+ if (_applicationRegistry != null)
+ {
+ _applicationRegistry.close();
+ }
+ }
+ finally
+ {
+ clearAMQShortStringCache();
+ }
}
}
@@ -84,274 +88,76 @@ public class Broker
public void startup(final BrokerOptions options) throws Exception
{
+ CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
try
{
- CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
startupImpl(options);
addShutdownHook();
}
finally
{
- CurrentActor.remove();
+ try
+ {
+ CurrentActor.remove();
+ }
+ finally
+ {
+ clearAMQShortStringCache();
+ }
}
}
private void startupImpl(final BrokerOptions options) throws Exception
{
- final String qpidHome = options.getQpidHome();
- final File configFile = getConfigFile(options.getConfigFile(),
- BrokerOptions.DEFAULT_CONFIG_FILE, qpidHome, true);
-
- CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath()));
-
- File logConfigFile = getConfigFile(options.getLogConfigFile(),
- BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false);
-
- configureLogging(logConfigFile, options.getLogWatchFrequency());
+ final String qpidHome = System.getProperty(BrokerProperties.PROPERTY_QPID_HOME);
+ String storeLocation = options.getConfigurationStoreLocation();
+ String storeType = options.getConfigurationStoreType();
- ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile, options.getBundleContext());
- ServerConfiguration serverConfig = config.getConfiguration();
- if (options.getQpidWork() != null)
+ if (storeLocation == null)
{
- serverConfig.setQpidWork(options.getQpidWork());
- }
- if (options.getQpidHome() != null)
- {
- serverConfig.setQpidHome(options.getQpidHome());
- }
- updateManagementPorts(serverConfig, options.getJmxPortRegistryServer(), options.getJmxPortConnectorServer());
-
- ApplicationRegistry.initialise(config);
-
- // We have already loaded the BrokerMessages class by this point so we
- // need to refresh the locale setting incase we had a different value in
- // the configuration.
- BrokerMessages.reload();
-
- // AR.initialise() sets and removes its own actor so we now need to set the actor
- // for the remainder of the startup, and the default actor if the stack is empty
- CurrentActor.set(new BrokerActor(config.getCompositeStartupMessageLogger()));
- CurrentActor.setDefault(new BrokerActor(config.getRootMessageLogger()));
- GenericActor.setDefaultMessageLogger(config.getRootMessageLogger());
-
- try
- {
- Set<Integer> ports = new HashSet<Integer>(options.getPorts());
- if(ports.isEmpty())
- {
- parsePortList(ports, serverConfig.getPorts());
- }
-
- Set<Integer> sslPorts = new HashSet<Integer>(options.getSSLPorts());
- if(sslPorts.isEmpty())
- {
- 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)
- {
- bindAddr = serverConfig.getBind();
- }
-
- InetAddress bindAddress;
- if (bindAddr.equals(WILDCARD_ADDRESS))
- {
- bindAddress = null;
- }
- else
- {
- bindAddress = InetAddress.getByName(bindAddr);
- }
-
- final AmqpProtocolVersion defaultSupportedProtocolReply = serverConfig.getDefaultSupportedProtocolReply();
-
- if (!serverConfig.getSSLOnly())
- {
- for(int port : ports)
- {
- 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,
- 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);
-
- final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance();
- final MultiVersionProtocolEngineFactory protocolEngineFactory =
- new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply);
-
- transport.accept(settings, protocolEngineFactory, null);
-
- ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress,
- new QpidAcceptor(transport,QpidAcceptor.Transport.TCP, supported));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
- }
- }
-
- if (serverConfig.getEnableSSL())
+ String qpidWork = System.getProperty(BrokerProperties.PROPERTY_QPID_WORK);
+ if (qpidWork == null)
{
- final String keystorePath = serverConfig.getConnectorKeyStorePath();
- final String keystorePassword = serverConfig.getConnectorKeyStorePassword();
- final String keystoreType = serverConfig.getConnectorKeyStoreType();
- final String keyManagerFactoryAlgorithm = serverConfig.getConnectorKeyManagerFactoryAlgorithm();
- 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,
- 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);
-
- final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance();
- final MultiVersionProtocolEngineFactory protocolEngineFactory =
- new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply);
-
- transport.accept(settings, protocolEngineFactory, sslContext);
-
- ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress,
- new QpidAcceptor(transport,QpidAcceptor.Transport.SSL, supported));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort));
- }
+ qpidWork = new File(System.getProperty("user.dir"), "work").getAbsolutePath();
}
-
- CurrentActor.get().message(BrokerMessages.READY());
- }
- finally
- {
- // Startup is complete so remove the AR initialised Startup actor
- CurrentActor.remove();
+ storeLocation = new File(qpidWork, BrokerOptions.DEFAULT_CONFIG_FILE + "." + storeType).getAbsolutePath();
}
- }
- private static Set<AmqpProtocolVersion> getSupportedVersions(final int port,
- final Set<Integer> exclude_1_0,
- final Set<Integer> exclude_0_10,
- 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);
+ CurrentActor.get().message(BrokerMessages.CONFIG(storeLocation));
- if((exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled()) && !include_1_0.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v1_0_0);
- }
+ File logConfigFile = getConfigFile(options.getLogConfigFile(), BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false);
+ configureLogging(logConfigFile, options.getLogWatchFrequency());
- if((exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) && !include_0_10.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_10);
- }
+ BrokerConfigurationStoreCreator storeCreator = new BrokerConfigurationStoreCreator();
+ ConfigurationEntryStore store = storeCreator.createStore(storeLocation, storeType,
+ options.getInitialConfigurationStoreLocation(), options.getInitialConfigurationStoreLocation());
- if((exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled()) && !include_0_9_1.contains(port))
+ if (options.isManagementMode())
{
- supported.remove(AmqpProtocolVersion.v0_9_1);
+ store = new ManagementModeStoreHandler(store, options);
}
- if((exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled()) && !include_0_9.contains(port))
+ _applicationRegistry = new ApplicationRegistry(store);
+ try
{
- supported.remove(AmqpProtocolVersion.v0_9);
+ _applicationRegistry.initialise();
}
-
- if((exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled()) && !include_0_8.contains(port))
+ catch(Exception e)
{
- supported.remove(AmqpProtocolVersion.v0_8);
+ try
+ {
+ _applicationRegistry.close();
+ }
+ catch(Exception ce)
+ {
+ LOGGER.debug("An error occured when closing the registry following initialization failure", ce);
+ }
+ throw e;
}
- return supported;
}
+
private File getConfigFile(final String fileName,
final String defaultFileName,
final String qpidHome, boolean throwOnFileNotFound) throws InitException
@@ -368,11 +174,11 @@ public class Broker
if (!configFile.exists() && throwOnFileNotFound)
{
- String error = "File " + fileName + " could not be found. Check the file exists and is readable.";
+ String error = "File " + configFile + " could not be found. Check the file exists and is readable.";
if (qpidHome == null)
{
- error = error + "\nNote: " + BrokerOptions.QPID_HOME + " is not set.";
+ error = error + "\nNote: " + BrokerProperties.PROPERTY_QPID_HOME + " is not set.";
}
throw new InitException(error, null);
@@ -399,37 +205,6 @@ public class Broker
}
}
- /**
- * Update the configuration data with the management port.
- * @param configuration
- * @param registryServerPort The string from the command line
- */
- private void updateManagementPorts(ServerConfiguration configuration, Integer registryServerPort, Integer connectorServerPort)
- {
- if (registryServerPort != null)
- {
- try
- {
- configuration.setJMXPortRegistryServer(registryServerPort);
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid management (registry server) port: " + registryServerPort, null);
- }
- }
- if (connectorServerPort != null)
- {
- try
- {
- configuration.setJMXPortConnectorServer(connectorServerPort);
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid management (connector server) port: " + connectorServerPort, null);
- }
- }
- }
-
private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException
{
if (logConfigFile.exists() && logConfigFile.canRead())
@@ -443,7 +218,7 @@ public class Broker
// log4j expects the watch interval in milliseconds
try
{
- LoggingFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
+ LoggingManagementFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
}
catch (Exception e)
{
@@ -454,7 +229,7 @@ public class Broker
{
try
{
- LoggingFacade.configure(logConfigFile.getPath());
+ LoggingManagementFacade.configure(logConfigFile.getPath());
}
catch (Exception e)
{
@@ -531,6 +306,24 @@ public class Broker
LOGGER.debug("Skipping shutdown hook removal as there either isnt one, or we are it.");
}
}
+ /**
+ * Workaround that prevents AMQShortStrings cache from being left in the thread local. This is important
+ * when embedding the Broker in containers where the starting thread may not belong to Qpid.
+ * The long term solution here is to stop our use of AMQShortString outside the AMQP transport layer.
+ */
+ private void clearAMQShortStringCache()
+ {
+ AMQShortString.clearLocalCache();
+ }
+
+ public org.apache.qpid.server.model.Broker getBroker()
+ {
+ if (_applicationRegistry == null)
+ {
+ return null;
+ }
+ return _applicationRegistry.getBroker();
+ }
private class ShutdownService implements Runnable
{
@@ -540,4 +333,5 @@ public class Broker
Broker.this.shutdown();
}
}
+
}
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 434d40d557..57e401e608 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
@@ -20,66 +20,25 @@
*/
package org.apache.qpid.server;
-import org.osgi.framework.BundleContext;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
public class BrokerOptions
{
- public static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
+ public static final String DEFAULT_STORE_TYPE = "json";
+ public static final String DEFAULT_CONFIG_FILE = "config";
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;
- private String _bind;
- private Integer _jmxPortRegistryServer;
- private Integer _jmxPortConnectorServer;
- private BundleContext _bundleContext;
-
private Integer _logWatchFrequency = 0;
- private String _qpidWorkFolder;
- private String _qpidHomeFolder;
- public void addPort(final int port)
- {
- _ports.add(port);
- }
+ private String _configurationStoreLocation;
+ private String _configurationStoreType = DEFAULT_STORE_TYPE;
- public void addSSLPort(final int sslPort)
- {
- _sslPorts.add(sslPort);
- }
+ private String _initialConfigurationStoreLocation;
+ private String _initialConfigurationStoreType = DEFAULT_STORE_TYPE;
- public Set<Integer> getPorts()
- {
- return Collections.unmodifiableSet(_ports);
- }
-
- public Set<Integer> getSSLPorts()
- {
- return Collections.unmodifiableSet(_sslPorts);
- }
-
- public String getConfigFile()
- {
- return _configFile;
- }
-
- public void setConfigFile(final String configFile)
- {
- _configFile = configFile;
- }
+ private boolean _managementMode;
+ private int _managementModeRmiPort;
+ private int _managementModeConnectorPort;
+ private int _managementModeHttpPort;
public String getLogConfigFile()
{
@@ -91,110 +50,97 @@ public class BrokerOptions
_logConfigFile = logConfigFile;
}
- public Integer getJmxPortRegistryServer()
+ public int getLogWatchFrequency()
{
- return _jmxPortRegistryServer;
+ return _logWatchFrequency;
}
- public void setJmxPortRegistryServer(final int jmxPortRegistryServer)
+ /**
+ * Set the frequency with which the log config file will be checked for updates.
+ * @param logWatchFrequency frequency in seconds
+ */
+ public void setLogWatchFrequency(final int logWatchFrequency)
{
- _jmxPortRegistryServer = jmxPortRegistryServer;
+ _logWatchFrequency = logWatchFrequency;
}
- public Integer getJmxPortConnectorServer()
+ public String getConfigurationStoreLocation()
{
- return _jmxPortConnectorServer;
+ return _configurationStoreLocation;
}
- public void setJmxPortConnectorServer(final int jmxPortConnectorServer)
+ public void setConfigurationStoreLocation(String cofigurationStore)
{
- _jmxPortConnectorServer = jmxPortConnectorServer;
+ _configurationStoreLocation = cofigurationStore;
}
- public String getQpidHome()
+
+ public String getConfigurationStoreType()
{
- return _qpidHomeFolder == null? System.getProperty(QPID_HOME): _qpidHomeFolder;
+ return _configurationStoreType;
}
- public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol)
+ public void setConfigurationStoreType(String cofigurationStoreType)
{
- final Set<Integer> excludedPorts = _exclusionMap.get(excludeProtocol);
- return excludedPorts == null ? Collections.<Integer>emptySet() : excludedPorts;
+ _configurationStoreType = cofigurationStoreType;
}
- public void addExcludedPort(final ProtocolExclusion excludeProtocol, final int port)
+ public void setInitialConfigurationStoreLocation(String initialConfigurationStore)
{
- if (!_exclusionMap.containsKey(excludeProtocol))
- {
- _exclusionMap.put(excludeProtocol, new HashSet<Integer>());
- }
-
- Set<Integer> ports = _exclusionMap.get(excludeProtocol);
- ports.add(port);
+ _initialConfigurationStoreLocation = initialConfigurationStore;
}
- public String getBind()
+ public void setInitialConfigurationStoreType(String initialConfigurationStoreType)
{
- return _bind;
+ _initialConfigurationStoreType = initialConfigurationStoreType;
}
- public void setBind(final String bind)
+ public String getInitialConfigurationStoreLocation()
{
- _bind = bind;
+ return _initialConfigurationStoreLocation;
}
- public int getLogWatchFrequency()
+ public String getInitialConfigurationStoreType()
{
- return _logWatchFrequency;
+ return _initialConfigurationStoreType;
}
- /**
- * Set the frequency with which the log config file will be checked for updates.
- * @param logWatchFrequency frequency in seconds
- */
- public void setLogWatchFrequency(final int logWatchFrequency)
+ public boolean isManagementMode()
{
- _logWatchFrequency = logWatchFrequency;
+ return _managementMode;
}
- public BundleContext getBundleContext()
+ public void setManagementMode(boolean managementMode)
{
- return _bundleContext ;
+ _managementMode = managementMode;
}
- public void setBundleContext(final BundleContext bundleContext)
+ public int getManagementModeRmiPort()
{
- _bundleContext = bundleContext;
+ return _managementModeRmiPort;
}
- public Set<Integer> getIncludedPorts(final ProtocolInclusion includeProtocol)
+ public void setManagementModeRmiPort(int managementModeRmiPort)
{
- final Set<Integer> includedPorts = _inclusionMap.get(includeProtocol);
- return includedPorts == null ? Collections.<Integer>emptySet() : includedPorts;
+ _managementModeRmiPort = managementModeRmiPort;
}
- public void addIncludedPort(final ProtocolInclusion includeProtocol, final int port)
+ public int getManagementModeConnectorPort()
{
- if (!_inclusionMap.containsKey(includeProtocol))
- {
- _inclusionMap.put(includeProtocol, new HashSet<Integer>());
- }
-
- Set<Integer> ports = _inclusionMap.get(includeProtocol);
- ports.add(port);
+ return _managementModeConnectorPort;
}
- public String getQpidWork()
+ public void setManagementModeConnectorPort(int managementModeConnectorPort)
{
- return _qpidWorkFolder;
+ _managementModeConnectorPort = managementModeConnectorPort;
}
- public void setQpidWork(String qpidWorkFolder)
+ public int getManagementModeHttpPort()
{
- _qpidWorkFolder = qpidWorkFolder;
+ return _managementModeHttpPort;
}
- public void setQpidHome(String qpidHomeFolder)
+ public void setManagementModeHttpPort(int managementModeHttpPort)
{
- _qpidHomeFolder = qpidHomeFolder;
+ _managementModeHttpPort = managementModeHttpPort;
}
} \ 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 9fe7a6619f..4927956c6c 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
@@ -30,9 +30,6 @@ import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.server.Broker.InitException;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
/**
* Main entry point for AMQPD.
@@ -45,86 +42,17 @@ public class Main
private static final Option OPTION_VERSION = new Option("v", "version", false, "print the version information and exit");
- private static final Option OPTION_CONFIG_FILE =
- OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config")
- .create("c");
-
- private static final Option OPTION_PORT =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("listen on the specified port. Overrides any value in the config file")
- .withLongOpt("port").create("p");
-
- private static final Option OPTION_SSLPORT =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("SSL port. Overrides any value in the config file")
- .withLongOpt("sslport").create("s");
-
-
- private static final Option OPTION_EXCLUDE_1_0 =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("when listening on the specified port do not accept AMQP1-0 connections. The specified port must be one specified on the command line")
- .withLongOpt("exclude-1-0").create();
-
- private static final Option OPTION_EXCLUDE_0_10 =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("when listening on the specified port do not accept AMQP0-10 connections. The specified port must be one specified on the command line")
- .withLongOpt("exclude-0-10").create();
-
- private static final Option OPTION_EXCLUDE_0_9_1 =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("when listening on the specified port do not accept AMQP0-9-1 connections. The specified port must be one specified on the command line")
- .withLongOpt("exclude-0-9-1").create();
-
- private static final Option OPTION_EXCLUDE_0_9 =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("when listening on the specified port do not accept AMQP0-9 connections. The specified port must be one specified on the command line")
- .withLongOpt("exclude-0-9").create();
-
- private static final Option OPTION_EXCLUDE_0_8 =
- OptionBuilder.withArgName("port").hasArg()
- .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")
- .withLongOpt("jmxregistryport").create("m");
-
- private static final Option OPTION_JMX_PORT_CONNECTOR_SERVER =
- OptionBuilder.withArgName("port").hasArg()
- .withDescription("listen on the specified management (connector server) port. Overrides any value in the config file")
- .withLongOpt("jmxconnectorport").create();
-
- private static final Option OPTION_BIND =
- OptionBuilder.withArgName("address").hasArg()
- .withDescription("bind to the specified address. Overrides any value in the config file")
- .withLongOpt("bind").create("b");
+ private static final Option OPTION_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg()
+ .withDescription("use given configuration store location").withLongOpt("store-path").create("sp");
+
+ private static final Option OPTION_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg()
+ .withDescription("use given store type").withLongOpt("store-type").create("st");
+
+ private static final Option OPTION_INITIAL_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg()
+ .withDescription("pass the location of initial store to use to create a user store").withLongOpt("initial-store-path").create("isp");
+
+ private static final Option OPTION_INITIAL_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg()
+ .withDescription("the type of initial store").withLongOpt("initial-store-type").create("ist");
private static final Option OPTION_LOG_CONFIG_FILE =
OptionBuilder.withArgName("file").hasArg()
@@ -137,31 +65,31 @@ private static final Option OPTION_INCLUDE_0_8 =
.withDescription("monitor the log file configuration file for changes. Units are seconds. "
+ "Zero means do not check for changes.").withLongOpt("logwatch").create("w");
+ private static final Option OPTION_MANAGEMENT_MODE = OptionBuilder.withDescription("start broker in a management mode")
+ .withLongOpt("management-mode").create("mm");
+ private static final Option OPTION_RMI_PORT = OptionBuilder.withArgName("port").hasArg()
+ .withDescription("override jmx rmi port in management mode").withLongOpt("jmxregistryport").create("rmi");
+ private static final Option OPTION_CONNECTOR_PORT = OptionBuilder.withArgName("port").hasArg()
+ .withDescription("override jmx connector port in management mode").withLongOpt("jmxconnectorport").create("jmxrmi");
+ private static final Option OPTION_HTTP_PORT = OptionBuilder.withArgName("port").hasArg()
+ .withDescription("override web management port in management mode").withLongOpt("httpport").create("http");
+
private static final Options OPTIONS = new Options();
static
{
OPTIONS.addOption(OPTION_HELP);
OPTIONS.addOption(OPTION_VERSION);
- OPTIONS.addOption(OPTION_CONFIG_FILE);
+ OPTIONS.addOption(OPTION_CONFIGURATION_STORE_PATH);
+ OPTIONS.addOption(OPTION_CONFIGURATION_STORE_TYPE);
OPTIONS.addOption(OPTION_LOG_CONFIG_FILE);
OPTIONS.addOption(OPTION_LOG_WATCH);
- OPTIONS.addOption(OPTION_PORT);
- OPTIONS.addOption(OPTION_SSLPORT);
- OPTIONS.addOption(OPTION_EXCLUDE_1_0);
- OPTIONS.addOption(OPTION_EXCLUDE_0_10);
- 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);
- OPTIONS.addOption(OPTION_JMX_PORT_CONNECTOR_SERVER);
+ OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_PATH);
+ OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_TYPE);
+ OPTIONS.addOption(OPTION_MANAGEMENT_MODE);
+ OPTIONS.addOption(OPTION_RMI_PORT);
+ OPTIONS.addOption(OPTION_CONNECTOR_PORT);
+ OPTIONS.addOption(OPTION_HTTP_PORT);
}
protected CommandLine _commandLine;
@@ -243,10 +171,15 @@ private static final Option OPTION_INCLUDE_0_8 =
else
{
BrokerOptions options = new BrokerOptions();
- String configFile = _commandLine.getOptionValue(OPTION_CONFIG_FILE.getOpt());
- if(configFile != null)
+ String configurationStore = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_PATH.getOpt());
+ if (configurationStore != null)
+ {
+ options.setConfigurationStoreLocation(configurationStore);
+ }
+ String configurationStoreType = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_TYPE.getOpt());
+ if (configurationStoreType != null)
{
- options.setConfigFile(configFile);
+ options.setConfigurationStoreType(configurationStoreType);
}
String logWatchConfig = _commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt());
@@ -261,52 +194,37 @@ private static final Option OPTION_INCLUDE_0_8 =
options.setLogConfigFile(logConfig);
}
- String jmxPortRegistryServer = _commandLine.getOptionValue(OPTION_JMX_PORT_REGISTRY_SERVER.getOpt());
- if(jmxPortRegistryServer != null)
+ String initialConfigurationStore = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_PATH.getOpt());
+ if (initialConfigurationStore != null)
{
- options.setJmxPortRegistryServer(Integer.parseInt(jmxPortRegistryServer));
+ options.setInitialConfigurationStoreLocation(initialConfigurationStore);
}
-
- String jmxPortConnectorServer = _commandLine.getOptionValue(OPTION_JMX_PORT_CONNECTOR_SERVER.getLongOpt());
- if(jmxPortConnectorServer != null)
- {
- options.setJmxPortConnectorServer(Integer.parseInt(jmxPortConnectorServer));
- }
-
- String bindAddr = _commandLine.getOptionValue(OPTION_BIND.getOpt());
- if (bindAddr != null)
+ String initailConfigurationStoreType = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_TYPE.getOpt());
+ if (initailConfigurationStoreType != null)
{
- options.setBind(bindAddr);
+ options.setInitialConfigurationStoreType(initailConfigurationStoreType);
}
- String[] portStr = _commandLine.getOptionValues(OPTION_PORT.getOpt());
- if(portStr != null)
+ boolean managmentMode = _commandLine.hasOption(OPTION_MANAGEMENT_MODE.getOpt());
+ if (managmentMode)
{
- parsePortArray(options, portStr, false);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ options.setManagementMode(true);
+ String rmiPort = _commandLine.getOptionValue(OPTION_RMI_PORT.getOpt());
+ if (rmiPort != null)
{
- parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe);
+ options.setManagementModeRmiPort(Integer.parseInt(rmiPort));
}
- for(ProtocolInclusion pe : ProtocolInclusion.values())
+ String connectorPort = _commandLine.getOptionValue(OPTION_CONNECTOR_PORT.getOpt());
+ if (connectorPort != null)
{
- parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe);
+ options.setManagementModeConnectorPort(Integer.parseInt(connectorPort));
}
- }
-
- String[] sslPortStr = _commandLine.getOptionValues(OPTION_SSLPORT.getOpt());
- if(sslPortStr != null)
- {
- parsePortArray(options, sslPortStr, true);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ String httpPort = _commandLine.getOptionValue(OPTION_HTTP_PORT.getOpt());
+ if (httpPort != null)
{
- parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe);
- }
- for(ProtocolInclusion pe : ProtocolInclusion.values())
- {
- parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe);
+ options.setManagementModeHttpPort(Integer.parseInt(httpPort));
}
}
-
setExceptionHandler();
startBroker(options);
@@ -389,72 +307,7 @@ private static final Option OPTION_INCLUDE_0_8 =
protected void shutdown(final int status)
{
- ApplicationRegistry.remove();
System.exit(status);
}
- private static void parsePortArray(final BrokerOptions options,final Object[] ports,
- final boolean ssl) throws InitException
- {
- if(ports != null)
- {
- for(int i = 0; i < ports.length; i++)
- {
- try
- {
- if(ssl)
- {
- options.addSSLPort(Integer.parseInt(String.valueOf(ports[i])));
- }
- else
- {
- options.addPort(Integer.parseInt(String.valueOf(ports[i])));
- }
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid port: " + ports[i], e);
- }
- }
- }
- }
-
- private static void parsePortArray(final BrokerOptions options, final Object[] ports,
- final ProtocolExclusion excludedProtocol) throws InitException
- {
- if(ports != null)
- {
- for(int i = 0; i < ports.length; i++)
- {
- try
- {
- options.addExcludedPort(excludedProtocol,
- Integer.parseInt(String.valueOf(ports[i])));
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid port for exclusion: " + ports[i], e);
- }
- }
- }
- }
-
- 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/ProtocolExclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java
deleted file mode 100644
index fe6e32173f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.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;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public enum ProtocolExclusion
-{
- v0_8("exclude-0-8","--exclude-0-8"),
- v0_9("exclude-0-9", "--exclude-0-9"),
- v0_9_1("exclude-0-9-1", "--exclude-0-9-1"),
- v0_10("exclude-0-10", "--exclude-0-10"),
- v1_0("exclude-1-0", "--exclude-1-0");
-
- private static final Map<String, ProtocolExclusion> MAP = new HashMap<String,ProtocolExclusion>();
-
- static
- {
- for(ProtocolExclusion pe : ProtocolExclusion.values())
- {
- MAP.put(pe.getArg(), pe);
- }
- }
-
- private String _arg;
- private String _excludeName;
-
- private ProtocolExclusion(final String excludeName, final String arg)
- {
- _excludeName = excludeName;
- _arg = arg;
- }
-
- public String getArg()
- {
- return _arg;
- }
-
- public String getExcludeName()
- {
- return _excludeName;
- }
-
- public static ProtocolExclusion lookup(final String arg)
- {
- ProtocolExclusion ex = MAP.get(arg);
-
- if(ex == null)
- {
- throw new IllegalArgumentException(arg + " is not a valid protocol exclusion");
- }
-
- return ex;
- }
-}
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
deleted file mode 100644
index 85fbe2e02e..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.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;
-
-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
index 0c474cca13..b7007bf768 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java
@@ -18,46 +18,85 @@
*/
package org.apache.qpid.server;
-import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
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;
+import org.apache.qpid.server.txn.ServerTransaction;
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 static final String OPEN_TRANSACTION_TIMEOUT_ERROR = "Open transaction timed out";
+ private static final String IDLE_TRANSACTION_TIMEOUT_ERROR = "Idle transaction timed out";
private final LogSubject _logSubject;
- public TransactionTimeoutHelper(final LogSubject logSubject)
+ private final CloseAction _closeAction;
+
+ public TransactionTimeoutHelper(final LogSubject logSubject, final CloseAction closeAction)
{
_logSubject = logSubject;
+ _closeAction = closeAction;
}
- public void logIfNecessary(final long timeSoFar, final long warnTimeout,
- final LogMessage message, final String alternateLogPrefix)
+ public void checkIdleOrOpenTimes(ServerTransaction transaction, long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
{
- if (isTimedOut(timeSoFar, warnTimeout))
+ if (transaction.isTransactional())
{
- LogActor logActor = CurrentActor.get();
- if(logActor.getRootMessageLogger().isMessageEnabled(logActor, _logSubject, message.getLogHierarchy()))
+ final long transactionUpdateTime = transaction.getTransactionUpdateTime();
+ if(transactionUpdateTime > 0)
{
- logActor.message(_logSubject, message);
+ long idleTime = System.currentTimeMillis() - transactionUpdateTime;
+ boolean closed = logAndCloseIfNecessary(idleTime, idleWarn, idleClose, ChannelMessages.IDLE_TXN(idleTime), IDLE_TRANSACTION_TIMEOUT_ERROR);
+ if (closed)
+ {
+ return; // no point proceeding to check the open time
+ }
}
- else
+
+ final long transactionStartTime = transaction.getTransactionStartTime();
+ if(transactionStartTime > 0)
{
- LOGGER.warn(alternateLogPrefix + " " + _logSubject.toLogString() + " " + timeSoFar + " ms");
+ long openTime = System.currentTimeMillis() - transactionStartTime;
+ logAndCloseIfNecessary(openTime, openWarn, openClose, ChannelMessages.OPEN_TXN(openTime), OPEN_TRANSACTION_TIMEOUT_ERROR);
}
}
}
- public boolean isTimedOut(long timeSoFar, long timeout)
+ /**
+ * @return true iff closeTimeout was exceeded
+ */
+ private boolean logAndCloseIfNecessary(final long timeSoFar,
+ final long warnTimeout, final long closeTimeout,
+ final LogMessage warnMessage, final String closeMessage) throws AMQException
+ {
+ if (isTimedOut(timeSoFar, warnTimeout))
+ {
+ LogActor logActor = CurrentActor.get();
+ logActor.message(_logSubject, warnMessage);
+ }
+
+ if(isTimedOut(timeSoFar, closeTimeout))
+ {
+ _closeAction.doTimeoutAction(closeMessage);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ private boolean isTimedOut(long timeSoFar, long timeout)
{
return timeout > 0L && timeSoFar > timeout;
}
+
+ public interface CloseAction
+ {
+ void doTimeoutAction(String reason) throws AMQException;
+ }
+
}
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 9b3be624e0..469a4bb9d0 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,13 +35,15 @@ 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, UUID qmfId, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
+ public Binding(UUID id,
+ final String bindingKey,
+ final AMQQueue queue,
+ final Exchange exchange,
+ final Map<String, Object> arguments)
{
_id = id;
- _qmfId = qmfId;
_bindingKey = bindingKey;
_queue = queue;
_exchange = exchange;
@@ -53,11 +55,6 @@ 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 b805056311..69ff081528 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
@@ -24,10 +24,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.BindingConfig;
-import org.apache.qpid.server.configuration.BindingConfigType;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.BindingMessages;
@@ -52,7 +48,7 @@ public class BindingFactory
_virtualHost = vhost;
}
- private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task, BindingConfig
+ private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task
{
private final BindingLogSubject _logSubject;
//TODO : persist creation time
@@ -60,7 +56,7 @@ public class BindingFactory
private BindingImpl(UUID id, String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
{
- super(id, queue.getVirtualHost().getConfigStore().createId(), bindingKey, queue, exchange, arguments);
+ super(id, bindingKey, queue, exchange, arguments);
_logSubject = new BindingLogSubject(bindingKey,exchange,queue);
}
@@ -96,16 +92,6 @@ public class BindingFactory
return _createTime;
}
- public BindingConfigType getConfigType()
- {
- return BindingConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return _virtualHost;
- }
-
public boolean isDurable()
{
return getQueue().isDurable() && getExchange().isDurable();
@@ -186,7 +172,6 @@ public class BindingFactory
exchange.addCloseTask(b);
queue.addBinding(b);
exchange.addBinding(b);
- getConfigStore().addConfiguredObject(b);
b.logCreation();
return true;
@@ -197,11 +182,6 @@ public class BindingFactory
}
}
- private ConfigStore getConfigStore()
- {
- return _virtualHost.getConfigStore();
- }
-
public void restoreBinding(final UUID id, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap) throws AMQSecurityException, AMQInternalException
{
makeBinding(id, bindingKey,queue,exchange,argumentMap,true, false);
@@ -257,7 +237,6 @@ public class BindingFactory
_virtualHost.getMessageStore().unbindQueue(b);
}
b.logDestruction();
- getConfigStore().removeConfiguredObject(b);
}
return b;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java
deleted file mode 100644
index 1ed6b38758..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java
+++ /dev/null
@@ -1,114 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public final class BindingConfigType extends ConfigObjectType<BindingConfigType, BindingConfig>
-{
- private static final List<BindingProperty<?>> BINDING_PROPERTIES = new ArrayList<BindingProperty<?>>();
-
- public static interface BindingProperty<S> extends ConfigProperty<BindingConfigType, BindingConfig, S>
- {
- }
-
- private abstract static class BindingReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S>
- {
- public BindingReadWriteProperty(String name)
- {
- super(name);
- BINDING_PROPERTIES.add(this);
- }
- }
-
- private abstract static class BindingReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S>
- {
- public BindingReadOnlyProperty(String name)
- {
- super(name);
- BINDING_PROPERTIES.add(this);
- }
- }
-
- public static final BindingReadOnlyProperty<ExchangeConfig> EXCHANGE_PROPERTY = new BindingReadOnlyProperty<ExchangeConfig>("exchange")
- {
- public ExchangeConfig getValue(BindingConfig object)
- {
- return object.getExchange();
- }
- };
-
- public static final BindingReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new BindingReadOnlyProperty<QueueConfig>("queue")
- {
- public QueueConfig getValue(BindingConfig object)
- {
- return object.getQueue();
- }
- };
-
- public static final BindingReadOnlyProperty<String> BINDING_KEY_PROPERTY = new BindingReadOnlyProperty<String>("bindingKey")
- {
- public String getValue(BindingConfig object)
- {
- return object.getBindingKey();
- }
- };
-
- public static final BindingReadOnlyProperty<Map<String,Object>> ARGUMENTS = new BindingReadOnlyProperty<Map<String,Object>>("arguments")
- {
- public Map<String,Object> getValue(BindingConfig object)
- {
- return object.getArguments();
- }
- };
-
- public static final BindingReadOnlyProperty<String> ORIGIN_PROPERTY = new BindingReadOnlyProperty<String>("origin")
- {
- public String getValue(BindingConfig object)
- {
- return object.getOrigin();
- }
- };
-
- private static final BindingConfigType INSTANCE = new BindingConfigType();
-
- private BindingConfigType()
- {
- }
-
- public Collection<BindingProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(BINDING_PROPERTIES);
- }
-
- public static BindingConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java
deleted file mode 100644
index 888feeff0c..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java
+++ /dev/null
@@ -1,170 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class BridgeConfigType extends ConfigObjectType<BridgeConfigType, BridgeConfig>
-{
- private static final List<BridgeProperty<?>> BRIDGE_PROPERTIES = new ArrayList<BridgeProperty<?>>();
-
- public static interface BridgeProperty<S> extends ConfigProperty<BridgeConfigType, BridgeConfig, S>
- {
- }
-
- private abstract static class BridgeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S>
- {
- public BridgeReadWriteProperty(String name)
- {
- super(name);
- BRIDGE_PROPERTIES.add(this);
- }
- }
-
- private abstract static class BridgeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S>
- {
- public BridgeReadOnlyProperty(String name)
- {
- super(name);
- BRIDGE_PROPERTIES.add(this);
- }
- }
-
- public static final BridgeReadOnlyProperty<LinkConfig> LINK_PROPERTY = new BridgeReadOnlyProperty<LinkConfig>("link")
- {
- public LinkConfig getValue(BridgeConfig object)
- {
- return object.getLink();
- }
- };
-
- public static final BridgeReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new BridgeReadOnlyProperty<Integer>("channelId")
- {
- public Integer getValue(BridgeConfig object)
- {
- return object.getChannelId();
- }
- };
-
- public static final BridgeReadOnlyProperty<Boolean> DURABLE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("durable")
- {
- public Boolean getValue(BridgeConfig object)
- {
- return object.isDurable();
- }
- };
-
- public static final BridgeReadOnlyProperty<String> SOURCE_PROPERTY = new BridgeReadOnlyProperty<String>("source")
- {
- public String getValue(BridgeConfig object)
- {
- return object.getSource();
- }
- };
-
- public static final BridgeReadOnlyProperty<String> DESTINATION_PROPERTY = new BridgeReadOnlyProperty<String>("destination")
- {
- public String getValue(BridgeConfig object)
- {
- return object.getDestination();
- }
- };
-
- public static final BridgeReadOnlyProperty<String> KEY_PROPERTY = new BridgeReadOnlyProperty<String>("key")
- {
- public String getValue(BridgeConfig object)
- {
- return object.getKey();
- }
- };
-
- public static final BridgeReadOnlyProperty<Boolean> QUEUE_BRIDGE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("queueBridge")
- {
- public Boolean getValue(BridgeConfig object)
- {
- return object.isQueueBridge();
- }
- };
-
- public static final BridgeReadOnlyProperty<Boolean> LOCAL_SOURCE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("localSource")
- {
- public Boolean getValue(BridgeConfig object)
- {
- return object.isLocalSource();
- }
- };
-
- public static final BridgeReadOnlyProperty<String> TAG_PROPERTY = new BridgeReadOnlyProperty<String>("tag")
- {
- public String getValue(BridgeConfig object)
- {
- return object.getTag();
- }
- };
-
- public static final BridgeReadOnlyProperty<String> EXCLUDES_PROPERTY = new BridgeReadOnlyProperty<String>("excludes")
- {
- public String getValue(BridgeConfig object)
- {
- return object.getExcludes();
- }
- };
-
- public static final BridgeReadOnlyProperty<Boolean> DYNAMIC_PROPERTY = new BridgeReadOnlyProperty<Boolean>("dynamic")
- {
- public Boolean getValue(BridgeConfig object)
- {
- return object.isDynamic();
- }
- };
-
- public static final BridgeReadOnlyProperty<Integer> ACK_BATCHING_PROPERTY = new BridgeReadOnlyProperty<Integer>("ackBatching")
- {
- public Integer getValue(BridgeConfig object)
- {
- return object.getAckBatching();
- }
- };
-
-
- private static final BridgeConfigType INSTANCE = new BridgeConfigType();
-
- private BridgeConfigType()
- {
- }
-
- public Collection<BridgeProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(BRIDGE_PROPERTIES);
- }
-
- public static BridgeConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java
deleted file mode 100644
index 7dffc2d3c0..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java
+++ /dev/null
@@ -1,71 +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;
-
-import java.util.List;
-
-
-public interface BrokerConfig extends ConfiguredObject<BrokerConfigType,BrokerConfig>
-{
- void setSystem(SystemConfig system);
-
- SystemConfig getSystem();
-
- Integer getPort();
-
- Integer getWorkerThreads();
-
- Integer getMaxConnections();
-
- Integer getConnectionBacklogLimit();
-
- Long getStagingThreshold();
-
- Integer getManagementPublishInterval();
-
- String getVersion();
-
- String getDataDirectory();
-
- String getFederationTag();
-
- /**
- * List of feature(s) to be advertised to clients on connection.
- * Feature names are strings, beginning with qpid. followed by more or more
- * words separated by minus signs e.g. qpid.jms-selector.
- *
- * If there are no features, this method must return an empty array.
- *
- * @return list of feature names
- */
- List<String> getFeatures();
-
- void addVirtualHost(VirtualHostConfig virtualHost);
-
- void createBrokerConnection(String transport,
- String host,
- int port,
- boolean durable,
- String authMechanism,
- String username, String password);
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java
deleted file mode 100644
index 64a59c3f61..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.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.configuration;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class BrokerConfigType extends ConfigObjectType<BrokerConfigType, BrokerConfig>
-{
- private static final List<BrokerProperty<?>> BROKER_PROPERTIES = new ArrayList<BrokerProperty<?>>();
-
- public static interface BrokerProperty<S> extends ConfigProperty<BrokerConfigType, BrokerConfig, S>
- {
- }
-
- private abstract static class BrokerReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S>
- {
- public BrokerReadWriteProperty(String name)
- {
- super(name);
- BROKER_PROPERTIES.add(this);
- }
- }
-
- private abstract static class BrokerReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S>
- {
- public BrokerReadOnlyProperty(String name)
- {
- super(name);
- BROKER_PROPERTIES.add(this);
- }
- }
-
- public static final BrokerReadOnlyProperty<SystemConfig> SYSTEM_PROPERTY = new BrokerReadOnlyProperty<SystemConfig>("system")
- {
- public SystemConfig getValue(BrokerConfig object)
- {
- return object.getSystem();
- }
- };
-
- public static final BrokerReadOnlyProperty<Integer> PORT_PROPERTY = new BrokerReadOnlyProperty<Integer>("port")
- {
- public Integer getValue(BrokerConfig object)
- {
- return object.getPort();
- }
- };
-
- public static final BrokerReadOnlyProperty<Integer> WORKER_THREADS_PROPERTY = new BrokerReadOnlyProperty<Integer>("workerThreads")
- {
- public Integer getValue(BrokerConfig object)
- {
- return object.getWorkerThreads();
- }
- };
-
- public static final BrokerReadOnlyProperty<Integer> MAX_CONNECTIONS_PROPERTY = new BrokerReadOnlyProperty<Integer>("maxConnections")
- {
- public Integer getValue(BrokerConfig object)
- {
- return object.getMaxConnections();
- }
- };
-
- public static final BrokerReadOnlyProperty<Integer> CONNECTION_BACKLOG_LIMIT_PROPERTY = new BrokerReadOnlyProperty<Integer>("connectionBacklog")
- {
- public Integer getValue(BrokerConfig object)
- {
- return object.getConnectionBacklogLimit();
- }
- };
-
- public static final BrokerReadOnlyProperty<Long> STAGING_THRESHOLD_PROPERTY = new BrokerReadOnlyProperty<Long>("stagingThreshold")
- {
- public Long getValue(BrokerConfig object)
- {
- return object.getStagingThreshold();
- }
- };
-
- public static final BrokerReadOnlyProperty<Integer> MANAGEMENT_PUBLISH_INTERVAL_PROPERTY = new BrokerReadOnlyProperty<Integer>("mgmtPublishInterval")
- {
- public Integer getValue(BrokerConfig object)
- {
- return object.getManagementPublishInterval();
- }
- };
-
- public static final BrokerReadOnlyProperty<String> VERSION_PROPERTY = new BrokerReadOnlyProperty<String>("version")
- {
- public String getValue(BrokerConfig object)
- {
- return object.getVersion();
- }
- };
-
- public static final BrokerReadOnlyProperty<String> DATA_DIR_PROPERTY = new BrokerReadOnlyProperty<String>("dataDirectory")
- {
- public String getValue(BrokerConfig object)
- {
- return object.getDataDirectory();
- }
- };
-
- private static final BrokerConfigType INSTANCE = new BrokerConfigType();
-
- private BrokerConfigType()
- {
- }
-
- public Collection<BrokerProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(BROKER_PROPERTIES);
- }
-
- public static BrokerConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java
new file mode 100644
index 0000000000..31e08ab88a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+
+/**
+ * A helper class responsible for creation and opening of broker store.
+ */
+public class BrokerConfigurationStoreCreator
+{
+ /**
+ * URL to resource containing broker default configuration
+ */
+ public static final String DEFAULT_INITIAL_STORE_LOCATION = BrokerConfigurationStoreCreator.class.getClassLoader()
+ .getResource("initial-store.json").toExternalForm();
+
+ private Map<String, ConfigurationStoreFactory> _factories = new HashMap<String, ConfigurationStoreFactory>();
+
+ public BrokerConfigurationStoreCreator()
+ {
+ QpidServiceLoader<ConfigurationStoreFactory> serviceLoader = new QpidServiceLoader<ConfigurationStoreFactory>();
+ Iterable<ConfigurationStoreFactory> configurationStoreFactories = serviceLoader
+ .instancesOf(ConfigurationStoreFactory.class);
+ for (ConfigurationStoreFactory storeFactory : configurationStoreFactories)
+ {
+ String type = storeFactory.getStoreType();
+ ConfigurationStoreFactory factory = _factories.put(type.toLowerCase(), storeFactory);
+ if (factory != null)
+ {
+ throw new IllegalStateException("ConfigurationStoreFactory with type name '" + type
+ + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '"
+ + storeFactory.getClass().getName() + "'");
+ }
+ }
+ }
+
+ /**
+ * Create broker configuration store for a given store location, store type, initial store location and initial store type
+ *
+ * @param storeLocation store location
+ * @param storeType store type
+ * @param initialStoreLocation initial store location
+ * @param initialStoreType initial store type
+ * @return store instance opened at given store location
+ * @throws IllegalConfigurationException if store type is unknown
+ */
+ public ConfigurationEntryStore createStore(String storeLocation, String storeType, String initialStoreLocation,
+ String initialStoreType)
+ {
+ ConfigurationEntryStore store = createStore(storeType);
+ if (initialStoreLocation == null)
+ {
+ initialStoreLocation = DEFAULT_INITIAL_STORE_LOCATION;
+ initialStoreType = JsonConfigurationEntryStore.STORE_TYPE;
+ }
+ if (storeType.equals(initialStoreType))
+ {
+ store.open(storeLocation, initialStoreLocation);
+ }
+ else
+ {
+ ConfigurationEntryStore initialStore = createStore(initialStoreType);
+ initialStore.open(initialStoreLocation);
+ store.open(storeLocation, initialStore);
+ }
+ return store;
+ }
+
+ private ConfigurationEntryStore createStore(String storeType)
+ {
+ ConfigurationStoreFactory factory = _factories.get(storeType.toLowerCase());
+ if (factory == null)
+ {
+ throw new IllegalConfigurationException("Unknown store type: " + storeType);
+ }
+ return factory.createStore();
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java
new file mode 100644
index 0000000000..179d4a5640
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java
@@ -0,0 +1,54 @@
+package org.apache.qpid.server.configuration;
+
+import java.util.Locale;
+
+/**
+ * Declares broker system property names
+ */
+public class BrokerProperties
+{
+ public static final int DEFAULT_HEART_BEAT_TIMEOUT_FACTOR = 2;
+
+ public static final String PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX = "qpid.dead_letter_exchange_suffix";
+ public static final String PROPERTY_DEAD_LETTER_QUEUE_SUFFIX = "qpid.dead_letter_queue_suffix";
+
+ public static final String PROPERTY_FRAME_SIZE = "qpid.frame_size";
+ public static final String PROPERTY_MSG_AUTH = "qpid.msg_auth";
+ public static final String PROPERTY_STATUS_UPDATES = "qpid.status_updates";
+ public static final String PROPERTY_LOCALE = "qpid.locale";
+ public static final String PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY = "qpid.default_supported_protocol_version_reply";
+ public static final String PROPERTY_DISABLED_FEATURES = "qpid.broker_disabled_features";
+
+ public static final int DEFAULT_FRAME_SIZE = Integer.getInteger(PROPERTY_FRAME_SIZE, 65535);
+ public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES = "qpid.broker_default_amqp_protocol_excludes";
+ public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES = "qpid.broker_default_amqp_protocol_includes";
+
+ public static final String PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS = "qpid.broker_jmx_method_rights_infer_all_access";
+ public static final String PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY = "qpid.broker_jmx_use_custom_rmi_socket_factory";
+
+ public static final String PROPERTY_QPID_HOME = "QPID_HOME";
+ public static final String PROPERTY_QPID_WORK = "QPID_WORK";
+
+ private BrokerProperties()
+ {
+ }
+
+ public static Locale getLocale()
+ {
+ Locale locale = Locale.US;
+ String localeSetting = System.getProperty(BrokerProperties.PROPERTY_LOCALE);
+ if (localeSetting != null)
+ {
+ String[] localeParts = localeSetting.split("_");
+ String language = (localeParts.length > 0 ? localeParts[0] : "");
+ String country = (localeParts.length > 1 ? localeParts[1] : "");
+ String variant = "";
+ if (localeParts.length > 2)
+ {
+ variant = localeSetting.substring(language.length() + 1 + country.length() + 1);
+ }
+ locale = new Locale(language, country, variant);
+ }
+ return locale;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java
deleted file mode 100644
index 2d88ba00a0..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java
+++ /dev/null
@@ -1,66 +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;
-
-public interface ConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S>
-{
- public String getName();
-
- public S getValue(C object);
-
- public void setValue(C object, S value);
-
- public void clearValue(C object);
-
- public abstract static class ReadWriteConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>,S> implements ConfigProperty<T, C, S>
- {
- private final String _name;
-
- protected ReadWriteConfigProperty(String name)
- {
- _name = name;
- }
-
- public final String getName()
- {
- return _name;
- }
- }
-
- public abstract static class ReadOnlyConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> extends ReadWriteConfigProperty<T, C, S>
- {
- protected ReadOnlyConfigProperty(String name)
- {
- super(name);
- }
-
- public final void setValue(C object, S value)
- {
- throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only");
- }
-
- public final void clearValue(C object)
- {
- throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only");
- }
- }
-}
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
deleted file mode 100644
index c519a0c0fa..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java
+++ /dev/null
@@ -1,201 +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;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class ConfigStore
-{
- private ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>> _typeMap =
- new ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>>();
-
- private ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>> _listenerMap =
- new ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>>();
-
- private AtomicReference<SystemConfig> _root = new AtomicReference<SystemConfig>(null);
-
- private final AtomicLong _objectIdSource = new AtomicLong(0l);
- private final AtomicLong _persistentObjectIdSource = new AtomicLong(0l);
-
- // TODO - should load/increment this on broker startup
- private long _sequenceNumber = 1L;
-
- public enum Event
- {
- CREATED, DELETED
- }
-
- public interface ConfigEventListener<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>>
- {
- void onEvent(C object, Event evt);
- }
-
- private ConfigStore()
- {
- }
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> ConfiguredObject<T, C> getConfiguredObject(ConfigObjectType<T,C> type, UUID id)
- {
- ConcurrentHashMap<UUID, ConfiguredObject> typeMap = _typeMap.get(type);
- if(typeMap != null)
- {
- return typeMap.get(id);
- }
- else
- {
- return null;
- }
-
- }
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> Collection<? extends C> getConfiguredObjects(ConfigObjectType<T,C> type)
- {
- ConcurrentHashMap typeMap = _typeMap.get(type);
- if(typeMap != null)
- {
- return typeMap.values();
- }
- else
- {
- return Collections.EMPTY_LIST;
- }
-
- }
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfiguredObject(ConfiguredObject<T, C> object)
- {
- ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType());
- if(typeMap == null)
- {
- typeMap = new ConcurrentHashMap();
- ConcurrentHashMap oldMap = _typeMap.putIfAbsent(object.getConfigType(), typeMap);
- if(oldMap != null)
- {
- typeMap = oldMap;
- }
-
- }
-
- typeMap.put(object.getQMFId(), object);
- sendEvent(Event.CREATED, object);
- }
-
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfiguredObject(ConfiguredObject<T, C> object)
- {
- ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType());
- if(typeMap != null)
- {
- typeMap.remove(object.getQMFId());
- sendEvent(Event.DELETED, object);
- }
- }
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfigEventListener(T type, ConfigEventListener<T,C> listener)
- {
- CopyOnWriteArrayList listeners = _listenerMap.get(type);
- if(listeners == null)
- {
- listeners = new CopyOnWriteArrayList();
- CopyOnWriteArrayList oldListeners = _listenerMap.putIfAbsent(type, listeners);
- if(oldListeners != null)
- {
- listeners = oldListeners;
- }
-
- }
-
- listeners.add(listener);
-
- }
-
- public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfigEventListener(T type, ConfigEventListener<T,C> listener)
- {
- CopyOnWriteArrayList listeners = _listenerMap.get(type);
- if(listeners != null)
- {
- listeners.remove(listener);
- }
- }
-
- private void sendEvent(Event e, ConfiguredObject o)
- {
- CopyOnWriteArrayList<ConfigEventListener> listeners = _listenerMap.get(o.getConfigType());
- if(listeners != null)
- {
- for(ConfigEventListener listener : listeners)
- {
- listener.onEvent(o, e);
- }
- }
- }
-
- public boolean setRoot(SystemConfig object)
- {
- if(_root.compareAndSet(null,object))
- {
- addConfiguredObject(object);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- public UUID createId()
- {
- return new UUID(((_sequenceNumber & 0xFFFl)<<48), _objectIdSource.incrementAndGet());
- }
-
- public UUID createPersistentId()
- {
- return new UUID(0L, _persistentObjectIdSource.incrementAndGet());
- }
-
- public void persistentIdInUse(UUID id)
- {
- long lsb = id.getLeastSignificantBits();
- long currentId;
- while((currentId = _persistentObjectIdSource.get()) < lsb)
- {
- _persistentObjectIdSource.compareAndSet(currentId, lsb);
- }
- }
-
- public SystemConfig getRoot()
- {
- return _root.get();
- }
-
- public static ConfigStore newInstance()
- {
- return new ConfigStore();
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java
new file mode 100644
index 0000000000..8afb1af24d
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.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.configuration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+public class ConfigurationEntry
+{
+ public static final String ATTRIBUTE_NAME = "name";
+
+ private final UUID _id;
+ private final String _type;
+ private final Map<String, Object> _attributes;
+ private final Set<UUID> _childrenIds;
+ private final ConfigurationEntryStore _store;
+
+ public ConfigurationEntry(UUID id, String type, Map<String, Object> attributes, Set<UUID> childrenIds,
+ ConfigurationEntryStore store)
+ {
+ super();
+ _id = id;
+ _type = type;
+ _attributes = attributes;
+ _childrenIds = childrenIds;
+ _store = store;
+ }
+
+ public UUID getId()
+ {
+ return _id;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+
+ public Map<String, Object> getAttributes()
+ {
+ return _attributes;
+ }
+
+ public Set<UUID> getChildrenIds()
+ {
+ return _childrenIds;
+ }
+
+ public ConfigurationEntryStore getStore()
+ {
+ return _store;
+ }
+
+ /**
+ * Returns this entry's children. The collection should not be modified.
+ */
+ public Map<String, Collection<ConfigurationEntry>> getChildren()
+ {
+ Map<String, Collection<ConfigurationEntry>> children = null;
+ if (_childrenIds == null)
+ {
+ children = Collections.emptyMap();
+ }
+ else
+ {
+ children = new HashMap<String, Collection<ConfigurationEntry>>();
+ for (UUID childId : _childrenIds)
+ {
+ ConfigurationEntry entry = _store.getEntry(childId);
+ String type = entry.getType();
+ Collection<ConfigurationEntry> childrenOfType = children.get(type);
+ if (childrenOfType == null)
+ {
+ childrenOfType = new ArrayList<ConfigurationEntry>();
+ children.put(type, childrenOfType);
+ }
+ childrenOfType.add(entry);
+ }
+ }
+ return Collections.unmodifiableMap(children);
+ }
+
+ public boolean hasChild(UUID id)
+ {
+ return _childrenIds.contains(id);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return _id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+
+ ConfigurationEntry other = (ConfigurationEntry) obj;
+ if (_id == null)
+ {
+ if (other._id != null)
+ {
+ return false;
+ }
+ }
+ else if (!_id.equals(other._id))
+ {
+ return false;
+ }
+
+ if (_type == null)
+ {
+ if (other._type != null)
+ {
+ return false;
+ }
+ }
+ else if (!_type.equals(other._type))
+ {
+ return false;
+ }
+
+ if (_store == null)
+ {
+ if (other._store != null)
+ {
+ return false;
+ }
+ }
+ else if (!_store.equals(other._store))
+ {
+ return false;
+ }
+
+ if (_childrenIds == null)
+ {
+ if (other._childrenIds != null)
+ {
+ return false;
+ }
+ }
+ else if (!_childrenIds.equals(other._childrenIds))
+ {
+ return false;
+ }
+
+ if (_attributes == null)
+ {
+ if (other._attributes != null)
+ {
+ return false;
+ }
+ }
+ else if (!_attributes.equals(other._attributes))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ConfigurationEntry [id=" + _id + ", type=" + _type + ", attributes=" + _attributes + ", childrenIds="
+ + _childrenIds + "]";
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java
new file mode 100644
index 0000000000..8238d147bd
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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;
+
+import java.util.UUID;
+
+public interface ConfigurationEntryStore
+{
+ /**
+ * Opens the store from a given location.
+ * <p>
+ * If location does not exists than a new empty store is created with a single root entry
+ *
+ * @param storeLocation store location
+ * @throws IllegalConfigurationException if store cannot be opened in the given location
+ */
+ void open(String storeLocation);
+
+ /**
+ * Opens the store from a given location.
+ * <p>
+ * If location does not exists than a new store is created either empty or from the initial store location if it is provided
+ *
+ * @param storeLocation store location
+ * @param initialStoreLocation initial store location
+ * @throws IllegalConfigurationException if store cannot be opened in the given location or initial store location does not
+ * exists or corrupted.
+ */
+ void open(String storeLocation, String initialStoreLocation);
+
+ /**
+ * Opens the store from a given location.
+ * <p>
+ * If location does not exists than a new store is created either empty or from the initial store if it is provided
+ *
+ * @param storeLocation store location
+ * @param initialStore initial store
+ * @throws IllegalConfigurationException if store cannot be opened in the given location
+ */
+ void open(String storeLocation, ConfigurationEntryStore initialStore);
+
+ /**
+ * Returns stored root configuration entry
+ *
+ * @return root entry
+ */
+ ConfigurationEntry getRootEntry();
+
+ /**
+ * Returns the configuration entry with a given id.
+ *
+ * @return entry with a given id or null if entry does not exists
+ */
+ ConfigurationEntry getEntry(UUID id);
+
+ /**
+ * Saves given entries in the store.
+ *
+ * @param entries entries to store
+ * @throws IllegalConfigurationException if save operation fails
+ */
+ void save(ConfigurationEntry... entries);
+
+ /**
+ * Removes the entries with given IDs and all their children
+ *
+ * @param entryIds IDs of entries to remove
+ * @return IDs of removed entries
+ * @throws IllegalConfigurationException if remove operation fails
+ */
+ UUID[] remove(UUID... entryIds);
+
+ /**
+ * Copies the store into the given location
+ *
+ * @param target location to copy store into
+ * @throws IllegalConfigurationException if store cannot be copied into given location
+ */
+ public void copyTo(String copyLocation);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java
deleted file mode 100644
index 06402fa646..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java
+++ /dev/null
@@ -1,54 +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;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class ConfigurationManager
-{
- public List<ConfigurationPlugin> getConfigurationPlugins(String configurationElement, Configuration configuration) throws ConfigurationException
- {
- List<ConfigurationPlugin> plugins = new ArrayList<ConfigurationPlugin>();
- Map<List<String>, ConfigurationPluginFactory> factories =
- ApplicationRegistry.getInstance().getPluginManager().getConfigurationPlugins();
-
- for (Entry<List<String>, ConfigurationPluginFactory> entry : factories.entrySet())
- {
- if (entry.getKey().contains(configurationElement))
- {
- ConfigurationPluginFactory factory = entry.getValue();
- plugins.add(factory.newInstance(configurationElement, configuration));
- }
- }
-
- return plugins;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java
index c45aaaf1ee..dced38d260 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java
@@ -18,13 +18,18 @@
* under the License.
*
*/
-
package org.apache.qpid.server.configuration;
-import java.util.Collection;
-public abstract class ConfigObjectType<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>>
+public interface ConfigurationStoreFactory
{
- public abstract Collection<? extends ConfigProperty<T, C, ?>> getProperties();
+ /**
+ * Returns the type of the store this factory can create
+ */
+ public String getStoreType();
+ /**
+ * Creates the store instance.
+ */
+ public ConfigurationEntryStore createStore();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java
index bfb2de4235..65d97e6db1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java
@@ -20,10 +20,9 @@
*/
package org.apache.qpid.server.configuration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.model.ConfiguredObject;
-public interface ExchangeConfigurationPlugin
+public interface ConfiguredObjectRecoverer<T extends ConfiguredObject>
{
- ConfigurationPlugin getConfiguration(AMQQueue queue);
+ T create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java
deleted file mode 100644
index 5631fda37c..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.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.configuration;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class ConnectionConfigType extends ConfigObjectType<ConnectionConfigType, ConnectionConfig>
-{
- private static final List<ConnectionProperty<?>> CONNECTION_PROPERTIES = new ArrayList<ConnectionProperty<?>>();
-
- public static interface ConnectionProperty<S> extends ConfigProperty<ConnectionConfigType, ConnectionConfig, S>
- {
- }
-
- private abstract static class ConnectionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S>
- {
- public ConnectionReadWriteProperty(String name)
- {
- super(name);
- CONNECTION_PROPERTIES.add(this);
- }
- }
-
- private abstract static class ConnectionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S>
- {
- public ConnectionReadOnlyProperty(String name)
- {
- super(name);
- CONNECTION_PROPERTIES.add(this);
- }
- }
-
- public static final ConnectionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ConnectionReadOnlyProperty<VirtualHostConfig>("virtualHost")
- {
- public VirtualHostConfig getValue(ConnectionConfig object)
- {
- return object.getVirtualHost();
- }
- };
-
- public static final ConnectionReadOnlyProperty<String> ADDRESS_PROPERTY = new ConnectionReadOnlyProperty<String>("address")
- {
- public String getValue(ConnectionConfig object)
- {
- return object.getAddress();
- }
- };
-
- public static final ConnectionReadOnlyProperty<Boolean> INCOMING_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("incoming")
- {
- public Boolean getValue(ConnectionConfig object)
- {
- return object.isIncoming();
- }
- };
-
- public static final ConnectionReadOnlyProperty<Boolean> SYSTEM_CONNECTION_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("systemConnection")
- {
- public Boolean getValue(ConnectionConfig object)
- {
- return object.isSystemConnection();
- }
- };
-
- public static final ConnectionReadOnlyProperty<Boolean> FEDERATION_LINK_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("federationLink")
- {
- public Boolean getValue(ConnectionConfig object)
- {
- return object.isFederationLink();
- }
- };
-
- public static final ConnectionReadOnlyProperty<String> AUTH_ID_PROPERTY = new ConnectionReadOnlyProperty<String>("authId")
- {
- public String getValue(ConnectionConfig object)
- {
- return object.getAuthId();
- }
- };
-
- public static final ConnectionReadOnlyProperty<String> REMOTE_PROCESS_NAME_PROPERTY = new ConnectionReadOnlyProperty<String>("remoteProcessName")
- {
- public String getValue(ConnectionConfig object)
- {
- return object.getRemoteProcessName();
- }
- };
-
-
- public static final ConnectionReadOnlyProperty<Integer> REMOTE_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remotePid")
- {
- public Integer getValue(ConnectionConfig object)
- {
- return object.getRemotePID();
- }
- };
-
- public static final ConnectionReadOnlyProperty<Integer> REMOTE_PARENT_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remoteParentPid")
- {
- public Integer getValue(ConnectionConfig object)
- {
- return object.getRemoteParentPID();
- }
- };
-
- private static final ConnectionConfigType INSTANCE = new ConnectionConfigType();
-
- private ConnectionConfigType()
- {
- }
-
- public Collection<ConnectionProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(CONNECTION_PROPERTIES);
- }
-
- public static ConnectionConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
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
deleted file mode 100644
index 6633d93adf..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java
+++ /dev/null
@@ -1,60 +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;
-
-import org.apache.qpid.server.exchange.ExchangeType;
-
-import java.util.Map;
-
-
-public interface ExchangeConfig extends ConfiguredObject<ExchangeConfigType, ExchangeConfig>
-{
- VirtualHostConfig getVirtualHost();
-
- String getName();
-
- ExchangeType getType();
-
- boolean isAutoDelete();
-
- ExchangeConfig getAlternateExchange();
-
- Map<String, Object> getArguments();
-
-
- long getBindingCount();
-
- long getBindingCountHigh();
-
- long getMsgReceives();
-
- 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/ExchangeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java
deleted file mode 100644
index c7744117c4..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java
+++ /dev/null
@@ -1,115 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public final class ExchangeConfigType extends ConfigObjectType<ExchangeConfigType, ExchangeConfig>
-{
- private static final List<ExchangeProperty<?>> EXCHANGE_PROPERTIES = new ArrayList<ExchangeProperty<?>>();
-
- public static interface ExchangeProperty<S> extends ConfigProperty<ExchangeConfigType, ExchangeConfig, S>
- {
- }
-
- private abstract static class ExchangeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S>
- {
- public ExchangeReadWriteProperty(String name)
- {
- super(name);
- EXCHANGE_PROPERTIES.add(this);
- }
- }
-
- private abstract static class ExchangeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S>
- {
- public ExchangeReadOnlyProperty(String name)
- {
- super(name);
- EXCHANGE_PROPERTIES.add(this);
- }
- }
-
- public static final ExchangeReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ExchangeReadOnlyProperty<VirtualHostConfig>("virtualHost")
- {
- public VirtualHostConfig getValue(ExchangeConfig object)
- {
- return object.getVirtualHost();
- }
- };
-
- public static final ExchangeReadOnlyProperty<String> NAME_PROPERTY = new ExchangeReadOnlyProperty<String>("name")
- {
- public String getValue(ExchangeConfig object)
- {
- return object.getName();
- }
- };
-
- public static final ExchangeReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new ExchangeReadOnlyProperty<Boolean>("autodelete")
- {
- public Boolean getValue(ExchangeConfig object)
- {
- return object.isAutoDelete();
- }
- };
-
-
- public static final ExchangeReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new ExchangeReadOnlyProperty<ExchangeConfig>("alternateExchange")
- {
- public ExchangeConfig getValue(ExchangeConfig object)
- {
- return object.getAlternateExchange();
- }
- };
-
- public static final ExchangeReadOnlyProperty<Map<String,Object>> ARGUMENTS = new ExchangeReadOnlyProperty<Map<String,Object>>("arguments")
- {
- public Map<String,Object> getValue(ExchangeConfig object)
- {
- return object.getArguments();
- }
- };
-
- private static final ExchangeConfigType INSTANCE = new ExchangeConfigType();
-
- private ExchangeConfigType()
- {
- }
-
- public Collection<ExchangeProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(EXCHANGE_PROPERTIES);
- }
-
- public static ExchangeConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java
index 8a9029fbfd..bedd470ddf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java
@@ -18,25 +18,20 @@
* under the License.
*
*/
-
package org.apache.qpid.server.configuration;
-public interface SystemConfig extends ConfiguredObject<SystemConfigType,SystemConfig>
+public class IllegalConfigurationException extends RuntimeException
{
- String getName();
-
- String getOperatingSystemName();
-
- String getNodeName();
-
-
- String getOSRelease();
-
- String getOSVersion();
+ private static final long serialVersionUID = 1130064756291179812L;
- String getOSArchitecture();
+ public IllegalConfigurationException(String message)
+ {
+ super(message);
+ }
- void addBroker(BrokerConfig broker);
+ public IllegalConfigurationException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
- void removeBroker(BrokerConfig broker);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
deleted file mode 100644
index 2c37a94db0..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java
+++ /dev/null
@@ -1,56 +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;
-
-public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig>
-{
- VirtualHostConfig getVirtualHost();
-
-
- String getTransport();
-
- String getHost();
-
- int getPort();
-
- String getRemoteVhost();
-
- String getAuthMechanism();
-
- String getUsername();
-
- String getPassword();
-
- void close();
-
- void createBridge(boolean durable,
- boolean dynamic,
- boolean srcIsQueue,
- boolean srcIsLocal,
- String src,
- String dest,
- String key, String tag, String excludes);
-
- String getState();
-
- String getLastError();
-} \ 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
deleted file mode 100644
index 847cae87f5..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java
+++ /dev/null
@@ -1,137 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkConfig>
-{
- private static final List<LinkProperty<?>> LINK_PROPERTIES = new ArrayList<LinkProperty<?>>();
-
- public static interface LinkProperty<S> extends ConfigProperty<LinkConfigType, LinkConfig, S>
- {
- }
-
- private abstract static class LinkReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S>
- {
- public LinkReadWriteProperty(String name)
- {
- super(name);
- LINK_PROPERTIES.add(this);
- }
- }
-
- private abstract static class LinkReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S>
- {
- public LinkReadOnlyProperty(String name)
- {
- super(name);
- LINK_PROPERTIES.add(this);
- }
- }
-
- public static final LinkReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new LinkReadOnlyProperty<VirtualHostConfig>("virtualHost")
- {
- public VirtualHostConfig getValue(LinkConfig object)
- {
- return object.getVirtualHost();
- }
- };
-
- public static final LinkReadOnlyProperty<String> TRANSPORT_PROPERTY = new LinkReadOnlyProperty<String>("transport")
- {
- public String getValue(LinkConfig object)
- {
- return object.getTransport();
- }
- };
-
- public static final LinkReadOnlyProperty<String> HOST_PROPERTY = new LinkReadOnlyProperty<String>("host")
- {
- public String getValue(LinkConfig object)
- {
- return object.getHost();
- }
- };
-
- public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("port")
- {
- public Integer getValue(LinkConfig object)
- {
- return object.getPort();
- }
- };
-
- public static final LinkReadOnlyProperty<String> REMOTE_VHOST_PROPERTY = new LinkReadOnlyProperty<String>("remoteVhost")
- {
- public String getValue(LinkConfig object)
- {
- return object.getRemoteVhost();
- }
- };
-
- public static final LinkReadOnlyProperty<String> AUTH_MECHANISM_PROPERTY = new LinkReadOnlyProperty<String>("authMechanism")
- {
- public String getValue(LinkConfig object)
- {
- return object.getAuthMechanism();
- }
- };
-
- public static final LinkReadOnlyProperty<String> USERNAME_PROPERTY = new LinkReadOnlyProperty<String>("username")
- {
- public String getValue(LinkConfig object)
- {
- return object.getUsername();
- }
- };
-
- public static final LinkReadOnlyProperty<String> PASSWORD_PROPERTY = new LinkReadOnlyProperty<String>("password")
- {
- public String getValue(LinkConfig object)
- {
- return object.getPassword();
- }
- };
-
- private static final LinkConfigType INSTANCE = new LinkConfigType();
-
- private LinkConfigType()
- {
- }
-
- public Collection<LinkProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(LINK_PROPERTIES);
- }
-
- public static LinkConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java
deleted file mode 100644
index 1ef5edeb51..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java
+++ /dev/null
@@ -1,86 +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;
-
-import org.apache.qpid.AMQException;
-
-import java.util.Map;
-
-
-public interface QueueConfig extends ConfiguredObject<QueueConfigType, QueueConfig>
-{
- VirtualHostConfig getVirtualHost();
-
- String getName();
-
- boolean isExclusive();
-
- boolean isAutoDelete();
-
- ExchangeConfig getAlternateExchange();
-
- Map<String, Object> getArguments();
-
- long getReceivedMessageCount();
-
- int getMessageCount();
-
- long getQueueDepth();
-
- int getConsumerCount();
-
- int getConsumerCountHigh();
-
- int getBindingCount();
-
- int getBindingCountHigh();
-
- ConfigStore getConfigStore();
-
- long getMessageDequeueCount();
-
- long getTotalEnqueueSize();
-
- long getTotalDequeueSize();
-
- long getByteTxnEnqueues();
-
- long getByteTxnDequeues();
-
- long getMsgTxnEnqueues();
-
- long getMsgTxnDequeues();
-
- long getPersistentByteEnqueues();
-
- long getPersistentByteDequeues();
-
- long getPersistentMsgEnqueues();
-
- long getPersistentMsgDequeues();
-
- long getUnackedMessageCount();
-
- long getUnackedMessageCountHigh();
-
- void purge(long request) throws AMQException;
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java
deleted file mode 100644
index f958ef5350..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java
+++ /dev/null
@@ -1,123 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public final class QueueConfigType extends ConfigObjectType<QueueConfigType, QueueConfig>
-{
- private static final List<QueueProperty<?>> QUEUE_PROPERTIES = new ArrayList<QueueProperty<?>>();
-
- public static interface QueueProperty<S> extends ConfigProperty<QueueConfigType, QueueConfig, S>
- {
- }
-
- private abstract static class QueueReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S>
- {
- public QueueReadWriteProperty(String name)
- {
- super(name);
- QUEUE_PROPERTIES.add(this);
- }
- }
-
- private abstract static class QueueReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S>
- {
- public QueueReadOnlyProperty(String name)
- {
- super(name);
- QUEUE_PROPERTIES.add(this);
- }
- }
-
- public static final QueueReadOnlyProperty<VirtualHostConfig> VISTUAL_HOST_PROPERTY = new QueueReadOnlyProperty<VirtualHostConfig>("virtualHost")
- {
- public VirtualHostConfig getValue(QueueConfig object)
- {
- return object.getVirtualHost();
- }
- };
-
- public static final QueueReadOnlyProperty<String> NAME_PROPERTY = new QueueReadOnlyProperty<String>("name")
- {
- public String getValue(QueueConfig object)
- {
- return object.getName();
- }
- };
-
- public static final QueueReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new QueueReadOnlyProperty<Boolean>("autodelete")
- {
- public Boolean getValue(QueueConfig object)
- {
- return object.isAutoDelete();
- }
- };
-
- public static final QueueReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new QueueReadOnlyProperty<Boolean>("exclusive")
- {
- public Boolean getValue(QueueConfig object)
- {
- return object.isExclusive();
- }
- };
-
- public static final QueueReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new QueueReadOnlyProperty<ExchangeConfig>("alternateExchange")
- {
- public ExchangeConfig getValue(QueueConfig object)
- {
- return object.getAlternateExchange();
- }
- };
-
- public static final QueueReadOnlyProperty<Map<String,Object>> ARGUMENTS = new QueueReadOnlyProperty<Map<String,Object>>("arguments")
- {
- public Map<String,Object> getValue(QueueConfig object)
- {
- return object.getArguments();
- }
- };
-
-
- private static final QueueConfigType INSTANCE = new QueueConfigType();
-
- private QueueConfigType()
- {
- }
-
- public Collection<QueueProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(QUEUE_PROPERTIES);
- }
-
- public static QueueConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ 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 8f03383777..06691d8659 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
@@ -24,11 +24,11 @@ import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.AbstractConfiguration;
import java.util.List;
-public class QueueConfiguration extends ConfigurationPlugin
+public class QueueConfiguration extends AbstractConfiguration
{
private String _name;
private VirtualHostConfiguration _vHostConfig;
@@ -39,7 +39,7 @@ public class QueueConfiguration extends ConfigurationPlugin
_name = name;
CompositeConfiguration mungedConf = new CompositeConfiguration();
- mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + name));
+ mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + escapeTagName(name)));
mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues"));
setConfiguration("virtualhosts.virtualhost.queues.queue", mungedConf);
@@ -193,43 +193,4 @@ public class QueueConfiguration extends ConfigurationPlugin
{
return getBooleanValue("deadLetterQueues", _vHostConfig.isDeadLetterQueueEnabled());
}
-
- public static class QueueConfig extends ConfigurationPlugin
- {
- @Override
- public String[] getElementsProcessed()
- {
- return new String[]{"name"};
- }
-
- public String getName()
- {
- return getStringValue("name");
- }
-
-
- public void validateConfiguration() throws ConfigurationException
- {
- if (getConfig().isEmpty())
- {
- throw new ConfigurationException("Queue section cannot be empty.");
- }
-
- if (getName() == null)
- {
- throw new ConfigurationException("Queue section must have a 'name' element.");
- }
-
- }
-
-
- @Override
- public String formatToString()
- {
- return "Name:"+getName();
- }
-
-
- }
-
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java
index b96ddc56c6..963d019ec3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java
@@ -18,15 +18,11 @@
* under the License.
*
*/
-
package org.apache.qpid.server.configuration;
-public interface VirtualHostConfig extends ConfiguredObject<VirtualHostConfigType, VirtualHostConfig>
-{
- String getName();
-
- BrokerConfig getBroker();
-
- String getFederationTag();
+import org.apache.qpid.server.model.ConfiguredObject;
+public interface RecovererProvider
+{
+ ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type);
}
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
deleted file mode 100644
index f9e2d93cff..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ /dev/null
@@ -1,1031 +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;
-
-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;
-import org.apache.commons.configuration.ConfigurationFactory;
-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;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.signal.SignalHandlerTask;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-public class ServerConfiguration extends ConfigurationPlugin
-{
- protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class);
-
- // Default Configuration values
- public static final int DEFAULT_BUFFER_SIZE = 262144;
- public static final String DEFAULT_STATUS_UPDATES = "on";
- public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED";
-
- public static final int DEFAULT_FRAME_SIZE = 65536;
- public static final int DEFAULT_PORT = 5672;
- public static final int DEFAULT_SSL_PORT = 5671;
- 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";
- public static final String LIB_DIR = "lib";
- public static final String PLUGIN_DIR = "plugins";
- public static final String CACHE_DIR = "cache";
-
- private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>();
-
- 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>();
-
- // Configuration values to be read from the configuration file
- //todo Move all properties to static values to ensure system testing can be performed.
- 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";
- public static final String CONNECTOR_AMQP010ENABLED = "connector.amqp010enabled";
- public static final String CONNECTOR_AMQP091ENABLED = "connector.amqp091enabled";
- 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");
- envVarMap.put("QPID_SSLPORT", "connector.ssl.port");
- envVarMap.put("QPID_JMXPORT_REGISTRYSERVER", MGMT_JMXPORT_REGISTRYSERVER);
- envVarMap.put("QPID_JMXPORT_CONNECTORSERVER", MGMT_JMXPORT_CONNECTORSERVER);
- envVarMap.put("QPID_FRAMESIZE", "advanced.framesize");
- 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");
- envVarMap.put("QPID_MAXIMUMMESSAGECOUNT", "maximumMessageCount");
- envVarMap.put("QPID_MAXIMUMQUEUEDEPTH", "maximumQueueDepth");
- envVarMap.put("QPID_MAXIMUMMESSAGESIZE", "maximumMessageSize");
- envVarMap.put("QPID_MAXIMUMCHANNELCOUNT", "maximumChannelCount");
- envVarMap.put("QPID_MINIMUMALERTREPEATGAP", "minimumAlertRepeatGap");
- envVarMap.put("QPID_QUEUECAPACITY", "capacity");
- envVarMap.put("QPID_FLOWRESUMECAPACITY", "flowResumeCapacity");
- envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer");
- envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer");
- envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay");
- envVarMap.put("QPID_STATUS-UPDATES", "status-updates");
- }
-
- /**
- * Loads the given file and sets up the HUP signal handler.
- *
- * This will load the file and present the root level properties but will
- * not perform any virtualhost configuration.
- * <p>
- * To perform this {@link #initialise()} must be called.
- * <p>
- * 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
- * need to explicitly call {@link #initialise()} as this is done via the
- * {@link ApplicationRegistry#initialise()} method.
- *
- * @param configurationURL
- * @throws org.apache.commons.configuration.ConfigurationException
- */
- public ServerConfiguration(File configurationURL) throws ConfigurationException
- {
- this(parseConfig(configurationURL));
- _configFile = configurationURL;
-
- SignalHandlerTask hupReparseTask = new SignalHandlerTask()
- {
- public void handle()
- {
- try
- {
- reparseConfigFileSecuritySections();
- }
- catch (ConfigurationException e)
- {
- _logger.error("Could not reload configuration file security sections", e);
- }
- }
- };
-
- if(!hupReparseTask.register("HUP"))
- {
- _logger.info("Unable to register Signal HUP handler to reload security configuration.");
- _logger.info("Signal HUP not supported for this OS / JVM combination - " + SignalHandlerTask.getPlatformDescription());
- }
- }
-
- /**
- * Wraps the given Commons Configuration as a ServerConfiguration.
- *
- * Mainly used during testing and in locations where configuration is not
- * desired but the interface requires configuration.
- * <p>
- * If the given configuration has VirtualHost configuration then
- * {@link #initialise()} must be called to perform the required setup.
- * <p>
- * 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
- * need to explicitly call {@link #initialise()} as this is done via the
- * {@link ApplicationRegistry#initialise()} method.
- *
- * @param conf
- */
- public ServerConfiguration(Configuration conf)
- {
- setConfig(conf);
- }
-
- /**
- * Processes this configuration and setups any VirtualHosts defined in the
- * configuration.
- *
- * This has been separated from the constructor to allow the PluginManager
- * time to be created and provide plugins to the ConfigurationManager for
- * processing here.
- * <p>
- * Called by {@link ApplicationRegistry#initialise()}.
- * <p>
- * NOTE: A DEFAULT ApplicationRegistry must exist when using this method
- * or a new ApplicationRegistry will be created.
- *
- * @throws ConfigurationException
- */
- public void initialise() throws ConfigurationException
- {
- setConfiguration("", getConfig());
- setupVirtualHosts(getConfig());
- }
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // 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."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
-
- if (getListValue("security.jmx.principal-database").size() > 0)
- {
- String message = "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
-
- 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."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
-
- // QPID-3266. Tidy up housekeeping configuration option for scheduling frequency
- if (contains("housekeeping.expiredMessageCheckPeriod"))
- {
- String message = "Validation error : housekeeping/expiredMessageCheckPeriod must be replaced by housekeeping/checkPeriod."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- 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",
- "management.ssl.keystorePassword," +
- "connector.ssl.keystorePath",
- "connector.ssl.keystorePassword"})
- {
- if (contains(key))
- {
- final String deprecatedXpath = key.replaceAll("\\.", "/");
- final String preferredXpath = deprecatedXpath.replaceAll("keystore", "keyStore");
- _logger.warn("Validation warning: " + deprecatedXpath + " is deprecated and must be replaced by " + preferredXpath
- + (_configFile == null ? "" : " Configuration file : " + _configFile));
- }
- }
-
- // QPID-3739 certType was a misleading name.
- if (contains("connector.ssl.certType"))
- {
- _logger.warn("Validation warning: connector/ssl/certType is deprecated and must be replaced by connector/ssl/keyManagerFactoryAlgorithm"
- + (_configFile == null ? "" : " Configuration file : " + _configFile));
- }
- }
-
- /*
- * Modified to enforce virtualhosts configuration in external file or main file, but not
- * both, as a fix for QPID-2360 and QPID-2361.
- */
- @SuppressWarnings("unchecked")
- protected void setupVirtualHosts(Configuration conf) throws ConfigurationException
- {
- List<String> vhostFiles = (List) conf.getList("virtualhosts");
- Configuration vhostConfig = conf.subset("virtualhosts");
-
- // Only one configuration mechanism allowed
- if (!vhostFiles.isEmpty() && !vhostConfig.subset("virtualhost").isEmpty())
- {
- throw new ConfigurationException("Only one of external or embedded virtualhosts configuration allowed.");
- }
-
- // We can only have one vhosts XML file included
- if (vhostFiles.size() > 1)
- {
- throw new ConfigurationException("Only one external virtualhosts configuration file allowed, multiple filenames found.");
- }
-
- // Virtualhost configuration object
- Configuration vhostConfiguration = new HierarchicalConfiguration();
-
- // Load from embedded configuration if possible
- if (!vhostConfig.subset("virtualhost").isEmpty())
- {
- vhostConfiguration = vhostConfig;
- }
- else
- {
- // Load from the external configuration if possible
- for (String fileName : vhostFiles)
- {
- // Open the vhosts XML file and copy values from it to our config
- _vhostsFile = new File(fileName);
- if (!_vhostsFile.exists())
- {
- throw new ConfigurationException("Virtualhosts file does not exist");
- }
- vhostConfiguration = parseConfig(new File(fileName));
-
- // save the default virtualhost name
- String defaultVirtualHost = vhostConfiguration.getString("default");
- getConfig().setProperty("virtualhosts.default", defaultVirtualHost);
- }
- }
-
- // Now extract the virtual host names from the configuration object
- List hosts = vhostConfiguration.getList("virtualhost.name");
- for (int j = 0; j < hosts.size(); j++)
- {
- String name = (String) hosts.get(j);
-
- // Add the virtual hosts to the server configuration
- VirtualHostConfiguration virtualhost = new VirtualHostConfiguration(name, vhostConfiguration.subset("virtualhost." + name));
- _virtualHosts.put(virtualhost.getName(), virtualhost);
- }
- }
-
- private static void substituteEnvironmentVariables(Configuration conf)
- {
- for (Entry<String, String> var : envVarMap.entrySet())
- {
- String val = System.getenv(var.getKey());
- if (val != null)
- {
- conf.setProperty(var.getValue(), val);
- }
- }
- }
-
- private static Configuration parseConfig(File file) throws ConfigurationException
- {
- ConfigurationFactory factory = new ConfigurationFactory();
- factory.setConfigurationFileName(file.getAbsolutePath());
- Configuration conf = factory.getConfiguration();
-
- Iterator<?> keys = conf.getKeys();
- if (!keys.hasNext())
- {
- keys = null;
- conf = flatConfig(file);
- }
-
- substituteEnvironmentVariables(conf);
-
- return conf;
- }
-
- /**
- * Check the configuration file to see if status updates are enabled.
- *
- * @return true if status updates are enabled
- */
- public boolean getStatusUpdatesEnabled()
- {
- // Retrieve the setting from configuration but default to on.
- String value = getStringValue(STATUS_UPDATES, DEFAULT_STATUS_UPDATES);
-
- return value.equalsIgnoreCase("on");
- }
-
- /**
- * The currently defined {@see Locale} for this broker
- *
- * @return the configuration defined locale
- */
- public Locale getLocale()
- {
- String localeString = getStringValue(ADVANCED_LOCALE);
- // Expecting locale of format langauge_country_variant
-
- // If the configuration does not have a defined locale use the JVM default
- if (localeString == null)
- {
- return Locale.getDefault();
- }
-
- String[] parts = localeString.split("_");
-
- Locale locale;
- switch (parts.length)
- {
- case 1:
- locale = new Locale(localeString);
- break;
- case 2:
- locale = new Locale(parts[0], parts[1]);
- break;
- default:
- StringBuilder variant = new StringBuilder(parts[2]);
- // If we have a variant such as the Java doc suggests for Spanish
- // Traditional_WIN we may end up with more than 3 parts on a
- // split with '_'. So we should recombine the variant.
- if (parts.length > 3)
- {
- for (int index = 3; index < parts.length; index++)
- {
- variant.append('_').append(parts[index]);
- }
- }
-
- locale = new Locale(parts[0], parts[1], variant.toString());
- }
-
- return locale;
- }
-
- // Our configuration class needs to make the interpolate method
- // public so it can be called below from the config method.
- public static class MyConfiguration extends CompositeConfiguration
- {
- public String interpolate(String obj)
- {
- return super.interpolate(obj);
- }
- }
-
- public final static Configuration flatConfig(File file) throws ConfigurationException
- {
- // We have to override the interpolate methods so that
- // interpolation takes place across the entirety of the
- // composite configuration. Without doing this each
- // configuration object only interpolates variables defined
- // inside itself.
- final MyConfiguration conf = new MyConfiguration();
- conf.addConfiguration(new SystemConfiguration()
- {
- protected String interpolate(String o)
- {
- return conf.interpolate(o);
- }
- });
- conf.addConfiguration(new XMLConfiguration(file)
- {
- protected String interpolate(String o)
- {
- return conf.interpolate(o);
- }
- });
- return conf;
- }
-
- public String getConfigurationURL()
- {
- return _configFile == null ? "" : _configFile.getAbsolutePath();
- }
-
- public void reparseConfigFileSecuritySections() throws ConfigurationException
- {
- if (_configFile != null)
- {
- Configuration newConfig = parseConfig(_configFile);
- setConfiguration("", newConfig);
- ApplicationRegistry.getInstance().getSecurityManager().configureHostPlugins(this);
-
- // Reload virtualhosts from correct location
- Configuration newVhosts;
- if (_vhostsFile == null)
- {
- newVhosts = newConfig.subset("virtualhosts");
- }
- else
- {
- newVhosts = parseConfig(_vhostsFile);
- }
-
- VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry();
- for (String hostName : _virtualHosts.keySet())
- {
- VirtualHost vhost = vhostRegistry.getVirtualHost(hostName);
- Configuration vhostConfig = newVhosts.subset("virtualhost." + hostName);
- vhost.getConfiguration().setConfiguration("virtualhosts.virtualhost", vhostConfig);
- vhost.getSecurityManager().configureGlobalPlugins(this);
- vhost.getSecurityManager().configureHostPlugins(vhost.getConfiguration());
- }
-
- _logger.warn(SECURITY_CONFIG_RELOADED);
- }
- }
-
- public String getQpidWork()
- {
- if ( _qpidWork == null )
- {
- return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir"));
- }
- else
- {
- return _qpidWork;
- }
- }
-
- public String getQpidHome()
- {
- if ( _qpidHome == null )
- {
- return System.getProperty(QPID_HOME);
- }
- else
- {
- return _qpidHome;
- }
- }
-
- public void setJMXPortRegistryServer(int registryServerPort)
- {
- getConfig().setProperty(MGMT_JMXPORT_REGISTRYSERVER, registryServerPort);
- }
-
- public int getJMXPortRegistryServer()
- {
- return getIntValue(MGMT_JMXPORT_REGISTRYSERVER, DEFAULT_JMXPORT_REGISTRYSERVER);
- }
-
- public void setJMXPortConnectorServer(int connectorServerPort)
- {
- getConfig().setProperty(MGMT_JMXPORT_CONNECTORSERVER, connectorServerPort);
- }
-
- public int getJMXConnectorServerPort()
- {
- return getIntValue(MGMT_JMXPORT_CONNECTORSERVER, getJMXPortRegistryServer() + JMXPORT_CONNECTORSERVER_OFFSET);
- }
-
- public boolean getUseCustomRMISocketFactory()
- {
- return getBooleanValue(MGMT_CUSTOM_REGISTRY_SOCKET, true);
- }
-
- public void setUseCustomRMISocketFactory(boolean bool)
- {
- getConfig().setProperty(MGMT_CUSTOM_REGISTRY_SOCKET, bool);
- }
-
- public boolean getPlatformMbeanserver()
- {
- 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");
- }
-
- public VirtualHostConfiguration getVirtualHostConfig(String name)
- {
- return _virtualHosts.get(name);
- }
-
- public void setVirtualHostConfig(VirtualHostConfiguration config)
- {
- _virtualHosts.put(config.getName(), config);
- }
-
- public int getFrameSize()
- {
- return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE);
- }
-
- public boolean getSynchedClocks()
- {
- return getBooleanValue("advanced.synced-clocks");
- }
-
- public boolean getMsgAuth()
- {
- 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");
- return getStringValue("management.ssl.keyStorePath", fallback);
- }
-
- public boolean getManagementSSLEnabled()
- {
- return getBooleanValue("management.ssl.enabled", false);
- }
-
- public String getManagementKeyStorePassword()
- {
- final String fallback = getStringValue("management.ssl.keystorePassword");
- return getStringValue("management.ssl.keyStorePassword", fallback);
- }
-
- public boolean getQueueAutoRegister()
- {
- return getBooleanValue("queue.auto_register", true);
- }
-
- public boolean getJMXManagementEnabled()
- {
- return getBooleanValue("management.enabled", true);
- }
-
- public int getHeartBeatDelay()
- {
- return getIntValue("heartbeat.delay", 5);
- }
-
- public double getHeartBeatTimeout()
- {
- return getDoubleValue("heartbeat.timeoutFactor", 2.0);
- }
-
- public long getMaximumMessageAge()
- {
- return getLongValue("maximumMessageAge");
- }
-
- public long getMaximumMessageCount()
- {
- return getLongValue("maximumMessageCount");
- }
-
- public long getMaximumQueueDepth()
- {
- return getLongValue("maximumQueueDepth");
- }
-
- public long getMaximumMessageSize()
- {
- return getLongValue("maximumMessageSize");
- }
-
- public long getMinimumAlertRepeatGap()
- {
- return getLongValue("minimumAlertRepeatGap", DEFAULT_MINIMUM_ALERT_REPEAT_GAP);
- }
-
- public long getCapacity()
- {
- return getLongValue("capacity");
- }
-
- public long getFlowResumeCapacity()
- {
- return getLongValue("flowResumeCapacity", getCapacity());
- }
-
- public int getConnectorProcessors()
- {
- return getIntValue("connector.processors", 4);
- }
-
- public List getPorts()
- {
- return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT));
- }
-
- public List getPortExclude10()
- {
- return getListValue("connector.non10port");
- }
-
- public List getPortExclude010()
- {
- return getListValue("connector.non010port");
- }
-
- public List getPortExclude091()
- {
- return getListValue("connector.non091port");
- }
-
- public List getPortExclude09()
- {
- return getListValue("connector.non09port");
- }
-
- public List getPortExclude08()
- {
- 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);
- }
-
- public int getReceiveBufferSize()
- {
- return getIntValue("connector.socketReceiveBuffer", DEFAULT_BUFFER_SIZE);
- }
-
- public int getWriteBufferSize()
- {
- return getIntValue("connector.socketWriteBuffer", DEFAULT_BUFFER_SIZE);
- }
-
- public boolean getTcpNoDelay()
- {
- return getBooleanValue("connector.tcpNoDelay", true);
- }
-
- public boolean getEnableSSL()
- {
- return getBooleanValue("connector.ssl.enabled");
- }
-
- public boolean getSSLOnly()
- {
- return getBooleanValue("connector.ssl.sslOnly");
- }
-
- public List getSSLPorts()
- {
- return getListValue("connector.ssl.port", Collections.<Integer>singletonList(DEFAULT_SSL_PORT));
- }
-
- public String getConnectorKeyStorePath()
- {
- final String fallback = getStringValue("connector.ssl.keystorePath"); // pre-0.13 broker supported this name.
- return getStringValue("connector.ssl.keyStorePath", fallback);
- }
-
- public String getConnectorKeyStorePassword()
- {
- final String fallback = getStringValue("connector.ssl.keystorePassword"); // pre-0.13 brokers supported this name.
- return getStringValue("connector.ssl.keyStorePassword", fallback);
- }
-
- public String getConnectorKeyStoreType()
- {
- return getStringValue("connector.ssl.keyStoreType", "JKS");
- }
-
- public String getConnectorKeyManagerFactoryAlgorithm()
- {
- final String systemFallback = KeyManagerFactory.getDefaultAlgorithm();
- // deprecated, pre-0.17 brokers supported this name.
- final String fallback = getStringValue("connector.ssl.certType", systemFallback);
- 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");
- }
-
- public void setDefaultVirtualHost(String vhost)
- {
- getConfig().setProperty("virtualhosts.default", vhost);
- }
-
- public void setHousekeepingCheckPeriod(long value)
- {
- getConfig().setProperty("housekeeping.checkPeriod", value);
- }
-
- public long getHousekeepingCheckPeriod()
- {
- return getLongValue("housekeeping.checkPeriod", DEFAULT_HOUSEKEEPING_PERIOD);
- }
-
- public long getStatisticsSamplePeriod()
- {
- return getConfig().getLong("statistics.sample.period", 5000L);
- }
-
- public boolean isStatisticsGenerationBrokerEnabled()
- {
- return getConfig().getBoolean("statistics.generation.broker", false);
- }
-
- public boolean isStatisticsGenerationVirtualhostsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.virtualhosts", false);
- }
-
- public boolean isStatisticsGenerationConnectionsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.connections", false);
- }
-
- public long getStatisticsReportingPeriod()
- {
- return getConfig().getLong("statistics.reporting.period", 0L);
- }
-
- public boolean isStatisticsReportResetEnabled()
- {
- return getConfig().getBoolean("statistics.reporting.reset", false);
- }
-
- public int getMaxChannelCount()
- {
- return getIntValue("maximumChannelCount", 256);
- }
-
- /**
- * List of Broker features that have been disabled within configuration. Disabled
- * features won't be advertised to the clients on connection.
- *
- * @return list of disabled features, or empty list if no features are disabled.
- */
- public List<String> getDisabledFeatures()
- {
- final List<String> disabledFeatures = getListValue("disabledFeatures", Collections.emptyList());
- return disabledFeatures;
- }
-
- public boolean getManagementRightsInferAllAccess()
- {
- return getBooleanValue("management.managementRightsInferAllAccess", true);
- }
-
- public int getMaxDeliveryCount()
- {
- return getConfig().getInt("maximumDeliveryCount", 0);
- }
-
- /**
- * Check if dead letter queue delivery is enabled, defaults to disabled if not set.
- */
- public boolean isDeadLetterQueueEnabled()
- {
- return getConfig().getBoolean("deadLetterQueues", false);
- }
-
- /**
- * String to affix to end of queue name when generating an alternate exchange for DLQ purposes.
- */
- public String getDeadLetterExchangeSuffix()
- {
- return getConfig().getString("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
- }
-
- /**
- * String to affix to end of queue name when generating a queue for DLQ purposes.
- */
- public String getDeadLetterQueueSuffix()
- {
- return getConfig().getString("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
- }
-
- public boolean isAmqp10enabled()
- {
- return getConfig().getBoolean(CONNECTOR_AMQP10ENABLED, true);
- }
-
- public boolean isAmqp010enabled()
- {
- return getConfig().getBoolean(CONNECTOR_AMQP010ENABLED, true);
- }
-
- public boolean isAmqp091enabled()
- {
- return getConfig().getBoolean(CONNECTOR_AMQP091ENABLED, true);
- }
-
- public boolean isAmqp09enabled()
- {
- return getConfig().getBoolean(CONNECTOR_AMQP09ENABLED, true);
- }
-
- public boolean isAmqp08enabled()
- {
- return getConfig().getBoolean(CONNECTOR_AMQP08ENABLED, true);
- }
-
- /**
- * Returns the configured default reply to an unsupported AMQP protocol initiation, or null if there is none
- */
- public AmqpProtocolVersion getDefaultSupportedProtocolReply()
- {
- String reply = getConfig().getString(CONNECTOR_AMQP_SUPPORTED_REPLY, null);
-
- 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
deleted file mode 100644
index 51dcc38c47..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.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.configuration;
-
-import java.net.InetSocketAddress;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-
-public class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
-{
- private final ServerConfiguration _serverConfig;
- private final String _transport;
- private InetSocketAddress _address;
-
- public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig,
- final InetSocketAddress address,
- final String transport)
- {
- _serverConfig = serverConfig;
- _address = address;
- _transport = transport;
- }
-
- public Boolean getTcpNoDelay()
- {
- return _serverConfig.getTcpNoDelay();
- }
-
- public Integer getSendBufferSize()
- {
- return _serverConfig.getWriteBufferSize();
- }
-
- public Integer getReceiveBufferSize()
- {
- return _serverConfig.getReceiveBufferSize();
- }
-
- public Integer getPort()
- {
- return _address.getPort();
- }
-
- public String getHost()
- {
- return _address.getHostName();
- }
-
- public String getTransport()
- {
- return _transport;
- }
-
- public Integer getConnectorProcessors()
- {
- return _serverConfig.getConnectorProcessors();
- }
-
- public InetSocketAddress getAddress()
- {
- 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/SessionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java
deleted file mode 100644
index 1685cfab60..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java
+++ /dev/null
@@ -1,137 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class SessionConfigType extends ConfigObjectType<SessionConfigType, SessionConfig>
-{
- private static final List<SessionProperty<?>> SESSION_PROPERTIES = new ArrayList<SessionProperty<?>>();
-
- public static interface SessionProperty<S> extends ConfigProperty<SessionConfigType, SessionConfig, S>
- {
- }
-
- private abstract static class SessionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S>
- {
- public SessionReadWriteProperty(String name)
- {
- super(name);
- SESSION_PROPERTIES.add(this);
- }
- }
-
- private abstract static class SessionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S>
- {
- public SessionReadOnlyProperty(String name)
- {
- super(name);
- SESSION_PROPERTIES.add(this);
- }
- }
-
- public static final SessionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new SessionReadOnlyProperty<VirtualHostConfig>("virtualHost")
- {
- public VirtualHostConfig getValue(SessionConfig object)
- {
- return object.getVirtualHost();
- }
- };
-
- public static final SessionReadOnlyProperty<String> NAME_PROPERTY = new SessionReadOnlyProperty<String>("name")
- {
- public String getValue(SessionConfig object)
- {
- return object.getSessionName();
- }
- };
-
- public static final SessionReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new SessionReadOnlyProperty<Integer>("channelId")
- {
- public Integer getValue(SessionConfig object)
- {
- return object.getChannel();
- }
- };
-
- public static final SessionReadOnlyProperty<ConnectionConfig> CONNECTION_PROPERTY = new SessionReadOnlyProperty<ConnectionConfig>("connection")
- {
- public ConnectionConfig getValue(SessionConfig object)
- {
- return object.getConnectionConfig();
- }
- };
-
- public static final SessionReadOnlyProperty<Boolean> ATTACHED_PROPERTY = new SessionReadOnlyProperty<Boolean>("attached")
- {
- public Boolean getValue(SessionConfig object)
- {
- return object.isAttached();
- }
- };
-
- public static final SessionReadOnlyProperty<Long> DETACHED_LIFESPAN_PROPERTY = new SessionReadOnlyProperty<Long>("detachedLifespan")
- {
- public Long getValue(SessionConfig object)
- {
- return object.getDetachedLifespan();
- }
- };
-
- public static final SessionReadOnlyProperty<Long> EXPIRE_TIME_PROPERTY = new SessionReadOnlyProperty<Long>("expireTime")
- {
- public Long getValue(SessionConfig object)
- {
- return object.getExpiryTime();
- }
- };
-
- public static final SessionReadOnlyProperty<Long> MAX_CLIENT_RATE_PROPERTY = new SessionReadOnlyProperty<Long>("maxClientRate")
- {
- public Long getValue(SessionConfig object)
- {
- return object.getMaxClientRate();
- }
- };
-
- private static final SessionConfigType INSTANCE = new SessionConfigType();
-
- private SessionConfigType()
- {
- }
-
- public Collection<SessionProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(SESSION_PROPERTIES);
- }
-
- public static SessionConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java
deleted file mode 100644
index b101d70553..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.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;
-
-import java.util.Map;
-
-
-public interface SubscriptionConfig extends ConfiguredObject<SubscriptionConfigType, SubscriptionConfig>
-{
-
- SessionConfig getSessionConfig();
-
- QueueConfig getQueue();
-
- String getName();
-
- Map<String, Object> getArguments();
-
- String getCreditMode();
-
- boolean isBrowsing();
-
- boolean isExclusive();
-
- boolean isExplicitAcknowledge();
-
- Long getDelivered();
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java
deleted file mode 100644
index 7b7848dd87..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java
+++ /dev/null
@@ -1,140 +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;
-
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public final class SubscriptionConfigType extends ConfigObjectType<SubscriptionConfigType, SubscriptionConfig>
-{
- private static final List<SubscriptionProperty<?>> SUBSCRIPTION_PROPERTIES = new ArrayList<SubscriptionProperty<?>>();
-
- public static interface SubscriptionProperty<S> extends ConfigProperty<SubscriptionConfigType, SubscriptionConfig, S>
- {
- }
-
- private abstract static class SubscriptionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S>
- {
- public SubscriptionReadWriteProperty(String name)
- {
- super(name);
- SUBSCRIPTION_PROPERTIES.add(this);
- }
- }
-
- private abstract static class SubscriptionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S>
- {
- public SubscriptionReadOnlyProperty(String name)
- {
- super(name);
- SUBSCRIPTION_PROPERTIES.add(this);
- }
- }
-
- public static final SubscriptionReadOnlyProperty<SessionConfig> SESSION_PROPERTY = new SubscriptionReadOnlyProperty<SessionConfig>("session")
- {
- public SessionConfig getValue(SubscriptionConfig object)
- {
- return object.getSessionConfig();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new SubscriptionReadOnlyProperty<QueueConfig>("queue")
- {
- public QueueConfig getValue(SubscriptionConfig object)
- {
- return object.getQueue();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<String> NAME_PROPERTY = new SubscriptionReadOnlyProperty<String>("name")
- {
- public String getValue(SubscriptionConfig object)
- {
- return object.getName();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<Map<String,Object>> ARGUMENTS = new SubscriptionReadOnlyProperty<Map<String,Object>>("arguments")
- {
- public Map<String,Object> getValue(SubscriptionConfig object)
- {
- return object.getArguments();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<String> CREDIT_MODE_PROPERTY = new SubscriptionReadOnlyProperty<String>("creditMode")
- {
- public String getValue(SubscriptionConfig object)
- {
- return object.getCreditMode();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<Boolean> BROWSING_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("browsing")
- {
- public Boolean getValue(SubscriptionConfig object)
- {
- return object.isBrowsing();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("exclusive")
- {
- public Boolean getValue(SubscriptionConfig object)
- {
- return object.isExclusive();
- }
- };
-
- public static final SubscriptionReadOnlyProperty<Boolean> EXPLICIT_ACK_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("explicitAck")
- {
- public Boolean getValue(SubscriptionConfig object)
- {
- return object.isExplicitAcknowledge();
- }
- };
-
- private static final SubscriptionConfigType INSTANCE = new SubscriptionConfigType();
-
- private SubscriptionConfigType()
- {
- }
-
- public Collection<SubscriptionProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(SUBSCRIPTION_PROPERTIES);
- }
-
-
- public static SubscriptionConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-} \ No newline at end of file
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
deleted file mode 100644
index 80c2e8b2f1..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java
+++ /dev/null
@@ -1,137 +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;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class SystemConfigImpl implements SystemConfig
-{
- private static final String OS_NAME = System.getProperty("os.name");
- private static final String OS_ARCH = System.getProperty("os.arch");
- private static final String OS_VERSION = System.getProperty("os.version");
-
- private final UUID _qmfId;
- private String _name;
-
- private final String _host;
-
- private final Map<UUID, BrokerConfig> _brokers = new ConcurrentHashMap<UUID, BrokerConfig>();
-
- private final long _createTime = System.currentTimeMillis();
- private final ConfigStore _store;
-
- public SystemConfigImpl(ConfigStore store)
- {
- this(store.createId(), store);
- }
-
- public SystemConfigImpl(UUID qmfId, ConfigStore store)
- {
- _qmfId = qmfId;
- _store = store;
- String host;
- try
- {
- InetAddress addr = InetAddress.getLocalHost();
- host = addr.getHostName();
- }
- catch (UnknownHostException e)
- {
- host="localhost";
- }
- _host = host;
- }
-
- public String getName()
- {
- return _name;
- }
-
- public String getOperatingSystemName()
- {
- return OS_NAME;
- }
-
- public String getNodeName()
- {
- return _host;
- }
-
- public String getOSRelease()
- {
- return OS_VERSION;
- }
-
- public String getOSVersion()
- {
- return "";
- }
-
- public String getOSArchitecture()
- {
- return OS_ARCH;
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public SystemConfigType getConfigType()
- {
- return SystemConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return null;
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public void addBroker(final BrokerConfig broker)
- {
- broker.setSystem(this);
- _store.addConfiguredObject(broker);
- _brokers.put(broker.getQMFId(), broker);
- }
-
- public void removeBroker(final BrokerConfig broker)
- {
- _brokers.remove(broker.getQMFId());
- _store.removeConfiguredObject(broker);
- }
-
- public long getCreateTime()
- {
- return _createTime;
- }
-
-}
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
deleted file mode 100644
index 4a383cce7a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java
+++ /dev/null
@@ -1,132 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
-public final class SystemConfigType extends ConfigObjectType<SystemConfigType, SystemConfig>
-{
- private static final List<SystemProperty<?>> SYSTEM_PROPERTIES = new ArrayList<SystemProperty<?>>();
-
- public static interface SystemProperty<S> extends ConfigProperty<SystemConfigType, SystemConfig, S>
- {
- }
-
- private abstract static class SystemReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S>
- {
- public SystemReadWriteProperty(String name)
- {
- super(name);
- SYSTEM_PROPERTIES.add(this);
- }
- }
-
- private abstract static class SystemReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S>
- {
- public SystemReadOnlyProperty(String name)
- {
- super(name);
- SYSTEM_PROPERTIES.add(this);
- }
- }
-
- public static final SystemReadOnlyProperty<String> NAME_PROPERTY = new SystemReadOnlyProperty<String>("name")
- {
- public String getValue(SystemConfig object)
- {
- return object.getName();
- }
- };
-
- public static final SystemReadOnlyProperty<UUID> ID_PROPERTY = new SystemReadOnlyProperty<UUID>("id")
- {
- public UUID getValue(SystemConfig object)
- {
- return object.getQMFId();
- }
- };
-
- public static final SystemReadOnlyProperty<String> OS_NAME_PROPERTY = new SystemReadOnlyProperty<String>("osName")
- {
- public String getValue(SystemConfig object)
- {
- return object.getOperatingSystemName();
- }
- };
-
- public static final SystemReadOnlyProperty<String> NODE_NAME_PROPERTY = new SystemReadOnlyProperty<String>("nodeName")
- {
- public String getValue(SystemConfig object)
- {
- return object.getNodeName();
- }
- };
-
- public static final SystemReadOnlyProperty<String> RELEASE_PROPERTY = new SystemReadOnlyProperty<String>("release")
- {
- public String getValue(SystemConfig object)
- {
- return object.getOSRelease();
- }
- };
-
- public static final SystemReadOnlyProperty<String> VERSION_PROPERTY = new SystemReadOnlyProperty<String>("version")
- {
- public String getValue(SystemConfig object)
- {
- return object.getOSVersion();
- }
- };
-
- public static final SystemReadOnlyProperty<String> MACHINE_PROPERTY = new SystemReadOnlyProperty<String>("machine")
- {
- public String getValue(SystemConfig object)
- {
- return object.getOSArchitecture();
- }
- };
-
- private static final SystemConfigType INSTANCE = new SystemConfigType();
-
- private SystemConfigType()
- {
- }
-
- public Collection<SystemProperty<?>> getProperties()
- {
- return Collections.unmodifiableList(SYSTEM_PROPERTIES);
- }
-
-
-
- public static SystemConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-
-}
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
deleted file mode 100644
index aaa1766489..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java
+++ /dev/null
@@ -1,78 +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;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-
-public class TopicConfig extends ConfigurationPlugin
-{
- public TopicConfig()
- {
- setConfig(new PropertiesConfiguration());
- }
-
- @Override
- public String[] getElementsProcessed()
- {
- return new String[]{"name", "subscriptionName"};
- }
-
- public String getName()
- {
- // If we don't have a specific topic then this config is for all topics.
- return getStringValue("name", "#");
- }
-
- public String getSubscriptionName()
- {
- return getStringValue("subscriptionName");
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
- if (getConfig().isEmpty())
- {
- throw new ConfigurationException("Topic section cannot be empty.");
- }
-
- if (getStringValue("name") == null && getSubscriptionName() == null)
- {
- throw new ConfigurationException("Topic section must have a 'name' or 'subscriptionName' element.");
- }
-
- }
-
-
- @Override
- public String formatToString()
- {
- String response = "Topic:"+getName();
- if (getSubscriptionName() != null)
- {
- response += ", SubscriptionName:"+getSubscriptionName();
- }
-
- return response;
- }
-} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java
deleted file mode 100644
index feafd3de1d..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java
+++ /dev/null
@@ -1,270 +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;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.exchange.TopicExchange;
-import org.apache.qpid.server.queue.AMQQueue;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-public class TopicConfiguration extends ConfigurationPlugin implements ExchangeConfigurationPlugin
-{
- public static final ConfigurationPluginFactory FACTORY = new TopicConfigurationFactory();
-
- private static final String VIRTUALHOSTS_VIRTUALHOST_TOPICS = "virtualhosts.virtualhost.topics";
-
- public static class TopicConfigurationFactory implements ConfigurationPluginFactory
- {
-
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- TopicConfiguration topicsConfig = new TopicConfiguration();
- topicsConfig.setConfiguration(path, config);
- return topicsConfig;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList(VIRTUALHOSTS_VIRTUALHOST_TOPICS);
- }
- }
-
- private Map<String, TopicConfig> _topics = new HashMap<String, TopicConfig>();
- private Map<String, Map<String, TopicConfig>> _subscriptions = new HashMap<String, Map<String, TopicConfig>>();
-
- public String[] getElementsProcessed()
- {
- return new String[]{"topic"};
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- if (getConfig().isEmpty())
- {
- throw new ConfigurationException("Topics section cannot be empty.");
- }
-
- int topics = getConfig().getList("topic.name").size() +
- getConfig().getList("topic.subscriptionName").size();
-
- for (int index = 0; index < topics; index++)
- {
- Configuration topicSubset = getConfig().subset("topic(" + index + ")");
-
- // This will occur when we have a subscriptionName that is bound to a
- // topic.
- if (topicSubset.isEmpty())
- {
- break;
- }
-
- TopicConfig topic = new TopicConfig();
-
- topic.setConfiguration(VIRTUALHOSTS_VIRTUALHOST_TOPICS + ".topic", topicSubset );
-
- String name = getConfig().getString("topic(" + index + ").name");
- String subscriptionName = getConfig().getString("topic(" + index + ").subscriptionName");
-
- // Record config if subscriptionName is there
- if (subscriptionName != null)
- {
- processSubscription(subscriptionName, topic);
- }
- else
- {
- // Otherwise record config as topic if we have the name
- if (name != null)
- {
- processTopic(name, topic);
- }
- }
- }
- }
-
- /**
- * @param name
- * @param topic
- *
- * @throws org.apache.commons.configuration.ConfigurationException
- *
- */
- private void processTopic(String name, TopicConfig topic) throws ConfigurationException
- {
- if (_topics.containsKey(name))
- {
- throw new ConfigurationException("Topics section cannot contain two entries for the same topic.");
- }
- else
- {
- _topics.put(name, topic);
- }
- }
-
-
- private void processSubscription(String name, TopicConfig topic) throws ConfigurationException
- {
- Map<String,TopicConfig> topics;
- if (_subscriptions.containsKey(name))
- {
- topics = _subscriptions.get(name);
-
- if (topics.containsKey(topic.getName()))
- {
- throw new ConfigurationException("Subcription cannot contain two entries for the same topic.");
- }
- }
- else
- {
- topics = new HashMap<String,TopicConfig>();
- }
-
- topics.put(topic.getName(),topic);
- _subscriptions.put(name, topics);
-
- }
-
- @Override
- public String formatToString()
- {
- return "Topics:" + _topics + ", Subscriptions:" + _subscriptions;
- }
-
- /**
- * This processes the given queue and apply configuration in the following
- * order:
- *
- * Global Topic Values -> Topic Values -> Subscription Values
- *
- * @param queue
- *
- * @return
- */
- public ConfigurationPlugin getConfiguration(AMQQueue queue)
- {
- //Create config with global topic configuration
- TopicConfig config = new TopicConfig();
-
- // Add global topic configuration
- config.addConfiguration(this);
-
- // Process Topic Bindings as these are more generic than subscriptions
- List<TopicConfig> boundToTopics = new LinkedList<TopicConfig>();
-
- //Merge the configuration in the order that they are bound
- for (Binding binding : queue.getBindings())
- {
- if (binding.getExchange().getType().equals(TopicExchange.TYPE))
- {
- // Identify topic for the binding key
- TopicConfig topicConfig = getTopicConfigForRoutingKey(binding.getBindingKey());
- if (topicConfig != null)
- {
- boundToTopics.add(topicConfig);
- }
- }
- }
-
- // If the Queue is bound to a number of topics then only use the global
- // topic configuration.
- // todo - What does it mean in terms of configuration to be bound to a
- // number of topics? Do we try and merge?
- // YES - right thing to do would be to merge from generic to specific.
- // Means we need to be able to get an ordered list of topics for this
- // binding.
- if (boundToTopics.size() == 1)
- {
- config.addConfiguration(boundToTopics.get(0));
- }
-
- // If we have a subscription then attempt to look it up.
- String subscriptionName = queue.getName();
-
- // Apply subscription configurations
- if (_subscriptions.containsKey(subscriptionName))
- {
-
- //Get all the Configuration that this subscription is bound to.
- Map<String, TopicConfig> topics = _subscriptions.get(subscriptionName);
-
- TopicConfig subscriptionSpecificConfig = null;
-
- // See if we have a TopicConfig in topics for a topic we are bound to.
- for (Binding binding : queue.getBindings())
- {
- if (binding.getExchange().getType().equals(TopicExchange.TYPE))
- {
- //todo - What does it mean to have multiple matches?
- // Take the first match we get
- if (subscriptionSpecificConfig == null)
- {
- // lookup the binding to see if we have a match in the subscription configs
- subscriptionSpecificConfig = topics.get(binding.getBindingKey());
- }
- }
- }
-
- //todo we don't account for wild cards here. only explicit matching and all subscriptions
- if (subscriptionSpecificConfig == null)
- {
- // lookup the binding to see if we have a match in the subscription configs
- subscriptionSpecificConfig = topics.get("#");
- }
-
- // Apply subscription specific config.
- if (subscriptionSpecificConfig != null)
- {
- config.addConfiguration(subscriptionSpecificConfig);
- }
- }
- return config;
- }
-
- /**
- * This method should perform the same heuristics as the TopicExchange
- * to attempt to identify a piece of configuration for the give routingKey.
- *
- * i.e. If we have 'stocks.*' defined in the config
- * and we bind 'stocks.appl' then we should return the 'stocks.*'
- * configuration.
- *
- * @param routingkey the key to lookup
- *
- * @return the TopicConfig if found.
- */
- private TopicConfig getTopicConfigForRoutingKey(String routingkey)
- {
- //todo actually perform TopicExchange style lookup not just straight
- // lookup as we are just now.
- return _topics.get(routingkey);
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java
deleted file mode 100644
index 16e08e3934..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java
+++ /dev/null
@@ -1,99 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public class VirtualHostConfigType extends ConfigObjectType<VirtualHostConfigType, VirtualHostConfig>
-{
- private static final List<VirtualHostProperty<?>> VIRTUAL_HOST_PROPERTIES = new ArrayList<VirtualHostProperty<?>>();
- private static final VirtualHostConfigType INSTANCE = new VirtualHostConfigType();
-public static interface VirtualHostProperty<S> extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, S>
- {
- }
-
- private abstract static class VirtualHostReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S>
- {
- public VirtualHostReadWriteProperty(String name)
- {
- super(name);
- VIRTUAL_HOST_PROPERTIES.add(this);
- }
- }
-
- private abstract static class VirtualHostReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S>
- {
- public VirtualHostReadOnlyProperty(String name)
- {
- super(name);
- VIRTUAL_HOST_PROPERTIES.add(this);
- }
- }
-
-
- public static final VirtualHostReadOnlyProperty<String> NAME_PROPERTY = new VirtualHostReadOnlyProperty<String>("name")
- {
- public String getValue(VirtualHostConfig object)
- {
- return object.getName();
- }
- };
-
-
- public static final VirtualHostReadOnlyProperty<BrokerConfig> BROKER_PROPERTY = new VirtualHostReadOnlyProperty<BrokerConfig>("broker")
- {
- public BrokerConfig getValue(VirtualHostConfig object)
- {
- return object.getBroker();
- }
- };
-
- public static final VirtualHostReadOnlyProperty<String> FEDERATION_TAG_PROPERTY = new VirtualHostReadOnlyProperty<String>("federationTag")
- {
- public String getValue(VirtualHostConfig object)
- {
- return object.getFederationTag();
- }
- };
-
-
-
- public Collection<? extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, ?>> getProperties()
- {
- return Collections.unmodifiableList(VIRTUAL_HOST_PROPERTIES);
- }
-
-
- private VirtualHostConfigType()
- {
- }
-
- public static VirtualHostConfigType getInstance()
- {
- return INSTANCE;
- }
-
-
-}
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 e557085631..eada676b65 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
@@ -23,35 +23,66 @@ package org.apache.qpid.server.configuration;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.binding.Binding;
-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.configuration.plugins.AbstractConfiguration;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.store.MemoryMessageStore;
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-public class VirtualHostConfiguration extends ConfigurationPlugin
+public class VirtualHostConfiguration extends AbstractConfiguration
{
private final String _name;
private final Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>();
private final Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>();
+ private final Broker _broker;
+ private final long _defaultHouseKeepingCheckPeriod;
- public VirtualHostConfiguration(String name, Configuration config) throws ConfigurationException
+ public VirtualHostConfiguration(String name, Configuration config, Broker broker) throws ConfigurationException
{
_name = name;
+ _broker = broker;
+
+ // store value of this attribute for running life of virtual host since updating of this value has no run-time effect
+ _defaultHouseKeepingCheckPeriod = ((Number)_broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).longValue();
setConfiguration(config);
}
+ public VirtualHostConfiguration(String name, File configurationFile, Broker broker) throws ConfigurationException
+ {
+ this(name, loadConfiguration(name, configurationFile), broker);
+ }
+
+ private static Configuration loadConfiguration(String name, File configurationFile) throws ConfigurationException
+ {
+ Configuration configuration = null;
+ if (configurationFile == null)
+ {
+ throw new IllegalConfigurationException("Virtualhost configuration file must be supplied!");
+ }
+ else
+ {
+ Configuration virtualHostConfig = XmlConfigurationUtilities.parseConfig(configurationFile, null);
+
+ // check if it is an old virtual host configuration file which has an element of the same name as virtual host
+ Configuration config = virtualHostConfig.subset("virtualhost." + XmlConfigurationUtilities.escapeTagName(name));
+ if (config.isEmpty())
+ {
+ // assume it is a new configuration which does not have an element of the same name as the virtual host
+ configuration = virtualHostConfig;
+ }
+ else
+ {
+ configuration = config;
+ }
+ }
+ return configuration;
+ }
+
/**
* Apply the given configuration to this VirtualHostConfiguration
*
@@ -89,12 +120,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
public long getHousekeepingCheckPeriod()
{
- return getLongValue("housekeeping.checkPeriod", ApplicationRegistry.getInstance().getConfiguration().getHousekeepingCheckPeriod());
- }
-
- public List getCustomExchanges()
- {
- return getListValue("custom-exchanges.class-name");
+ return getLongValue("housekeeping.checkPeriod", _defaultHouseKeepingCheckPeriod);
}
public Configuration getStoreConfiguration()
@@ -149,138 +175,39 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
}
}
- public ConfigurationPlugin getQueueConfiguration(AMQQueue queue)
- {
- VirtualHostConfiguration hostConfig = queue.getVirtualHost().getConfiguration();
-
- // First check if we have a named queue configuration (the easy case)
- if (Arrays.asList(hostConfig.getQueueNames()).contains(queue.getName()))
- {
- return null;
- }
-
- // We don't have an explicit queue config we must find out what we need.
- ArrayList<Binding> bindings = new ArrayList<Binding>(queue.getBindings());
-
- List<AMQShortString> exchangeClasses = new ArrayList<AMQShortString>(bindings.size());
-
- //Remove default exchange
- for (int index = 0; index < bindings.size(); index++)
- {
- // Ignore the DEFAULT Exchange binding
- if (bindings.get(index).getExchange().getNameShortString().equals(ExchangeDefaults.DEFAULT_EXCHANGE_NAME))
- {
- bindings.remove(index);
- }
- else
- {
- exchangeClasses.add(bindings.get(index).getExchange().getType().getName());
-
- if (exchangeClasses.size() > 1)
- {
- // If we have more than 1 class of exchange then we can only use the global queue configuration.
- // and this will be returned from the default getQueueConfiguration
- return null;
- }
- }
- }
-
- // If we are just bound the the default exchange then use the default.
- if (bindings.isEmpty())
- {
- return null;
- }
-
- // If we are bound to only one type of exchange then we are going
- // to have to resolve the configuration for that exchange.
-
- String exchangeName = bindings.get(0).getExchange().getType().getName().toString();
-
- // Lookup a Configuration handler for this Exchange.
-
- // Build the expected class name. <Exchangename>sConfiguration
- // i.e. TopicConfiguration or HeadersConfiguration
- String exchangeClass = "org.apache.qpid.server.configuration."
- + exchangeName.substring(0, 1).toUpperCase()
- + exchangeName.substring(1) + "Configuration";
-
- ExchangeConfigurationPlugin exchangeConfiguration
- = (ExchangeConfigurationPlugin) queue.getVirtualHost().getConfiguration().getConfiguration(exchangeClass);
-
- // now need to perform the queue-topic-topics-queues magic.
- // So make a new ConfigurationObject that will hold all the configuration for this queue.
- ConfigurationPlugin queueConfig = new QueueConfiguration.QueueConfig();
-
- // Initialise the queue with any Global values we may have
- PropertiesConfiguration newQueueConfig = new PropertiesConfiguration();
- newQueueConfig.setProperty("name", queue.getName());
-
- try
- {
- //Set the queue name
- CompositeConfiguration mungedConf = new CompositeConfiguration();
- //Set the queue name
- mungedConf.addConfiguration(newQueueConfig);
- //Set the global queue configuration
- mungedConf.addConfiguration(getConfig().subset("queues"));
-
- // Set configuration
- queueConfig.setConfiguration("virtualhosts.virtualhost.queues", mungedConf);
- }
- catch (ConfigurationException e)
- {
- // This will not occur as queues only require a name.
- _logger.error("QueueConfiguration requirements have changed.");
- }
-
- // Merge any configuration the Exchange wishes to apply
- if (exchangeConfiguration != null)
- {
- queueConfig.addConfiguration(exchangeConfiguration.getConfiguration(queue));
- }
-
- //Finally merge in any specific queue configuration we have.
- if (_queues.containsKey(queue.getName()))
- {
- queueConfig.addConfiguration(_queues.get(queue.getName()));
- }
-
- return queueConfig;
- }
-
public int getMaximumMessageAge()
{
- return getIntValue("queues.maximumMessageAge");
+ return getIntValue("queues.maximumMessageAge", getBrokerAttributeAsInt(Broker.ALERT_THRESHOLD_MESSAGE_AGE));
}
public Long getMaximumQueueDepth()
{
- return getLongValue("queues.maximumQueueDepth");
+ return getLongValue("queues.maximumQueueDepth", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_QUEUE_DEPTH));
}
public Long getMaximumMessageSize()
{
- return getLongValue("queues.maximumMessageSize");
+ return getLongValue("queues.maximumMessageSize", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_SIZE));
}
public Long getMaximumMessageCount()
{
- return getLongValue("queues.maximumMessageCount");
+ return getLongValue("queues.maximumMessageCount", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_COUNT));
}
public Long getMinimumAlertRepeatGap()
{
- return getLongValue("queues.minimumAlertRepeatGap", ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap());
+ return getLongValue("queues.minimumAlertRepeatGap", getBrokerAttributeAsLong(Broker.ALERT_REPEAT_GAP));
}
public long getCapacity()
{
- return getLongValue("queues.capacity");
+ return getLongValue("queues.capacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_SIZE_BYTES));
}
public long getFlowResumeCapacity()
{
- return getLongValue("queues.flowResumeCapacity", getCapacity());
+ return getLongValue("queues.flowResumeCapacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES));
}
public String[] getElementsProcessed()
@@ -336,7 +263,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
public int getMaxDeliveryCount()
{
- return getIntValue("queues.maximumDeliveryCount", ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount());
+ return getIntValue("queues.maximumDeliveryCount", getBrokerAttributeAsInt(Broker.MAXIMUM_DELIVERY_ATTEMPTS));
}
/**
@@ -344,7 +271,25 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
*/
public boolean isDeadLetterQueueEnabled()
{
- return getBooleanValue("queues.deadLetterQueues", ApplicationRegistry.getInstance().getConfiguration().isDeadLetterQueueEnabled());
+ return getBooleanValue("queues.deadLetterQueues", getBrokerAttributeAsBoolean(Broker.DEAD_LETTER_QUEUE_ENABLED));
+ }
+
+ private long getBrokerAttributeAsLong(String name)
+ {
+ Number brokerValue = (Number)_broker.getAttribute(name);
+ return brokerValue == null? 0 : brokerValue.longValue();
+ }
+
+ private int getBrokerAttributeAsInt(String name)
+ {
+ Number brokerValue = (Number)_broker.getAttribute(name);
+ return brokerValue == null? 0 : brokerValue.intValue();
+ }
+
+ private boolean getBrokerAttributeAsBoolean(String name)
+ {
+ Boolean brokerValue = (Boolean)_broker.getAttribute(name);
+ return brokerValue == null? false : brokerValue.booleanValue();
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java
new file mode 100644
index 0000000000..c0cff2c109
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.ConfigurationFactory;
+import org.apache.commons.configuration.SystemConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+
+public class XmlConfigurationUtilities
+{
+
+ // Our configuration class needs to make the interpolate method
+ // public so it can be called below from the config method.
+ public static class MyConfiguration extends CompositeConfiguration
+ {
+ public String interpolate(String obj)
+ {
+ return super.interpolate(obj);
+ }
+ }
+
+ public static Configuration parseConfig(File file, Map<String, String> envVarMap) throws ConfigurationException
+ {
+ ConfigurationFactory factory = new ConfigurationFactory();
+ factory.setConfigurationFileName(file.getAbsolutePath());
+ Configuration conf = factory.getConfiguration();
+
+ Iterator<?> keys = conf.getKeys();
+ if (!keys.hasNext())
+ {
+ keys = null;
+ conf = flatConfig(file);
+ }
+
+ XmlConfigurationUtilities.substituteEnvironmentVariables(conf, envVarMap);
+ return conf;
+ }
+
+ public final static Configuration flatConfig(File file) throws ConfigurationException
+ {
+ // We have to override the interpolate methods so that
+ // interpolation takes place across the entirety of the
+ // composite configuration. Without doing this each
+ // configuration object only interpolates variables defined
+ // inside itself.
+ final MyConfiguration conf = new MyConfiguration();
+ conf.addConfiguration(new SystemConfiguration()
+ {
+ protected String interpolate(String o)
+ {
+ return conf.interpolate(o);
+ }
+ });
+ conf.addConfiguration(new XMLConfiguration(file)
+ {
+ protected String interpolate(String o)
+ {
+ return conf.interpolate(o);
+ }
+ });
+ return conf;
+ }
+
+ static void substituteEnvironmentVariables(Configuration conf, Map<String, String> envVarMap)
+ {
+ if (envVarMap == null || envVarMap.isEmpty())
+ {
+ return;
+ }
+ for (Entry<String, String> var : envVarMap.entrySet())
+ {
+ String val = System.getenv(var.getKey());
+ if (val != null)
+ {
+ conf.setProperty(var.getValue(), val);
+ }
+ }
+ }
+
+
+ public static String escapeTagName(String name)
+ {
+ return name.replaceAll("\\.", "\\.\\.");
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java
index d08e3bc806..3c17faef75 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java
@@ -23,25 +23,16 @@ import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.ConversionException;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.ConfigurationManager;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
-public abstract class ConfigurationPlugin
+public abstract class AbstractConfiguration
{
- protected static final Logger _logger = Logger.getLogger(ConfigurationPlugin.class);
-
- private Map<String, ConfigurationPlugin>
- _pluginConfiguration = new HashMap<String, ConfigurationPlugin>();
+ protected static final Logger _logger = Logger.getLogger(AbstractConfiguration.class);
private Configuration _config;
@@ -69,11 +60,6 @@ public abstract class ConfigurationPlugin
return _config;
}
- public <C extends ConfigurationPlugin> C getConfiguration(String plugin)
- {
- return (C) _pluginConfiguration.get(plugin);
- }
-
/**
* Sets the configuration for this plugin
*
@@ -118,7 +104,7 @@ public abstract class ConfigurationPlugin
// With an XMLConfiguration the key will be [@property]
// but with a CompositeConfiguration it will be @property].
// Hide this issue from our users so when/if we change the
- // configuration they don't have to.
+ // configuration they don't have to.
int bracketIndex = tag.indexOf("[");
if (bracketIndex != -1)
{
@@ -140,62 +126,9 @@ public abstract class ConfigurationPlugin
}
}
- offerRemainingConfigurationToOtherPlugins(path, configuration, elements);
-
validateConfiguration();
}
- private void offerRemainingConfigurationToOtherPlugins(String path,
- Configuration configuration, Set<String> elements) throws ConfigurationException
- {
- final IApplicationRegistry appRegistry = safeGetApplicationRegistryInstance();
-
- if (appRegistry == null)
- {
- // We see this happen during shutdown due to asynchronous reconfig using IO threads.
- // Need to remove the responsibility for offering configuration to other class.
- _logger.info("Cannot offer remaining config to other plugins, can't find app registry");
- return;
- }
-
- final ConfigurationManager configurationManager = appRegistry.getConfigurationManager();
- // Process the elements in the configuration
- for (String element : elements)
- {
- Configuration handled = element.length() == 0 ? configuration : configuration.subset(element);
-
- String configurationElement = element;
- if (path.length() > 0)
- {
- configurationElement = path + "." + configurationElement;
- }
-
- List<ConfigurationPlugin> handlers = configurationManager.getConfigurationPlugins(configurationElement, handled);
-
- if(_logger.isDebugEnabled())
- {
- _logger.debug("For '" + element + "' found handlers (" + handlers.size() + "):" + handlers);
- }
-
- for (ConfigurationPlugin plugin : handlers)
- {
- _pluginConfiguration.put(plugin.getClass().getName(), plugin);
- }
- }
- }
-
- private IApplicationRegistry safeGetApplicationRegistryInstance()
- {
- try
- {
- return ApplicationRegistry.getInstance();
- }
- catch (IllegalStateException ise)
- {
- return null;
- }
- }
-
/** Helper method to print out list of keys in a {@link Configuration}. */
public static final void showKeys(Configuration config)
{
@@ -382,101 +315,9 @@ public abstract class ConfigurationPlugin
}
}
- /**
- * Given another configuration merge the configuration into our own config
- *
- * The new values being merged in will take precedence over existing values.
- *
- * In the simplistic case this means something like:
- *
- * So if we have configuration set
- * name = 'fooo'
- *
- * And the new configuration contains a name then that will be reset.
- * name = 'new'
- *
- * However this plugin will simply contain other plugins so the merge will
- * be called until we end up at a base plugin that understand how to merge
- * items. i.e Alerting values. Where the provided configuration will take
- * precedence.
- *
- * @param configuration the config to merge in to our own.
- */
- public void addConfiguration(ConfigurationPlugin configuration)
- {
- // If given configuration is null then there is nothing to process.
- if (configuration == null)
- {
- return;
- }
-
- // Merge all the sub configuration items
- for (Map.Entry<String, ConfigurationPlugin> newPlugins : configuration._pluginConfiguration.entrySet())
- {
- String key = newPlugins.getKey();
- ConfigurationPlugin config = newPlugins.getValue();
-
- if (_pluginConfiguration.containsKey(key))
- {
- //Merge the configuration if we already have this type of config
- _pluginConfiguration.get(key).mergeConfiguration(config);
- }
- else
- {
- //otherwise just add it to our config.
- _pluginConfiguration.put(key, config);
- }
- }
-
- //Merge the configuration itself
- String key = configuration.getClass().getName();
- if (_pluginConfiguration.containsKey(key))
- {
- //Merge the configuration if we already have this type of config
- _pluginConfiguration.get(key).mergeConfiguration(configuration);
- }
- else
- {
- //If we are adding a configuration of our own type then merge
- if (configuration.getClass() == this.getClass())
- {
- mergeConfiguration(configuration);
- }
- else
- {
- // just store this in case someone else needs it.
- _pluginConfiguration.put(key, configuration);
- }
-
- }
-
- }
-
- protected void mergeConfiguration(ConfigurationPlugin configuration)
- {
- _config = configuration.getConfig();
- }
-
- public String toString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append("\n").append(getClass().getSimpleName());
- sb.append("=[ (").append(formatToString()).append(")");
-
- for(Map.Entry<String,ConfigurationPlugin> item : _pluginConfiguration.entrySet())
- {
- sb.append("\n").append(item.getValue());
- }
-
- sb.append("]\n");
-
- return sb.toString();
- }
-
- public String formatToString()
+ public static String escapeTagName(String name)
{
- return super.toString();
+ return name.replaceAll("\\.", "\\.\\.");
}
protected void setConfig(Configuration config)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java
deleted file mode 100644
index a90b1d514f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java
+++ /dev/null
@@ -1,86 +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.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-public class SlowConsumerDetectionConfiguration extends ConfigurationPlugin
-{
- public static class SlowConsumerDetectionConfigurationFactory implements ConfigurationPluginFactory
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- SlowConsumerDetectionConfiguration slowConsumerConfig = new SlowConsumerDetectionConfiguration();
- slowConsumerConfig.setConfiguration(path, config);
- return slowConsumerConfig;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("virtualhosts.virtualhost.slow-consumer-detection");
- }
- }
-
- //Set Default time unit to seconds
- private TimeUnit _timeUnit = TimeUnit.SECONDS;
-
- public String[] getElementsProcessed()
- {
- return new String[]{"delay",
- "timeunit"};
- }
-
- public long getDelay()
- {
- return getLongValue("delay", 10);
- }
-
- public TimeUnit getTimeUnit()
- {
- return _timeUnit;
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- validatePositiveLong("delay");
-
- String timeUnit = getStringValue("timeunit");
-
- if (timeUnit != null)
- {
- try
- {
- _timeUnit = TimeUnit.valueOf(timeUnit.toUpperCase());
- }
- catch (IllegalArgumentException iae)
- {
- throw new ConfigurationException("Unable to configure Slow Consumer Detection invalid TimeUnit:" + timeUnit);
- }
- }
-
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java
deleted file mode 100644
index a9026c6164..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.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.configuration.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class SlowConsumerDetectionPolicyConfiguration extends ConfigurationPlugin
-{
- public static class SlowConsumerDetectionPolicyConfigurationFactory implements ConfigurationPluginFactory
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- SlowConsumerDetectionPolicyConfiguration slowConsumerConfig = new SlowConsumerDetectionPolicyConfiguration();
- slowConsumerConfig.setConfiguration(path, config);
- return slowConsumerConfig;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList(
- "virtualhosts.virtualhost.queues.slow-consumer-detection.policy",
- "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy",
- "virtualhosts.virtualhost.topics.slow-consumer-detection.policy",
- "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy");
- }
- }
-
- public String[] getElementsProcessed()
- {
- return new String[]{"name"};
- }
-
- public String getPolicyName()
- {
- return getStringValue("name");
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- if (getPolicyName() == null)
- {
- throw new ConfigurationException("No Slow consumer policy defined.");
- }
- }
-
- @Override
- public String formatToString()
- {
- return "Policy:"+getPolicyName();
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java
deleted file mode 100644
index cb3bb5a77f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java
+++ /dev/null
@@ -1,163 +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.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin;
-import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-public class SlowConsumerDetectionQueueConfiguration extends ConfigurationPlugin
-{
- private SlowConsumerPolicyPlugin _policyPlugin;
-
- public static class SlowConsumerDetectionQueueConfigurationFactory implements ConfigurationPluginFactory
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- SlowConsumerDetectionQueueConfiguration slowConsumerConfig = new SlowConsumerDetectionQueueConfiguration();
- slowConsumerConfig.setConfiguration(path, config);
- return slowConsumerConfig;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList(
- "virtualhosts.virtualhost.queues.slow-consumer-detection",
- "virtualhosts.virtualhost.queues.queue.slow-consumer-detection",
- "virtualhosts.virtualhost.topics.slow-consumer-detection",
- "virtualhosts.virtualhost.topics.topic.slow-consumer-detection");
- }
- }
-
- public String[] getElementsProcessed()
- {
- return new String[]{"messageAge",
- "depth",
- "messageCount"};
- }
-
- public long getMessageAge()
- {
- return getLongValue("messageAge");
- }
-
- public long getDepth()
- {
- return getLongValue("depth");
- }
-
- public long getMessageCount()
- {
- return getLongValue("messageCount");
- }
-
- public SlowConsumerPolicyPlugin getPolicy()
- {
- return _policyPlugin;
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- PluginManager pluginManager;
- try
- {
- pluginManager = ApplicationRegistry.getInstance().getPluginManager();
- }
- catch (IllegalStateException ise)
- {
- // We see this happen during shutdown due to asynchronous reconfig performed IO threads
- // running at the same time as the shutdown handler.
- _policyPlugin = null;
- return;
- }
-
- if (!containsPositiveLong("messageAge") &&
- !containsPositiveLong("depth") &&
- !containsPositiveLong("messageCount"))
- {
- throw new ConfigurationException("At least one configuration property" +
- "('messageAge','depth' or 'messageCount') must be specified.");
- }
-
- SlowConsumerDetectionPolicyConfiguration policyConfig = getConfiguration(SlowConsumerDetectionPolicyConfiguration.class.getName());
- Map<String, SlowConsumerPolicyPluginFactory> factories = pluginManager.getSlowConsumerPlugins();
-
- if (policyConfig == null)
- {
- throw new ConfigurationException("No Slow Consumer Policy specified. Known Policies:" + factories.keySet());
- }
-
- if (_logger.isDebugEnabled())
- {
- Iterator<?> keys = policyConfig.getConfig().getKeys();
-
- while (keys.hasNext())
- {
- String key = (String) keys.next();
-
- _logger.debug("Policy Keys:" + key);
- }
-
- }
-
- SlowConsumerPolicyPluginFactory<SlowConsumerPolicyPlugin> pluginFactory = factories.get(policyConfig.getPolicyName().toLowerCase());
-
- if (pluginFactory == null)
- {
- throw new ConfigurationException("Unknown Slow Consumer Policy specified:" + policyConfig.getPolicyName() + " Known Policies:" + factories.keySet());
- }
-
- _policyPlugin = pluginFactory.newInstance(policyConfig);
-
- // Debug the creation of this Config
- _logger.debug(this);
- }
-
- public String formatToString()
- {
- StringBuilder sb = new StringBuilder();
- if (getMessageAge() > 0)
- {
- sb.append("Age:").append(getMessageAge()).append(":");
- }
- if (getDepth() > 0)
- {
- sb.append("Depth:").append(getDepth()).append(":");
- }
- if (getMessageCount() > 0)
- {
- sb.append("Count:").append(getMessageCount()).append(":");
- }
-
- sb.append("Policy[").append(getPolicy()).append("]");
- return sb.toString();
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java
new file mode 100644
index 0000000000..9b06a2b499
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.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.configuration.startup;
+
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+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.adapter.AuthenticationProviderFactory;
+
+public class AuthenticationProviderRecoverer implements ConfiguredObjectRecoverer<AuthenticationProvider>
+{
+ private final AuthenticationProviderFactory _authenticationProviderFactory;
+
+ public AuthenticationProviderRecoverer(AuthenticationProviderFactory authenticationProviderFactory)
+ {
+ _authenticationProviderFactory = authenticationProviderFactory;
+ }
+
+ @Override
+ public AuthenticationProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents)
+ {
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ Map<String, Object> attributes = configurationEntry.getAttributes();
+ AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create(
+ configurationEntry.getId(),
+ broker,
+ attributes, null);
+
+ return authenticationProvider;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
new file mode 100644
index 0000000000..4bfa0ca7a3
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
@@ -0,0 +1,139 @@
+package org.apache.qpid.server.configuration.startup;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+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.Port;
+import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory;
+import org.apache.qpid.server.model.adapter.BrokerAdapter;
+import org.apache.qpid.server.model.adapter.PortFactory;
+import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker>
+{
+ private final StatisticsGatherer _statisticsGatherer;
+ private final VirtualHostRegistry _virtualHostRegistry;
+ private final LogRecorder _logRecorder;
+ private final RootMessageLogger _rootMessageLogger;
+ private final AuthenticationProviderFactory _authenticationProviderFactory;
+ private final PortFactory _portFactory;
+ private final TaskExecutor _taskExecutor;
+
+ public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, PortFactory portFactory,
+ StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder,
+ RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor)
+ {
+ _portFactory = portFactory;
+ _authenticationProviderFactory = authenticationProviderFactory;
+ _statisticsGatherer = statisticsGatherer;
+ _virtualHostRegistry = virtualHostRegistry;
+ _logRecorder = logRecorder;
+ _rootMessageLogger = rootMessageLogger;
+ _taskExecutor = taskExecutor;
+ }
+
+ @Override
+ public Broker create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
+ {
+ StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore());
+ BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry,
+ _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor);
+ broker.addChangeListener(storeChangeListener);
+ Map<String, Collection<ConfigurationEntry>> childEntries = entry.getChildren();
+ for (String type : childEntries.keySet())
+ {
+ ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type);
+ if (recoverer == null)
+ {
+ throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker");
+ }
+ Collection<ConfigurationEntry> entries = childEntries.get(type);
+ for (ConfigurationEntry childEntry : entries)
+ {
+ ConfiguredObject object = recoverer.create(recovererProvider, childEntry, broker);
+ if (object == null)
+ {
+ throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry);
+ }
+ broker.recoverChild(object);
+ object.addChangeListener(storeChangeListener);
+ }
+ }
+ wireUpConfiguredObjects(broker, entry.getAttributes());
+
+ return broker;
+ }
+
+ private void wireUpConfiguredObjects(BrokerAdapter broker, Map<String, Object> brokerAttributes)
+ {
+ AuthenticationProvider defaultAuthenticationProvider = null;
+ Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders();
+ int numberOfAuthenticationProviders = authenticationProviders.size();
+ if (numberOfAuthenticationProviders == 0)
+ {
+ throw new IllegalConfigurationException("No authentication provider was configured");
+ }
+ else if (numberOfAuthenticationProviders == 1)
+ {
+ defaultAuthenticationProvider = authenticationProviders.iterator().next();
+ }
+ else
+ {
+ String name = (String) brokerAttributes.get(Broker.DEFAULT_AUTHENTICATION_PROVIDER);
+ if (name == null)
+ {
+ throw new IllegalConfigurationException("Multiple authentication providers defined, but no default was configured.");
+ }
+
+ defaultAuthenticationProvider = getAuthenticationProviderByName(broker, name);
+ }
+ broker.setDefaultAuthenticationProvider(defaultAuthenticationProvider);
+
+ GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(broker.getGroupProviders());
+ for (AuthenticationProvider authenticationProvider : authenticationProviders)
+ {
+ authenticationProvider.setGroupAccessor(groupPrincipalAccessor);
+ }
+
+ Collection<Port> ports = broker.getPorts();
+ for (Port port : ports)
+ {
+ String authenticationProviderName = (String) port.getAttribute(Port.AUTHENTICATION_MANAGER);
+ AuthenticationProvider provider = null;
+ if (authenticationProviderName != null)
+ {
+ provider = getAuthenticationProviderByName(broker, authenticationProviderName);
+ }
+ else
+ {
+ provider = defaultAuthenticationProvider;
+ }
+ port.setAuthenticationProvider(provider);
+ }
+ }
+
+ private AuthenticationProvider getAuthenticationProviderByName(BrokerAdapter broker, String authenticationProviderName)
+ {
+ AuthenticationProvider provider = broker.getAuthenticationProviderByName(authenticationProviderName);
+ if (provider == null)
+ {
+ throw new IllegalConfigurationException("Cannot find the authentication provider with name: "
+ + authenticationProviderName);
+ }
+ return provider;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java
new file mode 100644
index 0000000000..15cb229d8a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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.startup;
+
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory;
+import org.apache.qpid.server.model.adapter.PortFactory;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.plugin.GroupManagerFactory;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class DefaultRecovererProvider implements RecovererProvider
+{
+
+ private final StatisticsGatherer _brokerStatisticsGatherer;
+ private final VirtualHostRegistry _virtualHostRegistry;
+ private final LogRecorder _logRecorder;
+ private final RootMessageLogger _rootMessageLogger;
+ private final AuthenticationProviderFactory _authenticationProviderFactory;
+ private final PortFactory _portFactory;
+ private final QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader;
+ private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader;
+ private final TaskExecutor _taskExecutor;
+
+ public DefaultRecovererProvider(StatisticsGatherer brokerStatisticsGatherer, VirtualHostRegistry virtualHostRegistry,
+ LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor)
+ {
+ _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>());
+ _portFactory = new PortFactory();
+ _brokerStatisticsGatherer = brokerStatisticsGatherer;
+ _virtualHostRegistry = virtualHostRegistry;
+ _logRecorder = logRecorder;
+ _rootMessageLogger = rootMessageLogger;
+ _groupManagerServiceLoader = new QpidServiceLoader<GroupManagerFactory>();
+ _pluginFactoryServiceLoader = new QpidServiceLoader<PluginFactory>();
+ _taskExecutor = taskExecutor;
+ }
+
+ @Override
+ public ConfiguredObjectRecoverer<?> getRecoverer(String type)
+ {
+ if (Broker.class.getSimpleName().equals(type))
+ {
+ return new BrokerRecoverer(_authenticationProviderFactory, _portFactory, _brokerStatisticsGatherer, _virtualHostRegistry,
+ _logRecorder, _rootMessageLogger, _taskExecutor);
+ }
+ else if(VirtualHost.class.getSimpleName().equals(type))
+ {
+ return new VirtualHostRecoverer(_brokerStatisticsGatherer);
+ }
+ else if(AuthenticationProvider.class.getSimpleName().equals(type))
+ {
+ return new AuthenticationProviderRecoverer(_authenticationProviderFactory);
+ }
+ else if(Port.class.getSimpleName().equals(type))
+ {
+ return new PortRecoverer(_portFactory);
+ }
+ else if(GroupProvider.class.getSimpleName().equals(type))
+ {
+ return new GroupProviderRecoverer(_groupManagerServiceLoader);
+ }
+ else if(KeyStore.class.getSimpleName().equals(type))
+ {
+ return new KeyStoreRecoverer();
+ }
+ else if(TrustStore.class.getSimpleName().equals(type))
+ {
+ return new TrustStoreRecoverer();
+ }
+ else if(Plugin.class.getSimpleName().equals(type))
+ {
+ return new PluginRecoverer(_pluginFactoryServiceLoader);
+ }
+
+ return null;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java
new file mode 100644
index 0000000000..275a0c736c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.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.configuration.startup;
+
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.adapter.GroupProviderAdapter;
+import org.apache.qpid.server.plugin.GroupManagerFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.security.group.GroupManager;
+
+public class GroupProviderRecoverer implements ConfiguredObjectRecoverer<GroupProvider>
+{
+ private QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader;
+
+ public GroupProviderRecoverer(QpidServiceLoader<GroupManagerFactory> groupManagerServiceLoader)
+ {
+ super();
+ _groupManagerServiceLoader = groupManagerServiceLoader;
+ }
+
+ @Override
+ public GroupProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents)
+ {
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ Map<String, Object> attributes = configurationEntry.getAttributes();
+ GroupManager groupManager = createGroupManager(attributes);
+ if (groupManager == null)
+ {
+ throw new IllegalConfigurationException("Cannot create GroupManager from attributes : " + attributes);
+ }
+ GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(configurationEntry.getId(), groupManager, broker);
+ return groupProviderAdapter;
+ }
+
+ private GroupManager createGroupManager(Map<String, Object> attributes)
+ {
+ for(GroupManagerFactory factory : _groupManagerServiceLoader.instancesOf(GroupManagerFactory.class))
+ {
+ GroupManager groupManager = factory.createInstance(attributes);
+ if (groupManager != null)
+ {
+ return groupManager;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java
index 833ccfbca4..8efedd37b5 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java
@@ -18,30 +18,23 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.server.configuration.startup;
-import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.adapter.KeyStoreAdapter;
-public abstract class QMFEventCommand<T extends QMFEventClass> extends QMFCommand
+public class KeyStoreRecoverer implements ConfiguredObjectRecoverer<KeyStore>
{
- private final long _timestamp;
-
- protected QMFEventCommand()
- {
- super(new QMFCommandHeader((byte)'2',0, QMFOperation.EVENT));
- _timestamp = System.currentTimeMillis();
- }
-
- abstract public T getEventClass();
-
@Override
- public void encode(final BBEncoder encoder)
+ public KeyStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
{
- super.encode(encoder);
- encoder.writeStr8(getEventClass().getPackage().getName());
- encoder.writeStr8(getEventClass().getName());
- encoder.writeBin128(new byte[16]);
- encoder.writeUint64(_timestamp * 1000000L);
- encoder.writeUint8((short) getEventClass().getSeverity().ordinal());
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ return new KeyStoreAdapter(entry.getId(), broker, entry.getAttributes());
}
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java
new file mode 100644
index 0000000000..ddc4482953
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.startup;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+
+public class PluginRecoverer implements ConfiguredObjectRecoverer<ConfiguredObject>
+{
+ private QpidServiceLoader<PluginFactory> _serviceLoader;
+
+ public PluginRecoverer(QpidServiceLoader<PluginFactory> serviceLoader)
+ {
+ _serviceLoader = serviceLoader;
+ }
+
+ @Override
+ public ConfiguredObject create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents)
+ {
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ Map<String, Object> attributes = configurationEntry.getAttributes();
+ Iterable<PluginFactory> factories = _serviceLoader.instancesOf(PluginFactory.class);
+ for (PluginFactory pluginFactory : factories)
+ {
+ UUID configurationId = configurationEntry.getId();
+ ConfiguredObject pluginObject = pluginFactory.createInstance(configurationId, attributes, broker);
+ if (pluginObject != null)
+ {
+ UUID pluginId = pluginObject.getId();
+ if (!configurationId.equals(pluginId))
+ {
+ throw new IllegalStateException("Plugin object id '" + pluginId + "' does not equal expected id " + configurationId);
+ }
+ return pluginObject;
+ }
+ }
+ throw new IllegalConfigurationException("Cannot create a plugin object for " + attributes + " with factories " + factories);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java
new file mode 100644
index 0000000000..147e835a8d
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.startup;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.adapter.BrokerAdapter;
+import org.apache.qpid.server.model.adapter.PortFactory;
+
+public class PortRecoverer implements ConfiguredObjectRecoverer<Port>
+{
+ /**
+ * delegates to a {@link PortFactory} so that the logic can be shared by
+ * {@link BrokerAdapter}
+ */
+ private final PortFactory _portFactory;
+
+ public PortRecoverer(PortFactory portFactory)
+ {
+ _portFactory = portFactory;
+ }
+
+ @Override
+ public Port create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents)
+ {
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ return _portFactory.createPort(configurationEntry.getId(), broker, configurationEntry.getAttributes());
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java
index 9c8fa1e2c6..b60c9c289f 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java
@@ -18,27 +18,27 @@
* under the License.
*
*/
+package org.apache.qpid.server.configuration.startup;
-package org.apache.qpid.qmf;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
-import org.apache.qpid.transport.codec.BBEncoder;
-
-public class QMFPackageIndicationCommand extends QMFCommand
+public class RecovererHelper
{
- private String _supportedSchema;
-
- public QMFPackageIndicationCommand(QMFPackageQueryCommand qmfPackageQueryCommand, String supportedSchema)
- {
- super( new QMFCommandHeader(qmfPackageQueryCommand.getHeader().getVersion(),
- qmfPackageQueryCommand.getHeader().getSeq(),
- QMFOperation.PACKAGE_INDICATION));
- _supportedSchema = supportedSchema;
-
- }
-
- public void encode(BBEncoder encoder)
+ public static Broker verifyOnlyBrokerIsParent(ConfiguredObject... parents)
{
- super.encode(encoder);
- encoder.writeStr8(_supportedSchema);
+ if (parents == null || parents.length == 0)
+ {
+ throw new IllegalArgumentException("Broker parent is not passed!");
+ }
+ if (parents.length != 1)
+ {
+ throw new IllegalArgumentException("Only one parent is expected!");
+ }
+ if (!(parents[0] instanceof Broker))
+ {
+ throw new IllegalArgumentException("Parent is not a broker");
+ }
+ return (Broker)parents[0];
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java
index 613e1e5978..7e9428a4d6 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java
@@ -18,31 +18,23 @@
* under the License.
*
*/
+package org.apache.qpid.server.configuration.startup;
-package org.apache.qpid.qmf;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.adapter.TrustStoreAdapter;
-import org.apache.qpid.transport.codec.BBEncoder;
-
-public class QMFClassIndicationCommand extends QMFCommand
+public class TrustStoreRecoverer implements ConfiguredObjectRecoverer<TrustStore>
{
- private QMFClass _qmfClass;
-
- public QMFClassIndicationCommand(QMFClassQueryCommand qmfClassQueryCommand, QMFClass qmfClass)
- {
- super(new QMFCommandHeader(qmfClassQueryCommand.getHeader().getVersion(),
- qmfClassQueryCommand.getHeader().getSeq(),
- QMFOperation.CLASS_INDICATION));
- _qmfClass = qmfClass;
- }
-
-
@Override
- public void encode(BBEncoder encoder)
+ public TrustStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
{
- super.encode(encoder);
- encoder.writeUint8(_qmfClass.getType().getValue());
- encoder.writeStr8(_qmfClass.getPackage().getName());
- encoder.writeStr8(_qmfClass.getName());
- encoder.writeBin128(_qmfClass.getSchemaHash());
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+ return new TrustStoreAdapter(entry.getId(), broker, entry.getAttributes());
}
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java
new file mode 100644
index 0000000000..4f863adfb5
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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.startup;
+
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.adapter.VirtualHostAdapter;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+
+public class VirtualHostRecoverer implements ConfiguredObjectRecoverer<VirtualHost>
+{
+ private StatisticsGatherer _brokerStatisticsGatherer;
+
+ public VirtualHostRecoverer(StatisticsGatherer brokerStatisticsGatherer)
+ {
+ super();
+ _brokerStatisticsGatherer = brokerStatisticsGatherer;
+ }
+
+ @Override
+ public VirtualHost create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
+ {
+ Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents);
+
+ return new VirtualHostAdapter(entry.getId(), entry.getAttributes(), broker, _brokerStatisticsGatherer, broker.getTaskExecutor());
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java
new file mode 100644
index 0000000000..e11b63001a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java
@@ -0,0 +1,711 @@
+package org.apache.qpid.server.configuration.store;
+
+import static org.apache.qpid.server.configuration.ConfigurationEntry.ATTRIBUTE_NAME;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.util.FileUtils;
+import org.apache.qpid.util.Strings;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.node.ArrayNode;
+
+public class JsonConfigurationEntryStore implements ConfigurationEntryStore
+{
+ public static final String STORE_TYPE = "json";
+ public static final String IN_MEMORY = ":memory:";
+
+ private static final String DEFAULT_BROKER_NAME = "Broker";
+ private static final String ID = "id";
+ private static final String TYPE = "@type";
+
+ private ObjectMapper _objectMapper;
+ private Map<UUID, ConfigurationEntry> _entries;
+ private File _storeFile;
+ private UUID _rootId;
+ private Map<String, Class<? extends ConfiguredObject>> _relationshipClasses;
+
+ public JsonConfigurationEntryStore()
+ {
+ _objectMapper = new ObjectMapper();
+ _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+ _entries = new HashMap<UUID, ConfigurationEntry>();
+ _relationshipClasses = buildRelationshipClassMap();
+ }
+
+ @Override
+ public void open(String storeLocation)
+ {
+ if (_rootId != null)
+ {
+ throw new IllegalConfigurationException("The store has been opened alread");
+ }
+ if (!IN_MEMORY.equals(storeLocation))
+ {
+ _storeFile = new File(storeLocation);
+ }
+ createOrLoadStore();
+ }
+
+ @Override
+ public void open(String storeLocation, String initialStoreLocation)
+ {
+ if (_rootId != null)
+ {
+ throw new IllegalConfigurationException("The store has been opened already");
+ }
+ if (!IN_MEMORY.equals(storeLocation))
+ {
+ _storeFile = new File(storeLocation);
+ if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStoreLocation != null)
+ {
+ copyInitialStoreFile(initialStoreLocation);
+ }
+ createOrLoadStore();
+ }
+ else
+ {
+ if (initialStoreLocation == null)
+ {
+ createRootEntryIfNotExists();
+ }
+ else
+ {
+ load(toURL(initialStoreLocation));
+ }
+ }
+ }
+
+ @Override
+ public void open(String storeLocation, ConfigurationEntryStore initialStore)
+ {
+ if (_rootId != null)
+ {
+ throw new IllegalConfigurationException("The store has been opened already");
+ }
+ boolean copyStore = false;
+ if (IN_MEMORY.equals(storeLocation))
+ {
+ copyStore = initialStore != null;
+ }
+ else
+ {
+ _storeFile = new File(storeLocation);
+ if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStore != null)
+ {
+ createStoreFileIfNotExist(_storeFile);
+ copyStore = true;
+ }
+ }
+ if (copyStore)
+ {
+ ConfigurationEntry rootEntry = initialStore.getRootEntry();
+ _rootId = rootEntry.getId();
+ copyEntry(rootEntry.getId(), initialStore);
+ saveAsTree();
+ }
+ else
+ {
+ createOrLoadStore();
+ }
+ }
+
+ @Override
+ public synchronized UUID[] remove(UUID... entryIds)
+ {
+ List<UUID> removedIds = new ArrayList<UUID>();
+ boolean anyRemoved = false;
+ for (UUID uuid : entryIds)
+ {
+ if (_rootId.equals(uuid))
+ {
+ throw new IllegalConfigurationException("Cannot remove root entry");
+ }
+ }
+ for (UUID uuid : entryIds)
+ {
+ if (removeInternal(uuid))
+ {
+ anyRemoved = true;
+
+ // remove references to the entry from parent entries
+ for (ConfigurationEntry entry : _entries.values())
+ {
+ if (entry.hasChild(uuid))
+ {
+ Set<UUID> children = new HashSet<UUID>(entry.getChildrenIds());
+ children.remove(uuid);
+ ConfigurationEntry referal = new ConfigurationEntry(entry.getId(), entry.getType(),
+ entry.getAttributes(), children, this);
+ _entries.put(entry.getId(), referal);
+ }
+ }
+ removedIds.add(uuid);
+ }
+ }
+ if (anyRemoved)
+ {
+ saveAsTree();
+ }
+ return removedIds.toArray(new UUID[removedIds.size()]);
+ }
+
+ @Override
+ public synchronized void save(ConfigurationEntry... entries)
+ {
+ boolean anySaved = false;
+ for (ConfigurationEntry entry : entries)
+ {
+ ConfigurationEntry oldEntry = _entries.put(entry.getId(), entry);
+ if (!entry.equals(oldEntry))
+ {
+ anySaved = true;
+ }
+ }
+ if (anySaved)
+ {
+ saveAsTree();
+ }
+ }
+
+ @Override
+ public ConfigurationEntry getRootEntry()
+ {
+ return getEntry(_rootId);
+ }
+
+ @Override
+ public synchronized ConfigurationEntry getEntry(UUID id)
+ {
+ return _entries.get(id);
+ }
+
+ @Override
+ public void copyTo(String copyLocation)
+ {
+ if (_rootId == null)
+ {
+ throw new IllegalConfigurationException("The store has not been opened");
+ }
+ File file = new File(copyLocation);
+ if (!file.exists())
+ {
+ createStoreFileIfNotExist(file);
+ }
+ saveAsTree(_rootId, _entries, _objectMapper, file);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "JsonConfigurationEntryStore [_storeFile=" + _storeFile + ", _rootId=" + _rootId + "]";
+ }
+
+ private Map<String, Class<? extends ConfiguredObject>> buildRelationshipClassMap()
+ {
+ Map<String, Class<? extends ConfiguredObject>> relationships = new HashMap<String, Class<? extends ConfiguredObject>>();
+
+ Collection<Class<? extends ConfiguredObject>> children = Model.getInstance().getChildTypes(Broker.class);
+ for (Class<? extends ConfiguredObject> childClass : children)
+ {
+ String name = childClass.getSimpleName().toLowerCase();
+ String relationshipName = name + (name.endsWith("s") ? "es" : "s");
+ relationships.put(relationshipName, childClass);
+ }
+ return relationships;
+ }
+
+ private void createOrLoadStore()
+ {
+ if (_storeFile != null)
+ {
+ if (!_storeFile.exists() || _storeFile.length() == 0)
+ {
+ createStoreFileIfNotExist(_storeFile);
+ }
+ else
+ {
+ load(fileToURL(_storeFile));
+ }
+ }
+
+ createRootEntryIfNotExists();
+ }
+
+ private void createRootEntryIfNotExists()
+ {
+ if (_rootId == null)
+ {
+ // create a root entry for an empty store
+ ConfigurationEntry brokerEntry = new ConfigurationEntry(UUIDGenerator.generateRandomUUID(),
+ Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), this);
+ _rootId = brokerEntry.getId();
+ _entries.put(_rootId, brokerEntry);
+ }
+ }
+
+ private void load(URL url)
+ {
+ InputStream is = null;
+ try
+ {
+ is = url.openStream();
+ JsonNode node = loadJsonNodes(is, _objectMapper);
+ ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries);
+ _rootId = brokerEntry.getId();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot load store from: " + url, e);
+ }
+ finally
+ {
+ if (is != null)
+ {
+ if (is != null)
+ {
+ try
+ {
+ is.close();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot close input stream for: " + url, e);
+ }
+ }
+ }
+ }
+ }
+
+ private void copyInitialStoreFile(String initialStoreLocation)
+ {
+ createStoreFileIfNotExist(_storeFile);
+ URL initialStoreURL = toURL(initialStoreLocation);
+ InputStream in = null;
+ try
+ {
+ in = initialStoreURL.openStream();
+ FileUtils.copy(in, _storeFile);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot create store file " + _storeFile + " by copying initial store from " + initialStoreLocation , e);
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot close initial store input stream: " + initialStoreLocation , e);
+ }
+ }
+ }
+ }
+
+ private URL fileToURL(File storeFile)
+ {
+ URL storeURL = null;
+ try
+ {
+ storeURL = storeFile.toURI().toURL();
+ }
+ catch (MalformedURLException e)
+ {
+ throw new IllegalConfigurationException("Cannot create URL for file " + storeFile, e);
+ }
+ return storeURL;
+ }
+
+ private boolean removeInternal(UUID entryId)
+ {
+ ConfigurationEntry oldEntry = _entries.remove(entryId);
+ if (oldEntry != null)
+ {
+ Set<UUID> children = oldEntry.getChildrenIds();
+ if (children != null && !children.isEmpty())
+ {
+ for (UUID childId : children)
+ {
+ removeInternal(childId);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void saveAsTree()
+ {
+ if (_storeFile != null)
+ {
+ saveAsTree(_rootId, _entries, _objectMapper, _storeFile);
+ }
+ }
+
+ private void saveAsTree(UUID rootId, Map<UUID, ConfigurationEntry> entries, ObjectMapper mapper, File file)
+ {
+ Map<String, Object> tree = toTree(rootId, entries);
+ try
+ {
+ mapper.writeValue(file, tree);
+ }
+ catch (JsonGenerationException e)
+ {
+ throw new IllegalConfigurationException("Cannot generate json!", e);
+ }
+ catch (JsonMappingException e)
+ {
+ throw new IllegalConfigurationException("Cannot map objects for json serialization!", e);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot save configuration into " + file + "!", e);
+ }
+ }
+
+ private Map<String, Object> toTree(UUID rootId, Map<UUID, ConfigurationEntry> entries)
+ {
+ ConfigurationEntry entry = entries.get(rootId);
+ if (entry == null || !entry.getId().equals(rootId))
+ {
+ throw new IllegalConfigurationException("Cannot find entry with id " + rootId + "!");
+ }
+ Map<String, Object> tree = new TreeMap<String, Object>();
+ Map<String, Object> attributes = entry.getAttributes();
+ if (attributes != null)
+ {
+ tree.putAll(attributes);
+ }
+ tree.put(ID, entry.getId());
+ tree.put(TYPE, entry.getType());
+ Set<UUID> childrenIds = entry.getChildrenIds();
+ if (childrenIds != null && !childrenIds.isEmpty())
+ {
+ for (UUID relationship : childrenIds)
+ {
+ ConfigurationEntry child = entries.get(relationship);
+ if (child != null)
+ {
+ String relationshipName = child.getType().toLowerCase() + "s";
+
+ @SuppressWarnings("unchecked")
+ Collection<Map<String, Object>> children = (Collection<Map<String, Object>>) tree.get(relationshipName);
+ if (children == null)
+ {
+ children = new ArrayList<Map<String, Object>>();
+ tree.put(relationshipName, children);
+ }
+ Map<String, Object> childAsMap = toTree(relationship, entries);
+ children.add(childAsMap);
+ }
+ }
+ }
+ return tree;
+ }
+
+ private JsonNode loadJsonNodes(InputStream is, ObjectMapper mapper)
+ {
+ JsonNode root = null;
+ try
+ {
+ root = mapper.readTree(is);
+ }
+ catch (JsonProcessingException e)
+ {
+ throw new IllegalConfigurationException("Cannot parse json", e);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot read json", e);
+ }
+ return root;
+ }
+
+ private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries)
+ {
+ Map<String, Object> attributes = null;
+ Set<UUID> childrenIds = new TreeSet<UUID>();
+ Iterator<String> fieldNames = parent.getFieldNames();
+ String type = null;
+ String idAsString = null;
+ while (fieldNames.hasNext())
+ {
+ String fieldName = fieldNames.next();
+ JsonNode fieldNode = parent.get(fieldName);
+ if (fieldName.equals(ID))
+ {
+ idAsString = fieldNode.asText();
+ }
+ else if (fieldName.equals(TYPE))
+ {
+ type = fieldNode.asText();
+ }
+ else if (fieldNode.isArray())
+ {
+ // array containing either broker children or attribute values
+ Iterator<JsonNode> elements = fieldNode.getElements();
+ List<Object> fieldValues = null;
+ while (elements.hasNext())
+ {
+ JsonNode element = elements.next();
+ if (element.isObject())
+ {
+ Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName);
+ // assuming it is a child node
+ ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries);
+ childrenIds.add(entry.getId());
+ }
+ else
+ {
+ if (fieldValues == null)
+ {
+ fieldValues = new ArrayList<Object>();
+ }
+ fieldValues.add(toObject(element));
+ }
+ }
+ if (fieldValues != null)
+ {
+ Object[] array = fieldValues.toArray(new Object[fieldValues.size()]);
+ attributes.put(fieldName, array);
+ }
+ }
+ else if (fieldNode.isObject())
+ {
+ // ignore, in-line objects are not supported yet
+ }
+ else
+ {
+ // primitive attribute
+ Object value = toObject(fieldNode);
+ if (attributes == null)
+ {
+ attributes = new HashMap<String, Object>();
+ }
+ attributes.put(fieldName, value);
+ }
+ }
+
+ if (type == null)
+ {
+ if (expectedConfiguredObjectClass == null)
+ {
+ throw new IllegalConfigurationException("Type attribute is not provided for configuration entry " + parent);
+ }
+ else
+ {
+ type = expectedConfiguredObjectClass.getSimpleName();
+ }
+ }
+ String name = null;
+ if (attributes != null)
+ {
+ name = (String) attributes.get(ATTRIBUTE_NAME);
+ }
+ if ((name == null || "".equals(name)))
+ {
+ if (expectedConfiguredObjectClass == Broker.class)
+ {
+ name = DEFAULT_BROKER_NAME;
+ }
+ else
+ {
+ throw new IllegalConfigurationException("Name attribute is not provided for configuration entry " + parent);
+ }
+ }
+ UUID id = null;
+ if (idAsString == null)
+ {
+ if (expectedConfiguredObjectClass == Broker.class)
+ {
+ id = UUIDGenerator.generateRandomUUID();
+ }
+ else
+ {
+ id = UUIDGenerator.generateBrokerChildUUID(type, name);
+ }
+ }
+ else
+ {
+ try
+ {
+ id = UUID.fromString(idAsString);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalConfigurationException(
+ "ID attribute value does not conform to UUID format for configuration entry " + parent);
+ }
+ }
+ ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, childrenIds, this);
+ if (entries.containsKey(id))
+ {
+ throw new IllegalConfigurationException("Duplicate id is found: " + id
+ + "! The following configuration entries have the same id: " + entries.get(id) + ", " + entry);
+ }
+ entries.put(id, entry);
+ return entry;
+ }
+
+ private Object toObject(JsonNode node)
+ {
+ if (node.isValueNode())
+ {
+ if (node.isBoolean())
+ {
+ return node.asBoolean();
+ }
+ else if (node.isDouble())
+ {
+ return node.asDouble();
+ }
+ else if (node.isInt())
+ {
+ return node.asInt();
+ }
+ else if (node.isLong())
+ {
+ return node.asLong();
+ }
+ else if (node.isNull())
+ {
+ return null;
+ }
+ else
+ {
+ return Strings.expand(node.asText());
+ }
+ }
+ else if (node.isArray())
+ {
+ return toArray(node);
+ }
+ else if (node.isObject())
+ {
+ return toMap(node);
+ }
+ else
+ {
+ throw new IllegalConfigurationException("Unexpected node: " + node);
+ }
+ }
+
+ private Map<String, Object> toMap(JsonNode node)
+ {
+ Map<String, Object> object = new TreeMap<String, Object>();
+ Iterator<String> fieldNames = node.getFieldNames();
+ while (fieldNames.hasNext())
+ {
+ String name = fieldNames.next();
+ Object value = toObject(node.get(name));
+ object.put(name, value);
+ }
+ return object;
+ }
+
+ private Object toArray(JsonNode node)
+ {
+ ArrayNode arrayNode = (ArrayNode) node;
+ Object[] array = new Object[arrayNode.size()];
+ Iterator<JsonNode> elements = arrayNode.getElements();
+ for (int i = 0; i < array.length; i++)
+ {
+ array[i] = toObject(elements.next());
+ }
+ return array;
+ }
+
+ /*
+ * Initial store location can be URL or absolute path
+ */
+ private URL toURL(String location)
+ {
+ URL url = null;
+ try
+ {
+ url = new URL(location);
+ }
+ catch (MalformedURLException e)
+ {
+ File locationFile = new File(location);
+ url = fileToURL(locationFile);
+ }
+ return url;
+ }
+
+ private void createStoreFileIfNotExist(File file)
+ {
+ File parent = file.getParentFile();
+ if (!parent.exists())
+ {
+ if (!parent.mkdirs())
+ {
+ throw new IllegalConfigurationException("Cannot create folders " + parent);
+ }
+ }
+ try
+ {
+ file.createNewFile();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Cannot create file " + file, e);
+ }
+ }
+
+ private void copyEntry(UUID entryId, ConfigurationEntryStore initialStore)
+ {
+ ConfigurationEntry entry = initialStore.getEntry(entryId);
+ if (entry != null)
+ {
+ if (_entries.containsKey(entryId))
+ {
+ throw new IllegalConfigurationException("Duplicate id is found: " + entryId
+ + "! The following configuration entries have the same id: " + _entries.get(entryId) + ", " + entry);
+ }
+ _entries.put(entryId, entry);
+ Set<UUID> children = entry.getChildrenIds();
+ if (children != null)
+ {
+ for (UUID uuid : children)
+ {
+ copyEntry(uuid, initialStore);
+ }
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
new file mode 100644
index 0000000000..e7c474bf55
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
@@ -0,0 +1,327 @@
+package org.apache.qpid.server.configuration.store;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+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.VirtualHost;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class ManagementModeStoreHandler implements ConfigurationEntryStore
+{
+ private static final Logger LOGGER = Logger.getLogger(ManagementModeStoreHandler.class);
+
+ private static final String MANAGEMENT_MODE_PORT_PREFIX = "MANAGEMENT-MODE-PORT-";
+ private static final String PORT_TYPE = Port.class.getSimpleName();
+ private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName();
+ private static final String ATTRIBUTE_STATE = VirtualHost.STATE;
+
+ private final ConfigurationEntryStore _store;
+ private final Map<UUID, ConfigurationEntry> _cliEntries;
+ private final Map<UUID, Object> _quiescedEntries;
+ private final UUID _rootId;
+
+ public ManagementModeStoreHandler(ConfigurationEntryStore store, BrokerOptions options)
+ {
+ ConfigurationEntry storeRoot = store.getRootEntry();
+ _store = store;
+ _rootId = storeRoot.getId();
+ _cliEntries = createPortsFromCommadLineOptions(options);
+ _quiescedEntries = quiesceEntries(storeRoot, options);
+ }
+
+ @Override
+ public void open(String storeLocation)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public void open(String storeLocation, String initialStoreLocation)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public void open(String storeLocation, ConfigurationEntryStore initialStore)
+ {
+ throw new IllegalStateException("The store should be already opened");
+ }
+
+ @Override
+ public ConfigurationEntry getRootEntry()
+ {
+ return getEntry(_rootId);
+ }
+
+ @Override
+ public ConfigurationEntry getEntry(UUID id)
+ {
+ synchronized (_store)
+ {
+ if (_cliEntries.containsKey(id))
+ {
+ return _cliEntries.get(id);
+ }
+
+ ConfigurationEntry entry = _store.getEntry(id);
+ if (_quiescedEntries.containsKey(id))
+ {
+ entry = createEntryWithState(entry, State.QUIESCED);
+ }
+ else if (id == _rootId)
+ {
+ entry = createRootWithCLIEntries(entry);
+ }
+ return entry;
+ }
+ }
+
+ @Override
+ public void save(ConfigurationEntry... entries)
+ {
+ synchronized (_store)
+ {
+ ConfigurationEntry[] entriesToSave = new ConfigurationEntry[entries.length];
+
+ for (int i = 0; i < entries.length; i++)
+ {
+ ConfigurationEntry entry = entries[i];
+ UUID id = entry.getId();
+ if (_cliEntries.containsKey(id))
+ {
+ throw new IllegalConfigurationException("Cannot save configuration provided as command line argument:"
+ + entry);
+ }
+ else if (_quiescedEntries.containsKey(id))
+ {
+ // save entry with the original state
+ entry = createEntryWithState(entry, _quiescedEntries.get(ATTRIBUTE_STATE));
+ }
+ else if (_rootId.equals(id))
+ {
+ // save root without command line entries
+ Set<UUID> childrenIds = new HashSet<UUID>(entry.getChildrenIds());
+ if (!_cliEntries.isEmpty())
+ {
+ childrenIds.removeAll(_cliEntries.entrySet());
+ }
+ HashMap<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes());
+ entry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, childrenIds, this);
+ }
+ entriesToSave[i] = entry;
+ }
+
+ _store.save(entriesToSave);
+ }
+ }
+
+ @Override
+ public UUID[] remove(UUID... entryIds)
+ {
+ synchronized (_store)
+ {
+ for (UUID id : entryIds)
+ {
+ if (_cliEntries.containsKey(id))
+ {
+ throw new IllegalConfigurationException("Cannot change configuration for command line entry:"
+ + _cliEntries.get(id));
+ }
+ }
+ UUID[] result = _store.remove(entryIds);
+ for (UUID id : entryIds)
+ {
+ if (_quiescedEntries.containsKey(id))
+ {
+ _quiescedEntries.remove(id);
+ }
+ }
+ return result;
+ }
+ }
+
+ @Override
+ public void copyTo(String copyLocation)
+ {
+ synchronized (_store)
+ {
+ _store.copyTo(copyLocation);
+ }
+ }
+
+ private Map<UUID, ConfigurationEntry> createPortsFromCommadLineOptions(BrokerOptions options)
+ {
+ int managementModeRmiPort = options.getManagementModeRmiPort();
+ if (managementModeRmiPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid rmi port is specified: " + managementModeRmiPort);
+ }
+ int managementModeConnectorPort = options.getManagementModeConnectorPort();
+ if (managementModeConnectorPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid connector port is specified: " + managementModeConnectorPort);
+ }
+ int managementModeHttpPort = options.getManagementModeHttpPort();
+ if (managementModeHttpPort < 0)
+ {
+ throw new IllegalConfigurationException("Invalid http port is specified: " + managementModeHttpPort);
+ }
+ Map<UUID, ConfigurationEntry> cliEntries = new HashMap<UUID, ConfigurationEntry>();
+ if (managementModeRmiPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeRmiPort, Protocol.RMI);
+ cliEntries.put(entry.getId(), entry);
+ if (managementModeConnectorPort == 0)
+ {
+ ConfigurationEntry connectorEntry = createCLIPortEntry(managementModeRmiPort + 100, Protocol.JMX_RMI);
+ cliEntries.put(connectorEntry.getId(), connectorEntry);
+ }
+ }
+ if (managementModeConnectorPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeConnectorPort, Protocol.JMX_RMI);
+ cliEntries.put(entry.getId(), entry);
+ }
+ if (managementModeHttpPort != 0)
+ {
+ ConfigurationEntry entry = createCLIPortEntry(managementModeHttpPort, Protocol.HTTP);
+ cliEntries.put(entry.getId(), entry);
+ }
+ return cliEntries;
+ }
+
+ private ConfigurationEntry createCLIPortEntry(int port, Protocol protocol)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PORT, port);
+ attributes.put(Port.PROTOCOLS, Collections.singleton(protocol));
+ attributes.put(Port.NAME, MANAGEMENT_MODE_PORT_PREFIX + protocol.name());
+ ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), PORT_TYPE, attributes,
+ Collections.<UUID> emptySet(), this);
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Add management mode port configuration " + portEntry + " for port " + port + " and protocol "
+ + protocol);
+ }
+ return portEntry;
+ }
+
+ private ConfigurationEntry createRootWithCLIEntries(ConfigurationEntry storeRoot)
+ {
+ Set<UUID> childrenIds = new HashSet<UUID>(storeRoot.getChildrenIds());
+ if (!_cliEntries.isEmpty())
+ {
+ childrenIds.addAll(_cliEntries.keySet());
+ }
+ ConfigurationEntry root = new ConfigurationEntry(storeRoot.getId(), storeRoot.getType(), new HashMap<String, Object>(
+ storeRoot.getAttributes()), childrenIds, this);
+ return root;
+ }
+
+ private Map<UUID, Object> quiesceEntries(ConfigurationEntry storeRoot, BrokerOptions options)
+ {
+ Map<UUID, Object> quiescedEntries = new HashMap<UUID, Object>();
+ Set<UUID> childrenIds;
+ int managementModeRmiPort = options.getManagementModeRmiPort();
+ int managementModeConnectorPort = options.getManagementModeConnectorPort();
+ int managementModeHttpPort = options.getManagementModeHttpPort();
+ childrenIds = storeRoot.getChildrenIds();
+ for (UUID id : childrenIds)
+ {
+ ConfigurationEntry entry = _store.getEntry(id);
+ String entryType = entry.getType();
+ Map<String, Object> attributes = entry.getAttributes();
+ boolean quiesce = false;
+ if (VIRTUAL_HOST_TYPE.equals(entryType))
+ {
+ quiesce = true;
+ }
+ else if (PORT_TYPE.equalsIgnoreCase(entryType))
+ {
+ if (attributes == null)
+ {
+ throw new IllegalConfigurationException("Port attributes are not set in " + entry);
+ }
+ Set<Protocol> protocols = getPortProtocolsAttribute(attributes);
+ if (protocols == null)
+ {
+ quiesce = true;
+ }
+ else
+ {
+ for (Protocol protocol : protocols)
+ {
+ switch (protocol)
+ {
+ case JMX_RMI:
+ quiesce = managementModeConnectorPort > 0 || managementModeRmiPort > 0;
+ break;
+ case RMI:
+ quiesce = managementModeRmiPort > 0;
+ break;
+ case HTTP:
+ case HTTPS:
+ quiesce = managementModeHttpPort > 0;
+ break;
+ default:
+ quiesce = true;
+ }
+ }
+ }
+ }
+ if (quiesce)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Management mode quiescing entry " + entry);
+ }
+
+ // save original state
+ quiescedEntries.put(entry.getId(), attributes.get(ATTRIBUTE_STATE));
+ }
+ }
+ return quiescedEntries;
+ }
+
+ private Set<Protocol> getPortProtocolsAttribute(Map<String, Object> attributes)
+ {
+ Object object = attributes.get(Port.PROTOCOLS);
+ if (object == null)
+ {
+ return null;
+ }
+ return MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, attributes, Protocol.class);
+ }
+
+ private ConfigurationEntry createEntryWithState(ConfigurationEntry entry, Object state)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes());
+ if (state == null)
+ {
+ attributes.remove(ATTRIBUTE_STATE);
+ }
+ else
+ {
+ attributes.put(ATTRIBUTE_STATE, state);
+ }
+ Set<UUID> originalChildren = entry.getChildrenIds();
+ Set<UUID> children = null;
+ if (originalChildren != null)
+ {
+ children = new HashSet<UUID>(originalChildren);
+ }
+ return new ConfigurationEntry(entry.getId(), entry.getType(), attributes, children, entry.getStore());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java
new file mode 100644
index 0000000000..813702d0a6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java
@@ -0,0 +1,205 @@
+/*
+ *
+ * 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.store;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHost;
+
+public class StoreConfigurationChangeListener implements ConfigurationChangeListener
+{
+ private ConfigurationEntryStore _store;
+
+ public StoreConfigurationChangeListener(ConfigurationEntryStore store)
+ {
+ super();
+ _store = store;
+ }
+
+ @Override
+ public void stateChanged(ConfiguredObject object, State oldState, State newState)
+ {
+ if (newState == State.DELETED)
+ {
+ _store.remove(object.getId());
+ object.removeChangeListener(this);
+ }
+ }
+
+ @Override
+ public void childAdded(ConfiguredObject object, ConfiguredObject child)
+ {
+ // exclude VirtualHost children from storing in broker store
+ if (!(object instanceof VirtualHost))
+ {
+ child.addChangeListener(this);
+ ConfigurationEntry parentEntry = toConfigurationEntry(object);
+ ConfigurationEntry childEntry = toConfigurationEntry(child);
+ _store.save(parentEntry, childEntry);
+ }
+
+ }
+
+ @Override
+ public void childRemoved(ConfiguredObject object, ConfiguredObject child)
+ {
+ _store.save(toConfigurationEntry(object));
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attrinuteName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ _store.save(toConfigurationEntry(object));
+ }
+
+ private ConfigurationEntry toConfigurationEntry(ConfiguredObject object)
+ {
+ Class<? extends ConfiguredObject> objectType = getConfiguredObjectType(object);
+ Set<UUID> childrenIds = getChildernIds(object, objectType);
+ ConfigurationEntry entry = new ConfigurationEntry(object.getId(), objectType.getSimpleName(),
+ object.getActualAttributes(), childrenIds, _store);
+ return entry;
+ }
+
+ private Set<UUID> getChildernIds(ConfiguredObject object, Class<? extends ConfiguredObject> objectType)
+ {
+ // Virtual Host children's IDs should not be stored in broker store
+ if (object instanceof VirtualHost)
+ {
+ return Collections.emptySet();
+ }
+ Set<UUID> childrenIds = new TreeSet<UUID>();
+ Collection<Class<? extends ConfiguredObject>> childClasses = Model.getInstance().getChildTypes(objectType);
+ if (childClasses != null)
+ {
+ for (Class<? extends ConfiguredObject> childClass : childClasses)
+ {
+ Collection<? extends ConfiguredObject> children = object.getChildren(childClass);
+ if (children != null)
+ {
+ for (ConfiguredObject childObject : children)
+ {
+ childrenIds.add(childObject.getId());
+ }
+ }
+ }
+ }
+ return childrenIds;
+ }
+
+ private Class<? extends ConfiguredObject> getConfiguredObjectType(ConfiguredObject object)
+ {
+ if (object instanceof Broker)
+ {
+ return Broker.class;
+ }
+ return getConfiguredObjectTypeFromImplementedInterfaces(object.getClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ private Class<? extends ConfiguredObject> getConfiguredObjectTypeFromImplementedInterfaces(Class<?> objectClass)
+ {
+ // get all implemented interfaces extending ConfiguredObject
+ Set<Class<?>> interfaces = getImplementedInterfacesExtendingSuper(objectClass, ConfiguredObject.class);
+
+ if (interfaces.size() == 0)
+ {
+ throw new RuntimeException("Can not identify the configured object type");
+ }
+
+ if (interfaces.size() == 1)
+ {
+ return (Class<? extends ConfiguredObject>)interfaces.iterator().next();
+ }
+
+ Set<Class<?>> superInterfaces = new HashSet<Class<?>>();
+
+ // find all super interfaces
+ for (Class<?> interfaceClass : interfaces)
+ {
+ for (Class<?> interfaceClass2 : interfaces)
+ {
+ if (interfaceClass != interfaceClass2)
+ {
+ if (interfaceClass.isAssignableFrom(interfaceClass2))
+ {
+ superInterfaces.add(interfaceClass);
+ }
+ }
+ }
+ }
+
+ // remove super interfaces
+ for (Class<?> superInterface : superInterfaces)
+ {
+ interfaces.remove(superInterface);
+ }
+
+ if (interfaces.size() == 1)
+ {
+ return (Class<? extends ConfiguredObject>)interfaces.iterator().next();
+ }
+ else
+ {
+ throw new RuntimeException("Can not identify the configured object type as an it implements"
+ + " more than one configured object interfaces: " + interfaces);
+ }
+
+ }
+
+ private Set<Class<?>> getImplementedInterfacesExtendingSuper(Class<?> classInstance, Class<?> superInterface)
+ {
+ Set<Class<?>> interfaces = new HashSet<Class<?>>();
+ Class<?>[] classInterfaces = classInstance.getInterfaces();
+ for (Class<?> interfaceClass : classInterfaces)
+ {
+ if (interfaceClass!= superInterface && superInterface.isAssignableFrom(interfaceClass))
+ {
+ interfaces.add(interfaceClass);
+ }
+ }
+ Class<?> superClass = classInstance.getSuperclass();
+ if (superClass != null)
+ {
+ Set<Class<?>> superClassInterfaces = getImplementedInterfacesExtendingSuper(superClass, superInterface);
+ interfaces.addAll(superClassInterfaces);
+ }
+ return interfaces;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "StoreConfigurationChangeListener [store=" + _store + "]";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java
index ec471f18e8..e37e58b840 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java
@@ -18,25 +18,24 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.server.configuration.store.factory;
-import java.util.List;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.ConfigurationStoreFactory;
+import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore;
-public abstract class QMFEventClass extends QMFClass
+public class JsonConfigurationStoreFactory implements ConfigurationStoreFactory
{
- public QMFEventClass(String name,
- byte[] schemaHash,
- List<QMFProperty> properties,
- List<QMFStatistic> statistics, List<QMFMethod> methods)
+ @Override
+ public ConfigurationEntryStore createStore()
{
- super(Type.EVENT, name, schemaHash, properties, statistics, methods);
+ return new JsonConfigurationEntryStore();
}
- public QMFEventClass(String name, byte[] schemaHash)
+ @Override
+ public String getStoreType()
{
- super(Type.EVENT, name, schemaHash);
+ return JsonConfigurationEntryStore.STORE_TYPE;
}
- abstract public QMFEventSeverity getSeverity();
-
-} \ No newline at end of file
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java
new file mode 100644
index 0000000000..b6de1e136a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.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.configuration.updater;
+
+import java.util.concurrent.Callable;
+
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+
+public final class ChangeStateTask implements Callable<State>
+{
+ private ConfiguredObject _object;
+ private State _expectedState;
+ private State _desiredState;
+
+ public ChangeStateTask(ConfiguredObject object, State expectedState, State desiredState)
+ {
+ _object = object;
+ _expectedState = expectedState;
+ _desiredState = desiredState;
+ }
+
+ public ConfiguredObject getObject()
+ {
+ return _object;
+ }
+
+ public State getExpectedState()
+ {
+ return _expectedState;
+ }
+
+ public State getDesiredState()
+ {
+ return _desiredState;
+ }
+
+ @Override
+ public State call()
+ {
+ return _object.setDesiredState(_expectedState, _desiredState);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ChangeStateTask [object=" + _object + ", expectedState=" + _expectedState + ", desiredState=" + _desiredState + "]";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java
new file mode 100644
index 0000000000..d3a8f5b797
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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.updater;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public final class CreateChildTask implements Callable<ConfiguredObject>
+{
+ private ConfiguredObject _object;
+ private Class<? extends ConfiguredObject> _childClass;
+ private Map<String, Object> _attributes;
+ private ConfiguredObject[] _otherParents;
+
+ public CreateChildTask(ConfiguredObject object, Class<? extends ConfiguredObject> childClass, Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ _object = object;
+ _childClass = childClass;
+ _attributes = attributes;
+ _otherParents = otherParents;
+ }
+
+ public ConfiguredObject getObject()
+ {
+ return _object;
+ }
+
+ public Class<? extends ConfiguredObject> getChildClass()
+ {
+ return _childClass;
+ }
+
+ public Map<String, Object> getAttributes()
+ {
+ return _attributes;
+ }
+
+ public ConfiguredObject[] getOtherParents()
+ {
+ return _otherParents;
+ }
+
+ @Override
+ public ConfiguredObject call()
+ {
+ return _object.createChild(_childClass, _attributes, _otherParents);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "CreateChildTask [object=" + _object + ", childClass=" + _childClass + ", attributes=" + _attributes
+ + ", otherParents=" + Arrays.toString(_otherParents) + "]";
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java
new file mode 100644
index 0000000000..94649434e6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.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.configuration.updater;
+
+import java.util.concurrent.Callable;
+
+import org.apache.qpid.server.model.ConfiguredObject;
+
+public final class SetAttributeTask implements Callable<Object>
+{
+ private ConfiguredObject _object;
+ private String _attributeName;
+ private Object _expectedValue;
+ private Object _desiredValue;
+
+ public SetAttributeTask(ConfiguredObject object, String attributeName, Object expectedValue, Object desiredValue)
+ {
+ _object = object;
+ _attributeName = attributeName;
+ _expectedValue = expectedValue;
+ _desiredValue = desiredValue;
+ }
+
+ public ConfiguredObject getObject()
+ {
+ return _object;
+ }
+
+ public String getAttributeName()
+ {
+ return _attributeName;
+ }
+
+ public Object getExpectedValue()
+ {
+ return _expectedValue;
+ }
+
+ public Object getDesiredValue()
+ {
+ return _desiredValue;
+ }
+
+ @Override
+ public Object call()
+ {
+ return _object.setAttribute(_attributeName, _expectedValue, _desiredValue);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "SetAttributeTask [object=" + _object + ", attributeName=" + _attributeName + ", expectedValue=" + _expectedValue
+ + ", desiredValue=" + _desiredValue + "]";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
new file mode 100644
index 0000000000..671104d413
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
@@ -0,0 +1,324 @@
+/*
+ *
+ * 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.updater;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.security.auth.Subject;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.security.SecurityManager;
+
+public class TaskExecutor
+{
+ private static final String TASK_EXECUTION_THREAD_NAME = "Broker-Configuration-Thread";
+ private static final Logger LOGGER = Logger.getLogger(TaskExecutor.class);
+
+ private volatile Thread _taskThread;
+ private final AtomicReference<State> _state;
+ private volatile ExecutorService _executor;
+
+ public TaskExecutor()
+ {
+ _state = new AtomicReference<State>(State.INITIALISING);
+ }
+
+ public State getState()
+ {
+ return _state.get();
+ }
+
+ public void start()
+ {
+ if (_state.compareAndSet(State.INITIALISING, State.ACTIVE))
+ {
+ LOGGER.debug("Starting task executor");
+ _executor = Executors.newFixedThreadPool(1, new ThreadFactory()
+ {
+ @Override
+ public Thread newThread(Runnable r)
+ {
+ _taskThread = new Thread(r, TASK_EXECUTION_THREAD_NAME);
+ return _taskThread;
+ }
+ });
+ LOGGER.debug("Task executor is started");
+ }
+ }
+
+ public void stopImmediately()
+ {
+ if (_state.compareAndSet(State.ACTIVE, State.STOPPED))
+ {
+ ExecutorService executor = _executor;
+ if (executor != null)
+ {
+ LOGGER.debug("Stopping task executor immediately");
+ List<Runnable> cancelledTasks = executor.shutdownNow();
+ if (cancelledTasks != null)
+ {
+ for (Runnable runnable : cancelledTasks)
+ {
+ if (runnable instanceof RunnableFuture<?>)
+ {
+ ((RunnableFuture<?>) runnable).cancel(true);
+ }
+ }
+ }
+ _executor = null;
+ _taskThread = null;
+ LOGGER.debug("Task executor was stopped immediately. Number of unfinished tasks: " + cancelledTasks.size());
+ }
+ }
+ }
+
+ public void stop()
+ {
+ if (_state.compareAndSet(State.ACTIVE, State.STOPPED))
+ {
+ ExecutorService executor = _executor;
+ if (executor != null)
+ {
+ LOGGER.debug("Stopping task executor");
+ executor.shutdown();
+ _executor = null;
+ _taskThread = null;
+ LOGGER.debug("Task executor is stopped");
+ }
+ }
+ }
+
+ Future<?> submit(Callable<?> task)
+ {
+ checkState();
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Submitting task: " + task);
+ }
+ Future<?> future = null;
+ if (isTaskExecutorThread())
+ {
+ Object result = executeTaskAndHandleExceptions(task);
+ return new ImmediateFuture(result);
+ }
+ else
+ {
+ future = _executor.submit(new CallableWrapper(task));
+ }
+ return future;
+ }
+
+ public Object submitAndWait(Callable<?> task) throws CancellationException
+ {
+ try
+ {
+ Future<?> future = submit(task);
+ return future.get();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException("Task execution was interrupted: " + task, e);
+ }
+ catch (ExecutionException e)
+ {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException) cause;
+ }
+ else if (cause instanceof Exception)
+ {
+ throw new RuntimeException("Failed to execute user task: " + task, cause);
+ }
+ else if (cause instanceof Error)
+ {
+ throw (Error) cause;
+ }
+ else
+ {
+ throw new RuntimeException("Failed to execute user task: " + task, cause);
+ }
+ }
+ }
+
+ public boolean isTaskExecutorThread()
+ {
+ return Thread.currentThread() == _taskThread;
+ }
+
+ private void checkState()
+ {
+ if (_state.get() != State.ACTIVE)
+ {
+ throw new IllegalStateException("Task executor is not in ACTIVE state");
+ }
+ }
+
+ private Object executeTaskAndHandleExceptions(Callable<?> userTask)
+ {
+ try
+ {
+ return executeTask(userTask);
+ }
+ catch (Exception e)
+ {
+ if (e instanceof RuntimeException)
+ {
+ throw (RuntimeException) e;
+ }
+ throw new RuntimeException("Failed to execute user task: " + userTask, e);
+ }
+ }
+
+ private Object executeTask(Callable<?> userTask) throws Exception
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Performing task " + userTask);
+ }
+ Object result = userTask.call();
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Task " + userTask + " is performed successfully with result:" + result);
+ }
+ return result;
+ }
+
+ private class CallableWrapper implements Callable<Object>
+ {
+ private Callable<?> _userTask;
+ private Subject _securityManagerSubject;
+ private LogActor _actor;
+ private Subject _contextSubject;
+
+ public CallableWrapper(Callable<?> userWork)
+ {
+ _userTask = userWork;
+ _securityManagerSubject = SecurityManager.getThreadSubject();
+ _actor = CurrentActor.get();
+ _contextSubject = Subject.getSubject(AccessController.getContext());
+ }
+
+ @Override
+ public Object call() throws Exception
+ {
+ SecurityManager.setThreadSubject(_securityManagerSubject);
+ CurrentActor.set(_actor);
+
+ try
+ {
+ Object result = null;
+ try
+ {
+ result = Subject.doAs(_contextSubject, new PrivilegedExceptionAction<Object>()
+ {
+ @Override
+ public Object run() throws Exception
+ {
+ return executeTask(_userTask);
+ }
+ });
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw e.getException();
+ }
+ return result;
+ }
+ finally
+ {
+ try
+ {
+ CurrentActor.remove();
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Unxpected exception on current actor removal", e);
+ }
+ try
+ {
+ SecurityManager.setThreadSubject(null);
+ }
+ catch (Exception e)
+ {
+ LOGGER.warn("Unxpected exception on nullifying of subject for a security manager", e);
+ }
+ }
+ }
+ }
+
+ private class ImmediateFuture implements Future<Object>
+ {
+ private Object _result;
+
+ public ImmediateFuture(Object result)
+ {
+ super();
+ this._result = result;
+ }
+
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isDone()
+ {
+ return true;
+ }
+
+ @Override
+ public Object get()
+ {
+ return _result;
+ }
+
+ @Override
+ public Object get(long timeout, TimeUnit unit)
+ {
+ return get();
+ }
+ }
+}
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 512a8c6996..246e056f0b 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
@@ -23,14 +23,12 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ExchangeConfigType;
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.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueRegistry;
@@ -86,8 +84,6 @@ public abstract class AbstractExchange implements Exchange
//TODO : persist creation time
private long _createTime = System.currentTimeMillis();
- private UUID _qmfId;
-
public AbstractExchange(final ExchangeType<? extends Exchange> type)
{
_type = type;
@@ -113,19 +109,12 @@ public abstract class AbstractExchange implements Exchange
_ticket = ticket;
_id = id;
- _qmfId = getConfigStore().createId();
- getConfigStore().addConfiguredObject(this);
_logSubject = new ExchangeLogSubject(this, this.getVirtualHost());
// Log Exchange creation
CurrentActor.get().message(ExchangeMessages.CREATED(String.valueOf(getTypeShortString()), String.valueOf(name), durable));
}
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
public boolean isDurable()
{
return _durable;
@@ -146,7 +135,6 @@ public abstract class AbstractExchange implements Exchange
if(_closed.compareAndSet(false,true))
{
- getConfigStore().removeConfiguredObject(this);
if(_alternateExchange != null)
{
_alternateExchange.removeReference(this);
@@ -298,29 +286,11 @@ public abstract class AbstractExchange implements Exchange
return _id;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public ExchangeConfigType getConfigType()
- {
- return ExchangeConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return _virtualHost;
- }
-
public long getBindingCount()
{
return getBindings().size();
}
-
-
public final List<? extends BaseQueue> route(final InboundMessage message)
{
_receivedMessageCount.incrementAndGet();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
index 5058f91995..5e6e36d330 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
@@ -27,10 +27,9 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.AMQUnknownExchangeType;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.qmf.ManagementExchange;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.model.UUIDGenerator;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.plugin.ExchangeType;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.ArrayList;
@@ -41,42 +40,72 @@ import java.util.UUID;
public class DefaultExchangeFactory implements ExchangeFactory
{
- private static final Logger _logger = Logger.getLogger(DefaultExchangeFactory.class);
public static final String DEFAULT_DLE_NAME_SUFFIX = "_DLE";
- private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>();
+ private static final Logger LOGGER = Logger.getLogger(DefaultExchangeFactory.class);
+
+ private static final AMQShortString[] BASE_EXCHANGE_TYPES =
+ new AMQShortString[]{ExchangeDefaults.DIRECT_EXCHANGE_CLASS,
+ ExchangeDefaults.FANOUT_EXCHANGE_CLASS,
+ ExchangeDefaults.HEADERS_EXCHANGE_CLASS,
+ ExchangeDefaults.TOPIC_EXCHANGE_CLASS};
+
private final VirtualHost _host;
+ private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>();
public DefaultExchangeFactory(VirtualHost host)
{
_host = host;
- registerExchangeType(DirectExchange.TYPE);
- registerExchangeType(TopicExchange.TYPE);
- registerExchangeType(HeadersExchange.TYPE);
- registerExchangeType(FanoutExchange.TYPE);
- registerExchangeType(ManagementExchange.TYPE);
+
+ @SuppressWarnings("rawtypes")
+ Iterable<ExchangeType> exchangeTypes = loadExchangeTypes();
+ for (ExchangeType<?> exchangeType : exchangeTypes)
+ {
+ AMQShortString typeName = exchangeType.getName();
+
+ if(LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug("Registering exchange type '" + typeName + "' using class '" + exchangeType.getClass().getName() + "'");
+ }
+
+ if(_exchangeClassMap.containsKey(typeName))
+ {
+ ExchangeType<?> existingType = _exchangeClassMap.get(typeName);
+
+ throw new IllegalStateException("ExchangeType with type name '" + typeName + "' is already registered using class '"
+ + existingType.getClass().getName() + "', can not register class '"
+ + exchangeType.getClass().getName() + "'");
+ }
+
+ _exchangeClassMap.put(typeName, exchangeType);
+ }
+
+ for(AMQShortString type : BASE_EXCHANGE_TYPES)
+ {
+ if(!_exchangeClassMap.containsKey(type))
+ {
+ throw new IllegalStateException("Did not find expected exchange type: " + type.asString());
+ }
+ }
}
- public void registerExchangeType(ExchangeType<? extends Exchange> type)
+ @SuppressWarnings("rawtypes")
+ protected Iterable<ExchangeType> loadExchangeTypes()
{
- _exchangeClassMap.put(type.getName(), type);
+ return new QpidServiceLoader<ExchangeType>().atLeastOneInstanceOf(ExchangeType.class);
}
public Collection<ExchangeType<? extends Exchange>> getRegisteredTypes()
{
return _exchangeClassMap.values();
}
-
+
public Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes()
{
Collection<ExchangeType<? extends Exchange>> publicTypes =
new ArrayList<ExchangeType<? extends Exchange>>();
publicTypes.addAll(_exchangeClassMap.values());
- //Remove the ManagementExchange type if present, as these
- //are private and cannot be created by external means
- publicTypes.remove(ManagementExchange.TYPE);
-
return publicTypes;
}
@@ -120,42 +149,4 @@ public class DefaultExchangeFactory implements ExchangeFactory
Exchange e = exchType.newInstance(id, _host, exchange, durable, ticket, autoDelete);
return e;
}
-
- public void initialise(VirtualHostConfiguration hostConfig)
- {
-
- if (hostConfig == null)
- {
- return;
- }
-
- for(Object className : hostConfig.getCustomExchanges())
- {
- try
- {
- ExchangeType<?> exchangeType = ApplicationRegistry.getInstance().getPluginManager().getExchanges().get(String.valueOf(className));
- if (exchangeType == null)
- {
- _logger.error("No such custom exchange class found: \""+String.valueOf(className)+"\"");
- continue;
- }
- Class<? extends ExchangeType> exchangeTypeClass = exchangeType.getClass();
- ExchangeType<? extends ExchangeType> type = exchangeTypeClass.newInstance();
- registerExchangeType(type);
- }
- catch (ClassCastException classCastEx)
- {
- _logger.error("No custom exchange class: \""+String.valueOf(className)+"\" cannot be registered as it does not extend class \""+ExchangeType.class+"\"");
- }
- catch (IllegalAccessException e)
- {
- _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e);
- }
- catch (InstantiationException e)
- {
- _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e);
- }
- }
-
- }
}
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 07813b073b..9cce8d640b 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
@@ -26,6 +26,7 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
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 92326412c1..fc6ce15bc4 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
@@ -20,30 +20,22 @@
*/
package org.apache.qpid.server.exchange;
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import javax.management.JMException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
public class DirectExchange extends AbstractExchange
{
- private static final Logger _logger = Logger.getLogger(DirectExchange.class);
-
private static final class BindingSet
{
private CopyOnWriteArraySet<Binding> _bindings = new CopyOnWriteArraySet<Binding>();
@@ -55,7 +47,6 @@ public class DirectExchange extends AbstractExchange
recalculateQueues();
}
-
public synchronized void removeBinding(Binding binding)
{
_bindings.remove(binding);
@@ -91,36 +82,7 @@ public class DirectExchange extends AbstractExchange
private final ConcurrentHashMap<String, BindingSet> _bindingsByKey =
new ConcurrentHashMap<String, BindingSet>();
- public static final ExchangeType<DirectExchange> TYPE = new ExchangeType<DirectExchange>()
- {
-
- public AMQShortString getName()
- {
- return ExchangeDefaults.DIRECT_EXCHANGE_CLASS;
- }
-
- public Class<DirectExchange> getExchangeClass()
- {
- return DirectExchange.class;
- }
-
- public DirectExchange newInstance(UUID id, VirtualHost host,
- AMQShortString name,
- boolean durable,
- int ticket,
- boolean autoDelete) throws AMQException
- {
- DirectExchange exch = new DirectExchange();
- exch.initialise(id, host,name,durable,ticket,autoDelete);
- return exch;
- }
-
- public AMQShortString getDefaultExchangeName()
- {
- return ExchangeDefaults.DIRECT_EXCHANGE_NAME;
- }
- };
-
+ public static final ExchangeType<DirectExchange> TYPE = new DirectExchangeType();
public DirectExchange()
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java
new file mode 100644
index 0000000000..096d5265ed
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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 java.util.UUID;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+public class DirectExchangeType implements ExchangeType<DirectExchange>
+{
+ public AMQShortString getName()
+ {
+ return ExchangeDefaults.DIRECT_EXCHANGE_CLASS;
+ }
+
+ public DirectExchange newInstance(UUID id, VirtualHost host,
+ AMQShortString name,
+ boolean durable,
+ int ticket,
+ boolean autoDelete) throws AMQException
+ {
+ DirectExchange exch = new DirectExchange();
+ exch.initialise(id, host,name,durable,ticket,autoDelete);
+ return exch;
+ }
+
+ public AMQShortString getDefaultExchangeName()
+ {
+ return ExchangeDefaults.DIRECT_EXCHANGE_NAME;
+ }
+}
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 762686e68d..4bafb04c33 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
@@ -26,8 +26,8 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.ExchangeConfig;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -38,9 +38,23 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
-public interface Exchange extends ExchangeReferrer, ExchangeConfig
+public interface Exchange extends ExchangeReferrer
{
+ String getName();
+
+ ExchangeType getType();
+
+ long getBindingCount();
+
+ long getByteDrops();
+
+ long getByteReceives();
+
+ long getMsgDrops();
+
+ long getMsgReceives();
+
public interface BindingListener
{
void bindingAdded(Exchange exchange, Binding binding);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
index aae4ae89bb..e602d476d9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.plugin.ExchangeType;
import java.util.Collection;
import java.util.UUID;
@@ -34,8 +34,6 @@ public interface ExchangeFactory
int ticket)
throws AMQException;
- void initialise(VirtualHostConfiguration hostConfig);
-
Collection<ExchangeType<? extends Exchange>> getRegisteredTypes();
Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java
index ba4f57a8e0..edb476f3aa 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java
@@ -24,6 +24,7 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.store.DurableConfigurationStore;
public class ExchangeInitialiser
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 5f4998f77f..8c433ce985 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
@@ -22,19 +22,15 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import javax.management.JMException;
import java.util.ArrayList;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class FanoutExchange extends AbstractExchange
@@ -48,35 +44,7 @@ public class FanoutExchange extends AbstractExchange
*/
private final ConcurrentHashMap<AMQQueue,Integer> _queues = new ConcurrentHashMap<AMQQueue,Integer>();
- public static final ExchangeType<FanoutExchange> TYPE = new ExchangeType<FanoutExchange>()
- {
-
- public AMQShortString getName()
- {
- return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
- }
-
- public Class<FanoutExchange> getExchangeClass()
- {
- return FanoutExchange.class;
- }
-
- public FanoutExchange newInstance(UUID id, VirtualHost host,
- AMQShortString name,
- boolean durable,
- int ticket,
- boolean autoDelete) throws AMQException
- {
- FanoutExchange exch = new FanoutExchange();
- exch.initialise(id, host, name, durable, ticket, autoDelete);
- return exch;
- }
-
- public AMQShortString getDefaultExchangeName()
- {
- return ExchangeDefaults.FANOUT_EXCHANGE_NAME;
- }
- };
+ public static final ExchangeType<FanoutExchange> TYPE = new FanoutExchangeType();
public FanoutExchange()
{
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java
index 34b2a851dc..0371a363de 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java
@@ -18,28 +18,34 @@
* under the License.
*
*/
+package org.apache.qpid.server.exchange;
-package org.apache.qpid.qmf;
+import java.util.UUID;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBEncoder;
-public class QMFBrokerResponseCommand extends QMFCommand
+public class FanoutExchangeType implements ExchangeType<FanoutExchange>
{
- private QMFCommandHeader _header;
- private VirtualHost _virtualHost;
+ public AMQShortString getName()
+ {
+ return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
+ }
- public QMFBrokerResponseCommand(QMFBrokerRequestCommand qmfBrokerRequestCommand, VirtualHost virtualHost)
+ public FanoutExchange newInstance(UUID id, VirtualHost host, AMQShortString name,
+ boolean durable, int ticket, boolean autoDelete)
+ throws AMQException
{
- super( new QMFCommandHeader(qmfBrokerRequestCommand.getHeader().getVersion(),
- qmfBrokerRequestCommand.getHeader().getSeq(),
- QMFOperation.BROKER_RESPONSE));
- _virtualHost = virtualHost;
+ FanoutExchange exch = new FanoutExchange();
+ exch.initialise(id, host, name, durable, ticket, autoDelete);
+ return exch;
}
- public void encode(BBEncoder encoder)
+ public AMQShortString getDefaultExchangeName()
{
- super.encode(encoder);
- encoder.writeUuid(_virtualHost.getBrokerId());
+ return ExchangeDefaults.FANOUT_EXCHANGE_NAME;
}
}
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 6bad59c2ae..746c8ac6bc 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
@@ -22,22 +22,18 @@ package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import javax.management.JMException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -81,40 +77,12 @@ public class HeadersExchange extends AbstractExchange
new CopyOnWriteArrayList<HeadersBinding>();
- public static final ExchangeType<HeadersExchange> TYPE = new ExchangeType<HeadersExchange>()
- {
-
- public AMQShortString getName()
- {
- return ExchangeDefaults.HEADERS_EXCHANGE_CLASS;
- }
-
- public Class<HeadersExchange> getExchangeClass()
- {
- return HeadersExchange.class;
- }
-
- public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket,
- boolean autoDelete) throws AMQException
- {
- HeadersExchange exch = new HeadersExchange();
-
- exch.initialise(id, host, name, durable, ticket, autoDelete);
- return exch;
- }
-
- public AMQShortString getDefaultExchangeName()
- {
-
- return ExchangeDefaults.HEADERS_EXCHANGE_NAME;
- }
- };
+ public static final ExchangeType<HeadersExchange> TYPE = new HeadersExchangeType();
public HeadersExchange()
{
super(TYPE);
}
-
public ArrayList<BaseQueue> doRoute(InboundMessage payload)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java
index 191f8041d2..ed4d57d0f8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java
@@ -18,44 +18,35 @@
* under the License.
*
*/
-package org.apache.qpid.server.virtualhost.plugins;
+package org.apache.qpid.server.exchange;
-import org.apache.log4j.Logger;
+import java.util.UUID;
-import org.apache.qpid.server.virtualhost.HouseKeepingTask;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import java.util.concurrent.TimeUnit;
-
-public abstract class VirtualHostHouseKeepingPlugin extends HouseKeepingTask implements VirtualHostPlugin
+public class HeadersExchangeType implements ExchangeType<HeadersExchange>
{
- private final Logger _logger = Logger.getLogger(getClass());
-
- public VirtualHostHouseKeepingPlugin(VirtualHost vhost)
+ public AMQShortString getName()
{
- super(vhost);
+ return ExchangeDefaults.HEADERS_EXCHANGE_CLASS;
}
+ public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket,
+ boolean autoDelete) throws AMQException
+ {
+ HeadersExchange exch = new HeadersExchange();
- /**
- * Long value representing the delay between repeats
- *
- * @return
- */
- public abstract long getDelay();
-
- /**
- * Option to specify what the delay value represents
- *
- * @return
- *
- * @see java.util.concurrent.TimeUnit for valid value.
- */
- public abstract TimeUnit getTimeUnit();
-
+ exch.initialise(id, host, name, durable, ticket, autoDelete);
+ return exch;
+ }
- protected Logger getLogger()
+ public AMQShortString getDefaultExchangeName()
{
- return _logger;
+
+ return ExchangeDefaults.HEADERS_EXCHANGE_NAME;
}
}
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 0ce16bd3f7..6d548be508 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
@@ -27,15 +27,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
-import javax.management.JMException;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.filter.SelectorParsingException;
import org.apache.qpid.filter.selector.ParseException;
import org.apache.qpid.filter.selector.TokenMgrError;
@@ -49,44 +45,15 @@ import org.apache.qpid.server.exchange.topic.TopicParser;
import org.apache.qpid.server.filter.JMSSelectorFilter;
import org.apache.qpid.server.filter.MessageFilter;
import org.apache.qpid.server.message.InboundMessage;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.Filterable;
-import org.apache.qpid.server.virtualhost.VirtualHost;
public class TopicExchange extends AbstractExchange
{
-
- public static final ExchangeType<TopicExchange> TYPE = new ExchangeType<TopicExchange>()
- {
-
- public AMQShortString getName()
- {
- return ExchangeDefaults.TOPIC_EXCHANGE_CLASS;
- }
-
- public Class<TopicExchange> getExchangeClass()
- {
- return TopicExchange.class;
- }
-
- public TopicExchange newInstance(UUID id, VirtualHost host,
- AMQShortString name,
- boolean durable,
- int ticket,
- boolean autoDelete) throws AMQException
- {
- TopicExchange exch = new TopicExchange();
- exch.initialise(id, host, name, durable, ticket, autoDelete);
- return exch;
- }
-
- public AMQShortString getDefaultExchangeName()
- {
- return ExchangeDefaults.TOPIC_EXCHANGE_NAME;
- }
- };
+ public static final ExchangeType<TopicExchange> TYPE = new TopicExchangeType();
private static final Logger _logger = Logger.getLogger(TopicExchange.class);
@@ -291,7 +258,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
{
- Binding binding = new Binding(null, null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments));
+ Binding binding = new Binding(null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments));
if (arguments == null)
{
@@ -314,7 +281,7 @@ public class TopicExchange extends AbstractExchange
public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue)
{
- Binding binding = new Binding(null, null, bindingKey, queue, this, arguments);
+ Binding binding = new Binding(null, bindingKey, queue, this, arguments);
if (arguments == null)
{
return _bindings.containsKey(binding);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java
new file mode 100644
index 0000000000..25a3549e61
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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 java.util.UUID;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+public class TopicExchangeType implements ExchangeType<TopicExchange>
+{
+ public AMQShortString getName()
+ {
+ return ExchangeDefaults.TOPIC_EXCHANGE_CLASS;
+ }
+
+ public TopicExchange newInstance(UUID id, VirtualHost host,
+ AMQShortString name,
+ boolean durable,
+ int ticket,
+ boolean autoDelete) throws AMQException
+ {
+ TopicExchange exch = new TopicExchange();
+ exch.initialise(id, host, name, durable, ticket, autoDelete);
+ return exch;
+ }
+
+ public AMQShortString getDefaultExchangeName()
+ {
+ return ExchangeDefaults.TOPIC_EXCHANGE_NAME;
+ }
+}
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
deleted file mode 100644
index 7eb476b15a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
+++ /dev/null
@@ -1,913 +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.federation;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQStoreException;
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.BridgeConfig;
-import org.apache.qpid.server.configuration.BridgeConfigType;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.flow.FlowCreditManager_0_10;
-import org.apache.qpid.server.flow.WindowCreditManager;
-import org.apache.qpid.server.message.MessageMetaData_0_10;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.AMQQueueFactory;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
-import org.apache.qpid.server.subscription.Subscription_0_10;
-import org.apache.qpid.server.transport.ServerSession;
-import org.apache.qpid.server.txn.AutoCommitTransaction;
-import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.DeliveryProperties;
-import org.apache.qpid.transport.MessageAcceptMode;
-import org.apache.qpid.transport.MessageAcquireMode;
-import org.apache.qpid.transport.MessageCreditUnit;
-import org.apache.qpid.transport.MessageFlowMode;
-import org.apache.qpid.transport.MessageReject;
-import org.apache.qpid.transport.MessageRejectCode;
-import org.apache.qpid.transport.MessageTransfer;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.RangeSet;
-import org.apache.qpid.transport.RangeSetFactory;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.SessionListener;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-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.ConcurrentMap;
-
-public class Bridge implements BridgeConfig
-{
- private static final String DURABLE = "durable";
- private static final String DYNAMIC = "dynamic";
- private static final String SRC_IS_QUEUE = "srcIsQueue";
- private static final String SRC_IS_LOCAL = "srcIsLocal";
- private static final String SOURCE = "source";
- private static final String DESTINATION = "destination";
- private static final String KEY = "key";
- private static final String TAG = "tag";
- private static final String EXCLUDES = "excludes";
- private final boolean _durable;
- private final boolean _dynamic;
- private final boolean _queueBridge;
- private final boolean _localSource;
- private final String _source;
- private final String _destination;
- private final String _key;
- private final String _tag;
- private final String _excludes;
- private final BrokerLink _link;
- private UUID _qmfId;
- private long _createTime = System.currentTimeMillis();
-
- private Session _session;
-
- private BridgeImpl _delegate;
-
- private final int _bridgeNo;
- private AutoCommitTransaction _transaction;
-
- public Bridge(final BrokerLink brokerLink,
- final int bridgeNo,
- final boolean durable,
- final boolean dynamic,
- final boolean srcIsQueue,
- final boolean srcIsLocal,
- final String src,
- final String dest,
- final String key,
- final String tag,
- final String excludes)
- {
- _link = brokerLink;
- _bridgeNo = bridgeNo;
- _durable = durable;
- _dynamic = dynamic;
- _queueBridge = srcIsQueue;
- _localSource = srcIsLocal;
- _source = src;
- _destination = dest;
- _key = key;
- _tag = tag;
- _excludes = excludes;
- _qmfId = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId();
-
- _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
-
- if(durable)
- {
- try
- {
- brokerLink.getVirtualHost().getMessageStore().createBridge(this);
- }
- catch (AMQStoreException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- createDelegate();
- }
-
- private void createDelegate()
- {
- if(_dynamic)
- {
- if(_localSource)
- {
- // TODO
- }
- else
- {
- if(_queueBridge)
- {
- // TODO
- }
- else
- {
- _delegate = new DynamicExchangeBridge();
- }
- }
- }
- else
- {
- if(_localSource)
- {
- if(_queueBridge)
- {
- _delegate = new StaticQueuePushBridge();
- }
- else
- {
- _delegate = new StaticExchangePushBridge();
- }
- }
- else
- {
- if(_queueBridge)
- {
- _delegate = new StaticQueuePullBridge();
- }
- else
- {
- _delegate = new StaticExchangePullBridge();
- }
- }
- }
- }
-
- public Bridge(final BrokerLink brokerLink,
- final int bridgeNo,
- final UUID id,
- final long createTime,
- final Map<String, String> arguments)
- {
- _link = brokerLink;
- _bridgeNo = bridgeNo;
- _qmfId = id;
- brokerLink.getConfigStore().persistentIdInUse(id);
- _createTime = createTime;
-
- _durable = Boolean.valueOf(arguments.get(DURABLE));
- _dynamic = Boolean.valueOf(arguments.get(DYNAMIC));
- _queueBridge = Boolean.valueOf(arguments.get(SRC_IS_QUEUE));
- _localSource = Boolean.valueOf(arguments.get(SRC_IS_LOCAL));
- _source = arguments.get(SOURCE);
- _destination = arguments.get(DESTINATION);
- _key = arguments.get(KEY);
- _tag = arguments.get(TAG);
- _excludes = arguments.get(EXCLUDES);
-
- //TODO.
- _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore());
-
-
- if(_durable)
- {
- try
- {
- brokerLink.getVirtualHost().getMessageStore().createBridge(this);
- }
- catch (AMQStoreException e)
- {
- throw new RuntimeException(e);
- }
- }
-
- createDelegate();
- }
-
-
- public Map<String,String> getArguments()
- {
- Map<String,String> arguments = new HashMap<String, String>();
-
- arguments.put(DURABLE, String.valueOf(_durable));
- arguments.put(DYNAMIC, String.valueOf(_dynamic));
- arguments.put(SRC_IS_QUEUE, String.valueOf(_queueBridge));
- arguments.put(SRC_IS_LOCAL, String.valueOf(_localSource));
- arguments.put(SOURCE, _source);
- arguments.put(DESTINATION, _destination);
- arguments.put(KEY, _key);
- arguments.put(TAG, _tag);
- arguments.put(EXCLUDES, _excludes);
-
- return Collections.unmodifiableMap(arguments);
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public BridgeConfigType getConfigType()
- {
- return BridgeConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getLink();
- }
-
- public boolean isDurable()
- {
- return _durable;
- }
-
- public boolean isDynamic()
- {
- return _dynamic;
- }
-
- public boolean isQueueBridge()
- {
- return _queueBridge;
- }
-
- public boolean isLocalSource()
- {
- return _localSource;
- }
-
- public String getSource()
- {
- return _source;
- }
-
- public String getDestination()
- {
- return _destination;
- }
-
- public String getKey()
- {
- return _key;
- }
-
- public String getTag()
- {
- return _tag;
- }
-
- public String getExcludes()
- {
- return _excludes;
- }
-
- public BrokerLink getLink()
- {
- return _link;
- }
-
- public Integer getChannelId()
- {
- return (_session == null) ? 0 : _session.getChannel();
- }
-
- public int getAckBatching()
- {
- return 0;
- }
-
- public long getCreateTime()
- {
- return _createTime;
- }
-
- @Override
- public boolean equals(final Object o)
- {
- if (this == o)
- {
- return true;
- }
- if (o == null || getClass() != o.getClass())
- {
- return false;
- }
-
- final Bridge bridge = (Bridge) o;
-
- if (_durable != bridge._durable)
- {
- return false;
- }
- if (_dynamic != bridge._dynamic)
- {
- return false;
- }
- if (_localSource != bridge._localSource)
- {
- return false;
- }
- if (_queueBridge != bridge._queueBridge)
- {
- return false;
- }
- if (_destination != null ? !_destination.equals(bridge._destination) : bridge._destination != null)
- {
- return false;
- }
- if (_excludes != null ? !_excludes.equals(bridge._excludes) : bridge._excludes != null)
- {
- return false;
- }
- if (_key != null ? !_key.equals(bridge._key) : bridge._key != null)
- {
- return false;
- }
- if (_source != null ? !_source.equals(bridge._source) : bridge._source != null)
- {
- return false;
- }
- if (_tag != null ? !_tag.equals(bridge._tag) : bridge._tag != null)
- {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode()
- {
- int result = (_durable ? 1 : 0);
- result = 31 * result + (_dynamic ? 1 : 0);
- result = 31 * result + (_queueBridge ? 1 : 0);
- result = 31 * result + (_localSource ? 1 : 0);
- result = 31 * result + (_source != null ? _source.hashCode() : 0);
- result = 31 * result + (_destination != null ? _destination.hashCode() : 0);
- result = 31 * result + (_key != null ? _key.hashCode() : 0);
- result = 31 * result + (_tag != null ? _tag.hashCode() : 0);
- result = 31 * result + (_excludes != null ? _excludes.hashCode() : 0);
- return result;
- }
-
- public void setSession(final Session session)
- {
- _session = session;
- _delegate.setSession(session);
- }
-
- private long getMessageWindowSize()
- {
- return 10l;
- }
-
-
- VirtualHost getVirtualHost()
- {
- return _link.getVirtualHost();
- }
-
- public void close()
- {
- // TODO
- _delegate.close();
- _session = null;
- }
-
-
-
- private interface BridgeImpl
- {
- void setSession(Session session);
-
- void close();
- }
-
- private abstract class AbstractPullBridge implements BridgeImpl, SessionListener
- {
- public final void setSession(final Session session)
- {
- session.setSessionListener(this);
- onSession();
-
- }
-
- abstract void onSession();
-
-
-
- public void message(final Session ssn, final MessageTransfer xfr)
- {
- ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
-
- Exchange exchange = exchangeRegistry.getExchange(_destination);
-
- // TODO - deal with exchange not existing
-
- DeliveryProperties delvProps = null;
- if(xfr.getHeader() != null && (delvProps = xfr.getHeader().getDeliveryProperties()) != null && delvProps.hasTtl() &&
- !delvProps.hasExpiration())
- {
- delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
- }
-
- MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
- final MessageStore store = getVirtualHost().getMessageStore();
- StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData);
- storeMessage.addContent(0,xfr.getBody());
- storeMessage.flushToStore();
- MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)_session).getReference());
-
- List<? extends BaseQueue> queues = exchange.route(message);
-
-
-
- if(queues != null && queues.size() != 0)
- {
- enqueue(message, queues);
- }
- else
- {
- if(delvProps == null || !delvProps.hasDiscardUnroutable() || !delvProps.getDiscardUnroutable())
- {
- if(xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT)
- {
- RangeSet rejects = RangeSetFactory.createRangeSet();
- rejects.add(xfr.getId());
- MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
- ssn.invoke(reject);
- }
- else
- {
- Exchange alternate = exchange.getAlternateExchange();
- if(alternate != null)
- {
- queues = alternate.route(message);
- if(queues != null && queues.size() != 0)
- {
- enqueue(message, queues);
- }
- else
- {
- //TODO - log the message discard
- }
- }
- else
- {
- //TODO - log the message discard
- }
-
-
- }
- }
-
-
- }
-
- ssn.processed(xfr);
-
- }
-
-
- private void enqueue(final ServerMessage message, final List<? extends BaseQueue> queues)
- {
- _transaction.enqueue(queues,message, new ServerTransaction.Action()
- {
-
- private BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
-
- public void postCommit()
- {
- for(int i = 0; i < _queues.length; i++)
- {
- try
- {
- _queues[i].enqueue(message);
- }
- catch (AMQException e)
- {
- // TODO
-
- throw new RuntimeException(e);
- }
- }
- }
-
- public void onRollback()
- {
- // NO-OP
- }
- }, 0L);
- }
-
- public void exception(final Session session, final SessionException exception)
- {
- // TODO - Handle exceptions
- }
-
- public void closed(final Session session)
- {
- // TODO - handle close
- }
-
- public void opened(final Session session)
- {
- // this method never called
- }
-
- public void resumed(final Session session)
- {
- // will never resume these sessions
- }
-
-
-
- }
-
- private final class StaticExchangePullBridge extends AbstractPullBridge
- {
- private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();;
-
- public void onSession()
- {
-
- final HashMap<String, Object> options = new HashMap<String, Object>();
- options.put("qpid.trace.exclude", _link.getFederationTag());
- options.put("qpid.trace.id",_link.getRemoteFederationTag());
- _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE);
- _session.sync();
- // todo check exception
- final Map<String,Object> bindingArgs = new HashMap<String,Object>();
- _session.exchangeBind(_tmpQueueName, _source, _key, bindingArgs);
- _session.sync();
- // todo check exception
-
- final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
- final String subName = String.valueOf(_bridgeNo);
- _session.messageSubscribe(_tmpQueueName,
- subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
- _session.sync();
- // todo check exception
-
- _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
- _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
- _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
-
- }
-
- public void close()
- {
- // TODO
- }
- }
-
- private final class StaticQueuePullBridge extends AbstractPullBridge
- {
-
- public void onSession()
- {
-
- final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
- final String subName = String.valueOf(_bridgeNo);
- _session.messageSubscribe(_source,
- subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
- _session.sync();
- // todo check exception
-
- _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
- _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
- _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
-
- }
-
- public void close()
- {
- // TODO
- }
- }
-
- private final class DynamicExchangeBridge extends AbstractPullBridge implements Exchange.BindingListener
- {
- private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();
-
- private final ConcurrentMap<Binding,Binding> _bindings = new ConcurrentHashMap<Binding,Binding>();
-
-
- void onSession()
- {
-
-
- final HashMap<String, Object> options = new HashMap<String, Object>();
- options.put("qpid.trace.exclude", _link.getFederationTag());
- options.put("qpid.trace.id",_link.getRemoteFederationTag());
- _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE);
- _session.sync();
- // todo - check exception
-
- final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP;
- final String subName = String.valueOf(_bridgeNo);
- _session.messageSubscribe(_tmpQueueName,
- subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions);
- _session.sync();
- // todo check exception
- _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW);
- _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize());
- _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF);
- _session.sync();
- // todo check exception
-
-
- ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
-
- Exchange exchange = exchangeRegistry.getExchange(_destination);
-
- // TODO - check null
-
- exchange.addBindingListener(this);
-
- Collection<Binding> bindings = exchange.getBindings();
- for(Binding binding : bindings)
- {
- propogateBinding(binding);
- }
-
- }
-
- private void propogateBinding(final Binding binding)
- {
- if(_bindings.putIfAbsent(binding,binding)== null)
- {
- Map<String,Object> arguments = new HashMap<String,Object>(binding.getArguments());
-
- if(arguments.get("qpid.fed.origin") == null)
- {
- arguments.put("qpid.fed.op","");
- arguments.put("qpid.fed.origin",_link.getFederationTag());
- arguments.put("qpid.fed.tags",_link.getFederationTag());
- }
- else
- {
- String tags = (String) arguments.get("qpid.fed.tags");
- if(tags == null)
- {
- tags = _link.getFederationTag();
- }
- else
- {
- if(Arrays.asList(tags.split(",")).contains(_link.getFederationTag()))
- {
- return;
- }
- tags += "," + _link.getFederationTag();
- }
- arguments.put("qpid.fed.tags", tags);
- }
-
- _session.exchangeBind(_tmpQueueName, _source, binding.getBindingKey(), arguments);
- _session.sync();
- // TODO - check exception?
-
- }
- }
-
- private void propogateBindingRemoval(final Binding binding)
- {
- if(_bindings.remove(binding) != null)
- {
- // TODO - this is wrong!!!!
- _session.exchangeUnbind(_tmpQueueName, _source, binding.getBindingKey());
- }
- }
-
-
- public void bindingAdded(final Exchange exchange, final Binding binding)
- {
- propogateBinding(binding);
- }
-
- public void bindingRemoved(final Exchange exchange, final Binding binding)
- {
- propogateBindingRemoval(binding);
- }
-
- public void close()
- {
- // TODO
- }
- }
-
- private class StaticExchangePushBridge implements BridgeImpl, SessionListener
- {
- private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();
- private AMQQueue _queue;
-
- public void setSession(final Session session)
- {
- assert session instanceof ServerSession;
-
- session.setSessionListener(this);
-
- ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
-
- Exchange exchange = exchangeRegistry.getExchange(_source);
-
- // TODO - Check null
-
- final HashMap<String, Object> options = new HashMap<String, Object>();
- options.put("qpid.trace.exclude", _link.getFederationTag());
- options.put("qpid.trace.id",_link.getRemoteFederationTag());
-
- try
- {
- _queue = AMQQueueFactory.createAMQQueueImpl(null,
- _tmpQueueName,
- isDurable(),
- _link.getFederationTag(),
- false,
- false,
- getVirtualHost(), options);
- }
- catch (AMQException e)
- {
- // TODO
- throw new RuntimeException(e);
- }
-
- FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize());
-
- //TODO Handle the passing of non-null Filters and Arguments here
-
- Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session,
- _destination,
- MessageAcceptMode.NONE,
- MessageAcquireMode.PRE_ACQUIRED,
- MessageFlowMode.WINDOW,
- creditManager, null,null);
-
- ((ServerSession)session).register(_destination, sub);
-
- try
- {
- _queue.registerSubscription(sub, true);
- getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.<String, Object>emptyMap());
- }
- catch (AMQException e)
- {
- // TODO
- throw new RuntimeException(e);
- }
- }
-
- public void close()
- {
- // TODO
- }
-
- public void opened(final Session session)
- {
- // this method never called
- }
-
- public void resumed(final Session session)
- {
- // this session will never be resumed
- }
-
- public void message(final Session ssn, final MessageTransfer xfr)
- {
- // messages should not be sent ... should probably log error
- }
-
- public void exception(final Session session, final SessionException exception)
- {
- // TODO
- }
-
- public void closed(final Session session)
- {
- // TODO
- }
- }
-
- private class StaticQueuePushBridge implements BridgeImpl, SessionListener
- {
- private AMQQueue _queue;
-
- public void setSession(final Session session)
- {
- assert session instanceof ServerSession;
-
- session.setSessionListener(this);
-
- QueueRegistry queueRegistry = getVirtualHost().getQueueRegistry();
-
- _queue = queueRegistry.getQueue(_source);
-
- // TODO - null check
-
- FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize());
-
- //TODO Handle the passing of non-null Filters and Arguments here
-
- Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session,
- _destination,
- MessageAcceptMode.NONE,
- MessageAcquireMode.PRE_ACQUIRED,
- MessageFlowMode.WINDOW,
- creditManager, null,null);
-
- ((ServerSession)session).register(_destination, sub);
-
- try
- {
- _queue.registerSubscription(sub, false);
- }
- catch (AMQException e)
- {
- // TODO
- throw new RuntimeException(e);
- }
-
- }
-
- public void close()
- {
- // TODO
- }
-
- public void opened(final Session session)
- {
- // never called
- }
-
- public void resumed(final Session session)
- {
- // session will not resume
- }
-
- public void message(final Session ssn, final MessageTransfer xfr)
- {
- // should never be called ... should probably log error
- }
-
- public void exception(final Session session, final SessionException exception)
- {
- // TODO
- }
-
- public void closed(final Session session)
- {
- // TODO
- }
- }
-
-}
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
deleted file mode 100644
index 1ef57c53cb..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
+++ /dev/null
@@ -1,692 +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.federation;
-
-import org.apache.qpid.AMQStoreException;
-import org.apache.qpid.common.ServerPropertyNames;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ConnectionConfig;
-import org.apache.qpid.server.configuration.ConnectionConfigType;
-import org.apache.qpid.server.configuration.LinkConfig;
-import org.apache.qpid.server.configuration.LinkConfigType;
-import org.apache.qpid.server.transport.ServerSession;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.Binary;
-import org.apache.qpid.transport.ClientDelegate;
-import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionException;
-import org.apache.qpid.transport.ConnectionListener;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.Session;
-import org.apache.qpid.transport.SessionDelegate;
-import org.apache.qpid.transport.TransportException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-import java.io.IOException;
-import java.util.Collections;
-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.ConcurrentLinkedQueue;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-
-public class BrokerLink implements LinkConfig, ConnectionListener
-{
-
- private static final int CORE_POOL_SIZE = 4;
-
- private static final ScheduledThreadPoolExecutor _threadPool =
- new ScheduledThreadPoolExecutor(CORE_POOL_SIZE);
- private static final String TRANSPORT = "transport";
- private static final String HOST = "host";
- private static final String PORT = "port";
- private static final String REMOTE_VHOST = "remoteVhost";
- private static final String DURABLE = "durable";
- private static final String AUTH_MECHANISM = "authMechanism";
- private static final String USERNAME = "username";
- private static final String PASSWORD = "password";
-
-
- private final String _transport;
- private final String _host;
- private final int _port;
- private final String _remoteVhost;
- private final boolean _durable;
- private final String _authMechanism;
- private final String _username;
- private final String _password;
- private final VirtualHost _virtualHost;
- private UUID _qmfId;
- private AtomicBoolean _closing = new AtomicBoolean();
- private final long _createTime;
- private Connection _qpidConnection;
- private AtomicReference<Thread> _executor = new AtomicReference<Thread>();
- private AtomicInteger _bridgeId = new AtomicInteger();
-
- private final ConcurrentHashMap<Bridge,Bridge> _bridges = new ConcurrentHashMap<Bridge,Bridge>();
- private final ConcurrentHashMap<Bridge,Bridge> _activeBridges = new ConcurrentHashMap<Bridge,Bridge>();
- private final ConcurrentLinkedQueue<Bridge> _pendingBridges = new ConcurrentLinkedQueue<Bridge>();
- private String _remoteFederationTag;
-
- private ConnectionConfig _connectionConfig;
- private ConnectionException _exception;
- private String _lastErrorMessage;
- private int _retryDelay = 1;
- private final Runnable _makeConnectionTask = new Runnable()
- {
- public void run()
- {
- doMakeConnection();
- }
- };
-
-
-
-
- public static enum State
- {
- OPERATIONAL,
- DOWN,
- ESTABLISHING,
- DELETED
- }
-
-
- private volatile State _state = State.DOWN;
-
- private static final AtomicReferenceFieldUpdater<BrokerLink, State> _stateUpdater =
- AtomicReferenceFieldUpdater.newUpdater(BrokerLink.class, State.class, "_state");
-
- private class ConnectionConfigAdapter implements ConnectionConfig
- {
- private long _adapterCreateTime = System.currentTimeMillis();
- private UUID _qmfId = BrokerLink.this.getConfigStore().createId();
-
- public VirtualHost getVirtualHost()
- {
- return BrokerLink.this.getVirtualHost();
- }
-
- public String getAddress()
- {
- return _host+":"+_port;
- }
-
- public Boolean isIncoming()
- {
- return false;
- }
-
- public Boolean isSystemConnection()
- {
- return true;
- }
-
- public Boolean isFederationLink()
- {
- return true;
- }
-
- public String getAuthId()
- {
- return _username;
- }
-
- public String getRemoteProcessName()
- {
- return null;
- }
-
- public Integer getRemotePID()
- {
- return null;
- }
-
- public Integer getRemoteParentPID()
- {
- return null;
- }
-
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public ConnectionConfigType getConfigType()
- {
- return ConnectionConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public long getCreateTime()
- {
- return _adapterCreateTime;
- }
-
- public Boolean isShadow()
- {
- return false;
- }
-
- public void mgmtClose()
- {
- _connectionConfig.mgmtClose();
- }
- }
-
- private class SessionFactory implements Connection.SessionFactory
- {
-
- public Session newSession(final Connection conn, final Binary name, final long expiry)
- {
- return new ServerSession(conn, new SessionDelegate(), name, expiry, _connectionConfig);
- }
- };
-
- public BrokerLink(final VirtualHost virtualHost, UUID qmfId, long createTime, Map<String, String> arguments)
- {
- _virtualHost = virtualHost;
- _qmfId = qmfId;
- virtualHost.getConfigStore().persistentIdInUse(qmfId);
- _createTime = createTime;
- _transport = arguments.get(TRANSPORT);
-
- _host = arguments.get(HOST);
- _port = Integer.parseInt(arguments.get(PORT));
- _remoteVhost = arguments.get(REMOTE_VHOST);
- _durable = Boolean.parseBoolean(arguments.get(DURABLE));
- _authMechanism = arguments.get("authMechanism");
- _username = arguments.get("username");
- _password = arguments.get("password");
-
- if(_durable)
- {
- try
- {
- _virtualHost.getMessageStore().createBrokerLink(this);
- }
- catch (AMQStoreException e)
- {
- throw new RuntimeException(e);
- }
- }
-
-
- _qpidConnection = new Connection();
- _connectionConfig = new ConnectionConfigAdapter();
- _qpidConnection.addConnectionListener(this);
-
-
- makeConnection();
-
- }
-
-
- public BrokerLink(final VirtualHost virtualHost,
- final String transport,
- final String host,
- final int port,
- final String remoteVhost,
- final boolean durable,
- final String authMechanism,
- final String username,
- final String password)
- {
- _virtualHost = virtualHost;
- _transport = transport;
- _createTime = System.currentTimeMillis();
- _host = host;
- _port = port;
- _remoteVhost = remoteVhost;
- _durable = durable;
- _authMechanism = authMechanism;
- _username = username;
- _password = password;
- _qmfId = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId();
-
- if(durable)
- {
- try
- {
- _virtualHost.getMessageStore().createBrokerLink(this);
- }
- catch (AMQStoreException e)
- {
- throw new RuntimeException(e);
- }
- }
- _qpidConnection = new Connection();
- _connectionConfig = new ConnectionConfigAdapter();
- _qpidConnection.addConnectionListener(this);
-
- makeConnection();
- }
-
- public Map<String,String> getArguments()
- {
- Map<String,String> arguments = new HashMap<String, String>();
-
- arguments.put(TRANSPORT, _transport);
- arguments.put(HOST, _host);
- arguments.put(PORT, String.valueOf(_port));
- arguments.put(REMOTE_VHOST, _remoteVhost);
- arguments.put(DURABLE, String.valueOf(_durable));
- arguments.put(AUTH_MECHANISM, _authMechanism);
- arguments.put(USERNAME, _username);
- arguments.put(PASSWORD, _password);
-
- return Collections.unmodifiableMap(arguments);
- }
-
- private final boolean updateState(State expected, State newState)
- {
- return _stateUpdater.compareAndSet(this,expected,newState);
- }
-
- private void makeConnection()
- {
- _threadPool.execute(_makeConnectionTask);
- }
-
-
-
- private void doMakeConnection()
- {
- if(updateState(State.DOWN, State.ESTABLISHING))
- {
- try
- {
- _qpidConnection.setConnectionDelegate(new ClientDelegate(new ConnectionSettings())
- {
- protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException,
- SaslException
- {
- Map<String,Object> saslProps = new HashMap<String,Object>();
-
-
- CallbackHandler cbh = new CallbackHandler()
- {
- public void handle(final Callback[] callbacks)
- throws IOException, UnsupportedCallbackException
- {
- for (int i = 0; i < callbacks.length; i++)
- {
- Callback cb = callbacks[i];
- if (cb instanceof NameCallback)
- {
- ((NameCallback)cb).setName(_username);
- }
- else if (cb instanceof PasswordCallback)
- {
- ((PasswordCallback)cb).setPassword(_password.toCharArray());
- }
- else
- {
- throw new UnsupportedCallbackException(cb);
- }
- }
-
- }
- };
- final SaslClient sc = Sasl.createSaslClient(new String[] {"PLAIN"}, null,
- getConnectionSettings().getSaslProtocol(),
- getConnectionSettings().getSaslServerName(),
- saslProps, cbh);
-
- return sc;
- }});
-
- _qpidConnection.connect(_host, _port, _remoteVhost, _username, _password, "ssl".equals(_transport), _authMechanism);
-
- final Map<String,Object> serverProps = _qpidConnection.getServerProperties();
-
- _remoteFederationTag = (String) serverProps.get(ServerPropertyNames.FEDERATION_TAG);
- if(_remoteFederationTag == null)
- {
- _remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString();
- }
- _qpidConnection.setSessionFactory(new SessionFactory());
-
- updateState(State.ESTABLISHING, State.OPERATIONAL);
-
- _retryDelay = 1;
-
- for(Bridge bridge : _bridges.values())
- {
- if(_state != State.OPERATIONAL)
- {
- break;
- }
- addBridge(bridge);
- }
-
-
- }
- catch (TransportException e)
- {
- _lastErrorMessage = e.getMessage();
- if(_retryDelay < 60)
- {
- _retryDelay <<= 1;
- }
-
- updateState(State.ESTABLISHING, State.DOWN);
- _activeBridges.clear();
- scheduleConnectionRetry();
- }
- }
- }
-
- private void scheduleConnectionRetry()
- {
- if(_state != State.DELETED)
- {
- _threadPool.schedule(_makeConnectionTask, _retryDelay, TimeUnit.SECONDS);
- }
- }
-
- public VirtualHost getVirtualHost()
- {
- return _virtualHost;
- }
-
- public String getTransport()
- {
- return _transport;
- }
-
- public String getHost()
- {
- return _host;
- }
-
- public int getPort()
- {
- return _port;
- }
-
- public String getRemoteVhost()
- {
- return _remoteVhost;
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public LinkConfigType getConfigType()
- {
- return LinkConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
- public boolean isDurable()
- {
- return _durable;
- }
-
- public String getAuthMechanism()
- {
- return _authMechanism;
- }
-
- public String getUsername()
- {
- return _username;
- }
-
- public String getPassword()
- {
- return _password;
- }
-
- @Override
- public boolean equals(final Object o)
- {
- if (this == o)
- {
- return true;
- }
- if (o == null || getClass() != o.getClass())
- {
- return false;
- }
-
- final BrokerLink that = (BrokerLink) o;
-
- if (_port != that._port)
- {
- return false;
- }
- if (_host != null ? !_host.equals(that._host) : that._host != null)
- {
- return false;
- }
- if (_remoteVhost != null ? !_remoteVhost.equals(that._remoteVhost) : that._remoteVhost != null)
- {
- return false;
- }
- if (_transport != null ? !_transport.equals(that._transport) : that._transport != null)
- {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode()
- {
- int result = _transport != null ? _transport.hashCode() : 0;
- result = 31 * result + (_host != null ? _host.hashCode() : 0);
- result = 31 * result + _port;
- result = 31 * result + (_remoteVhost != null ? _remoteVhost.hashCode() : 0);
- return result;
- }
-
- public void close()
- {
- if(_closing.compareAndSet(false,true))
- {
- // TODO - close connection
- for(Bridge bridge : _bridges.values())
- {
- bridge.close();
- }
- _bridges.clear();
-
- _virtualHost.removeBrokerConnection(this);
- }
- }
-
- public long getCreateTime()
- {
- return _createTime;
- }
-
- public void createBridge(final boolean durable,
- final boolean dynamic,
- final boolean srcIsQueue,
- final boolean srcIsLocal,
- final String src,
- final String dest,
- final String key,
- final String tag,
- final String excludes)
- {
- if(!_closing.get())
- {
- Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), durable,dynamic,srcIsQueue,srcIsLocal,src,dest,key,tag,excludes);
- if(_bridges.putIfAbsent(bridge, bridge) == null)
- {
-
- addBridge(bridge);
- }
- }
-
-
- }
-
- public void createBridge(final UUID id, final long createTime, final Map<String, String> arguments)
- {
- if(!_closing.get())
- {
- Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), id, createTime, arguments);
- if(_bridges.putIfAbsent(bridge, bridge) == null)
- {
-
- addBridge(bridge);
- }
- }
- }
-
-
- private void addBridge(final Bridge bridge)
- {
- getConfigStore().addConfiguredObject(bridge);
-
- if(_state == State.OPERATIONAL && (_activeBridges.putIfAbsent(bridge,bridge) == null))
- {
-
-
- Session session = _qpidConnection.createSession("Bridge("
- + (bridge.isDurable() ? "durable" : "transient")
- + "," + (bridge.isDynamic() ? "dynamic" : "static")
- + "," + (bridge.isQueueBridge() ? "queue" : "exchange")
- + "," + (bridge.isLocalSource() ? "local-src" : "remote-src")
- + ",[Source: '" + bridge.getSource() + "']"
- + ",[Destination: '" + bridge.getDestination() + "']"
- + ",[Key: '" + bridge.getKey() + "']"
- + ",[Tag: '" + bridge.getTag() + "']"
- + ".[Excludes: '" + bridge.getExcludes() + "'])");
- bridge.setSession(session);
-
-
- if(_closing.get())
- {
- bridge.close();
- }
- }
-
- }
-
- public void opened(final Connection connection)
- {
- // this method not called
- }
-
- public void exception(final Connection connection, final ConnectionException exception)
- {
- _exception = exception;
- _lastErrorMessage = exception.getMessage();
-
- }
-
- public void closed(final Connection connection)
- {
- State currentState = _state;
- if(currentState != State.DOWN && currentState != State.DELETED && updateState(currentState, State.DOWN))
- {
- scheduleConnectionRetry();
- }
- }
-
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
- public String getFederationTag()
- {
- return getVirtualHost().getFederationTag();
- }
-
- public String getRemoteFederationTag()
- {
- return _remoteFederationTag;
- }
-
- public String getState()
- {
- return _state.name();
- }
-
- public String getLastError()
- {
- return _lastErrorMessage;
- }
-
- @Override
- public String toString()
- {
- return "BrokerLink{" +
- " _id=" + _qmfId +
- ", _transport='" + _transport + '\'' +
- ", _host='" + _host + '\'' +
- ", _port=" + _port +
- ", _remoteVhost='" + _remoteVhost + '\'' +
- ", _durable=" + _durable +
- ", _authMechanism='" + _authMechanism + '\'' +
- ", _username='" + _username + '\'' +
- ", _password='" + _password + '\'' +
- ", _virtualHost=" + _virtualHost +
- ", _createTime=" + _createTime +
- ", _remoteFederationTag='" + _remoteFederationTag + '\'' +
- ", _state=" + _state +
- '}';
- }
-}
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 b8c8411c5d..0339287e38 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
@@ -30,11 +30,11 @@ import org.apache.qpid.framing.ConnectionSecureOkBody;
import org.apache.qpid.framing.ConnectionTuneBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -59,9 +59,10 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
public void methodReceived(AMQStateManager stateManager, ConnectionSecureOkBody body, int channelId) throws AMQException
{
+ Broker broker = stateManager.getBroker();
AMQProtocolSession session = stateManager.getProtocolSession();
- AuthenticationManager authMgr = stateManager.getAuthenticationManager();
+ SubjectCreator subjectCreator = stateManager.getSubjectCreator();
SaslServer ss = session.getSaslServer();
if (ss == null)
@@ -69,7 +70,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
throw new AMQException("No SASL context set up in session");
}
MethodRegistry methodRegistry = session.getMethodRegistry();
- AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+ SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse());
switch (authResult.getStatus())
{
case ERROR:
@@ -97,9 +98,9 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
ConnectionTuneBody tuneBody =
- methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(),
- ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
- ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
+ methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT),
+ BrokerProperties.DEFAULT_FRAME_SIZE,
+ (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY));
session.writeFrame(tuneBody.generateFrame(0));
session.setAuthorizedSubject(authResult.getSubject());
disposeSaslServer(session);
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 a522b9f60f..e70fa6a37b 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
@@ -29,12 +29,11 @@ import org.apache.qpid.framing.ConnectionStartOkBody;
import org.apache.qpid.framing.ConnectionTuneBody;
import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
@@ -60,16 +59,17 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException
{
+ Broker broker = stateManager.getBroker();
AMQProtocolSession session = stateManager.getProtocolSession();
_logger.info("SASL Mechanism selected: " + body.getMechanism());
_logger.info("Locale selected: " + body.getLocale());
- AuthenticationManager authMgr = stateManager.getAuthenticationManager();
+ SubjectCreator subjectCreator = stateManager.getSubjectCreator();
SaslServer ss = null;
try
{
- ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal());
+ ss = subjectCreator.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal());
if (ss == null)
{
@@ -78,7 +78,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
session.setSaslServer(ss);
- final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+ final SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse());
//save clientProperties
session.setClientProperties(body.getClientProperties());
@@ -112,9 +112,9 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
- ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(),
- getConfiguredFrameSize(),
- ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
+ ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT),
+ BrokerProperties.DEFAULT_FRAME_SIZE,
+ (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY));
session.writeFrame(tuneBody.generateFrame(0));
break;
case CONTINUE:
@@ -148,13 +148,6 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
}
}
- static int getConfiguredFrameSize()
- {
- final ServerConfiguration config = ApplicationRegistry.getInstance().getConfiguration();
- final int framesize = config.getFrameSize();
- _logger.info("Framesize set to " + framesize);
- return framesize;
- }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
index 8756409f64..eed0cd6020 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
@@ -101,7 +101,7 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
exchange = exchangeFactory.createExchange(exchangeName == null ? null : exchangeName.intern(),
body.getType() == null ? null : body.getType().intern(),
body.getDurable(),
- body.getPassive(), body.getTicket());
+ body.getAutoDelete(), body.getTicket());
exchangeRegistry.registerExchange(exchange);
if (exchange.isDurable())
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 ae725b9ec1..194c3d6351 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
@@ -38,7 +38,6 @@ 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.queue.QueueRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.store.DurableConfigurationStore;
@@ -59,8 +58,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
return _instance;
}
- private boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister();
-
public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException
{
final AMQProtocolSession protocolConnection = stateManager.getProtocolSession();
@@ -148,13 +145,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
});
}
}
- if (autoRegister)
- {
- Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
+ Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
- virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, Collections.EMPTY_MAP);
- _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")");
- }
+ virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange,
+ Collections.<String, Object> emptyMap());
+ _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")");
}
}
else if (queue.isExclusive() && !queue.isDurable() && (owningSession == null || owningSession.getConnectionModel() != protocolConnection))
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java
index 545f2adea2..98da9074ef 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.logging;
-import org.apache.qpid.server.configuration.ServerConfiguration;
public abstract class AbstractRootMessageLogger implements RootMessageLogger
{
@@ -33,9 +32,9 @@ public abstract class AbstractRootMessageLogger implements RootMessageLogger
}
- public AbstractRootMessageLogger(ServerConfiguration config)
+ public AbstractRootMessageLogger(boolean statusUpdatesEnabled)
{
- _enabled = config.getStatusUpdatesEnabled();
+ _enabled = statusUpdatesEnabled;
}
public boolean isEnabled()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java
index ec506ab51c..b4e9f2f333 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java
@@ -20,23 +20,18 @@
*/
package org.apache.qpid.server.logging;
-import org.apache.log4j.Level;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-
public class Log4jMessageLogger extends AbstractRootMessageLogger
{
- public static final Level LEVEL = Level.toLevel("INFO");
-
public Log4jMessageLogger()
{
super();
}
- public Log4jMessageLogger(ServerConfiguration config)
+ public Log4jMessageLogger(boolean statusUpdatesEnabled)
{
- super(config);
+ super(statusUpdatesEnabled);
}
@Override
@@ -51,7 +46,7 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger
if(isEnabled())
{
Logger logger = Logger.getLogger(logHierarchy);
- return logger.isEnabledFor(LEVEL);
+ return logger.isInfoEnabled();
}
else
{
@@ -69,7 +64,6 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger
public void rawMessage(String message, Throwable throwable, String logHierarchy)
{
Logger logger = Logger.getLogger(logHierarchy);
-
- logger.log(LEVEL, message, throwable);
+ logger.info(message, throwable);
}
}
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
index a1065319d3..d053dd3fe2 100644
--- 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
@@ -90,7 +90,6 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record>
public LogRecorder()
{
-
Logger.getRootLogger().addAppender(this);
}
@@ -109,7 +108,11 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record>
@Override
public void close()
{
- //TODO - Implement
+ }
+
+ public void closeLogRecorder()
+ {
+ Logger.getRootLogger().removeAppender(this);
}
@Override
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java
new file mode 100644
index 0000000000..8cf121b3d9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * 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.actors;
+
+import java.security.AccessController;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+
+public abstract class AbstractManagementActor extends AbstractActor
+{
+ /**
+ * Holds the principal name to display when principal subject is not available.
+ * <p>
+ * This is useful for cases when users invoke JMX operation over JConsole
+ * attached to the local JVM.
+ */
+ protected static final String UNKNOWN_PRINCIPAL = "N/A";
+
+ /** used when the principal name cannot be discovered from the Subject */
+ private final String _fallbackPrincipalName;
+
+ public AbstractManagementActor(RootMessageLogger rootLogger, String fallbackPrincipalName)
+ {
+ super(rootLogger);
+ _fallbackPrincipalName = fallbackPrincipalName;
+ }
+
+ /**
+ * Returns current {@link AuthenticatedPrincipal} name or {@link #_fallbackPrincipalName}
+ * if it can't be found.
+ */
+ protected String getPrincipalName()
+ {
+ String identity = _fallbackPrincipalName;
+
+ final Subject subject = Subject.getSubject(AccessController.getContext());
+ if (subject != null)
+ {
+ AuthenticatedPrincipal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject);
+ if(authenticatedPrincipal != null)
+ {
+ identity = authenticatedPrincipal.getName();
+ }
+ }
+ return identity;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java
index 97134515a0..6251471139 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java
@@ -105,6 +105,11 @@ public class CurrentActor
{
Stack<LogActor> stack = _currentActor.get();
stack.pop();
+
+ if (stack.isEmpty())
+ {
+ _currentActor.remove();
+ }
}
/**
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java
new file mode 100644
index 0000000000..9b445c2bd9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.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.logging.actors;
+
+import java.text.MessageFormat;
+
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.LogSubjectFormat;
+
+/**
+ * HttpManagement actor to use in {@link AbstractServlet} to log all http management operational logging.
+ *
+ * An instance is required per http Session.
+ */
+public class HttpManagementActor extends AbstractManagementActor
+{
+ private String _cachedLogString;
+ private String _lastPrincipalName;
+ private String _address;
+
+ public HttpManagementActor(RootMessageLogger rootLogger, String ip, int port)
+ {
+ super(rootLogger, UNKNOWN_PRINCIPAL);
+ _address = ip + ":" + port;
+ }
+
+ private synchronized String getAndCacheLogString()
+ {
+ String principalName = getPrincipalName();
+
+ if(!principalName.equals(_lastPrincipalName))
+ {
+ _lastPrincipalName = principalName;
+ _cachedLogString = "[" + MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, _address) + "] ";
+ }
+
+ return _cachedLogString;
+ }
+
+ public String getLogMessage()
+ {
+ return getAndCacheLogString();
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
index a2f3506502..ba5ea47fc1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java
@@ -21,58 +21,31 @@
package org.apache.qpid.server.logging.actors;
import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.subjects.LogSubjectFormat;
-import javax.management.remote.JMXPrincipal;
-import javax.security.auth.Subject;
-import java.security.AccessController;
-import java.security.Principal;
import java.text.MessageFormat;
-import java.util.Set;
/**
* Management actor to use in {@link MBeanInvocationHandlerImpl} to log all management operational logging.
*/
-public class ManagementActor extends AbstractActor
+public class ManagementActor extends AbstractManagementActor
{
- /**
- * Holds the principal name to display when principal subject is not available.
- * <p>
- * This is useful for cases when users invoke JMX operation over JConsole
- * attached to the local JVM.
- */
- private static final String UNKNOWN_PRINCIPAL = "N/A";
-
private String _lastThreadName = null;
/**
- * LOG FORMAT for the ManagementActor,
- * Uses a MessageFormat call to insert the required values according to
- * these indices:
- *
- * 0 - User ID
- * 1 - IP
- */
- public static final String MANAGEMENT_FORMAT = "mng:{0}({1})";
-
- /**
* The logString to be used for logging
*/
private String _logStringContainingPrincipal;
- /** used when the principal name cannot be discovered from the Subject */
- private final String _fallbackPrincipalName;
-
/** @param rootLogger The RootLogger to use for this Actor */
public ManagementActor(RootMessageLogger rootLogger)
{
- super(rootLogger);
- _fallbackPrincipalName = UNKNOWN_PRINCIPAL;
+ super(rootLogger, UNKNOWN_PRINCIPAL);
}
public ManagementActor(RootMessageLogger rootLogger, String principalName)
{
- super(rootLogger);
- _fallbackPrincipalName = principalName;
+ super(rootLogger, principalName);
}
private synchronized String getAndCacheLogString()
@@ -96,7 +69,7 @@ public class ManagementActor extends AbstractActor
if (split.length == 2)
{
String ip = currentName.split("-")[1];
- actor = MessageFormat.format(MANAGEMENT_FORMAT, principalName, ip);
+ actor = MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, ip);
}
else
{
@@ -119,33 +92,8 @@ public class ManagementActor extends AbstractActor
return logString;
}
- /**
- * Returns current JMX principal name.
- *
- * @return principal name or null if principal can not be found
- */
- private String getPrincipalName()
- {
- String identity = _fallbackPrincipalName;
-
- // retrieve Subject from current AccessControlContext
- final Subject subject = Subject.getSubject(AccessController.getContext());
- if (subject != null)
- {
- // retrieve JMXPrincipal from Subject
- final Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
- if (principals != null && !principals.isEmpty())
- {
- final Principal principal = principals.iterator().next();
- identity = principal.getName();
- }
- }
- return identity;
- }
-
public String getLogMessage()
{
return getAndCacheLogString();
}
-
}
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/LoggingManagementFacade.java
index 931171b175..6a961c8fa4 100644
--- 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/LoggingManagementFacade.java
@@ -58,49 +58,49 @@ import java.util.Random;
* turn {@link Logger} on, off and control their {@link Level}, and the manipulation and reload
* of the log4j configuration file.
*/
-public class LoggingFacade
+public class LoggingManagementFacade
{
private static Logger LOGGER;
- private static transient LoggingFacade _instance;
+ private static transient LoggingManagementFacade _instance;
private final String _filename;
private final int _delay;
- public static LoggingFacade configure(String filename) throws LoggingFacadeException
+ public static LoggingManagementFacade configure(String filename) throws LoggingFacadeException
{
- _instance = new LoggingFacade(filename);
+ _instance = new LoggingManagementFacade(filename);
return _instance;
}
- public static LoggingFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException
+ public static LoggingManagementFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException
{
- _instance = new LoggingFacade(filename, delay);
+ _instance = new LoggingManagementFacade(filename, delay);
return _instance;
}
- public static LoggingFacade getCurrentInstance()
+ public static LoggingManagementFacade getCurrentInstance()
{
return _instance;
}
- private LoggingFacade(String filename)
+ private LoggingManagementFacade(String filename)
{
DOMConfigurator.configure(filename);
if(LOGGER == null)
{
- LOGGER = Logger.getLogger(LoggingFacade.class);
+ LOGGER = Logger.getLogger(LoggingManagementFacade.class);
}
_filename = filename;
_delay = 0;
}
- private LoggingFacade(String filename, int delay)
+ private LoggingManagementFacade(String filename, int delay)
{
DOMConfigurator.configureAndWatch(filename, delay);
if(LOGGER == null)
{
- LOGGER = Logger.getLogger(LoggingFacade.class);
+ LOGGER = Logger.getLogger(LoggingManagementFacade.class);
}
_filename = filename;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties
index ac77f674f2..7924be28d3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties
@@ -18,16 +18,21 @@
#
# Default File used for all non-defined locales.
#
-STARTUP = MNG-1001 : Startup
+# 0 - Management Type
+STARTUP = MNG-1001 : {0} Management Startup
# 0 - Service
# 1 - Port
LISTENING = MNG-1002 : Starting : {0} : Listening on port {1,number,#}
# 0 - Service
# 1 - Port
SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#}
-READY = MNG-1004 : Ready[ : Using the platform JMX Agent]
-STOPPED = MNG-1005 : Stopped
+# 0 - Management Type
+READY = MNG-1004 : {0} Management Ready
+# 0 - Management Type
+STOPPED = MNG-1005 : {0} Management Stopped
# 0 - Path
SSL_KEYSTORE = MNG-1006 : Using SSL Keystore : {0}
+# 0 - Username
OPEN = MNG-1007 : Open : User {0}
+# 0 - Username
CLOSE = MNG-1008 : Close : User {0} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
index 859d7e2a27..bcb9cb2ac4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
@@ -76,7 +76,7 @@ public class ChannelLogSubject extends AbstractLogSubject
setLogStringWithFormat(CHANNEL_FORMAT,
connection == null ? -1L : connection.getConnectionId(),
session.getAuthorizedPrincipal() == null ? "?" : session.getAuthorizedPrincipal().getName(),
- (connection == null || connection.getConfig() == null) ? "?" : connection.getConfig().getAddress(),
+ (connection == null || connection.getRemoteAddressString() == null) ? "?" : connection.getRemoteAddressString(),
session.getVirtualHost().getName(),
session.getChannel());
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
index 28c4f0d52a..7611ee1a88 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java
@@ -32,11 +32,19 @@ package org.apache.qpid.server.logging.subjects;
public class LogSubjectFormat
{
+
private LogSubjectFormat()
{
}
/**
+ * LOG FORMAT for the ManagementActors,
+ * 0 - User ID
+ * 1 - IP[:Port]
+ */
+ public static final String MANAGEMENT_FORMAT = "mng:{0}({1})";
+
+ /**
* LOG FORMAT for the Subscription Log Subject
* 0 - Subscription ID
*/
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 2cc1a92853..e01f20d54f 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
@@ -342,6 +342,14 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
{
private final AMQPDescribedTypeRegistry _typeRegistry = AMQPDescribedTypeRegistry.newInstance();
+ private MetaDataFactory()
+ {
+ _typeRegistry.registerTransportLayer();
+ _typeRegistry.registerMessagingLayer();
+ _typeRegistry.registerTransactionLayer();
+ _typeRegistry.registerSecurityLayer();
+ }
+
public MessageMetaData_1_0 createMetaData(ByteBuffer buf)
{
ValueHandler valueHandler = new ValueHandler(_typeRegistry);
@@ -354,7 +362,8 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData
try
{
ByteBuffer encodedBuf = buf.duplicate();
- sections.add((Section) valueHandler.parse(buf));
+ Object parse = valueHandler.parse(buf);
+ sections.add((Section) parse);
encodedBuf.limit(buf.position());
encodedSections.add(encodedBuf);
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
index 6000886956..417f6036ab 100644
--- 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
@@ -24,6 +24,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+
public interface AuthenticationProvider extends ConfiguredObject
{
@@ -52,4 +55,15 @@ public interface AuthenticationProvider extends ConfiguredObject
TYPE));
//children
Collection<VirtualHostAlias> getVirtualHostPortBindings();
+
+ String getName();
+
+ /**
+ * A temporary method to create SubjectCreator.
+ *
+ * TODO: move all the functionality from SubjectCreator into AuthenticationProvider
+ */
+ SubjectCreator getSubjectCreator();
+
+ void setGroupAccessor(GroupPrincipalAccessor groupPrincipalAccessor);
}
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
index 08b01a1b65..fbecf1965b 100644
--- 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
@@ -20,12 +20,20 @@
*/
package org.apache.qpid.server.model;
+import java.net.SocketAddress;
import java.security.AccessControlException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
public interface Broker extends ConfiguredObject
{
@@ -44,9 +52,49 @@ public interface Broker extends ConfiguredObject
String STATE = "state";
String TIME_TO_LIVE = "timeToLive";
String UPDATED = "updated";
+ String DEFAULT_AUTHENTICATION_PROVIDER = "defaultAuthenticationProvider";
+ String DEFAULT_VIRTUAL_HOST = "defaultVirtualHost";
+
+ String ALERT_THRESHOLD_MESSAGE_AGE = "alertThresholdMessageAge";
+ String ALERT_THRESHOLD_MESSAGE_COUNT = "alertThresholdMessageCount";
+ String ALERT_THRESHOLD_QUEUE_DEPTH = "alertThresholdQueueDepth";
+ String ALERT_THRESHOLD_MESSAGE_SIZE = "alertThresholdMessageSize";
+ String ALERT_REPEAT_GAP = "alertRepeatGap";
+ String FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes";
+ String FLOW_CONTROL_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes";
+ String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts";
+ String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled";
+ String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod";
+
+ String SESSION_COUNT_LIMIT = "sessionCountLimit";
+ String HEART_BEAT_DELAY = "heartBeatDelay";
+ String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod";
+ String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled";
+
+ /*
+ * A temporary attribute to pass the path to ACL file.
+ * TODO: It should be a part of AuthorizationProvider.
+ */
+ String ACL_FILE = "aclFile";
+
+ /*
+ * A temporary attributes to set the broker default key/trust stores.
+ * TODO: Remove them after adding a full support to configure KeyStore/TrustStore via management layers.
+ */
+ String KEY_STORE_PATH = "keyStorePath";
+ String KEY_STORE_PASSWORD = "keyStorePassword";
+ String KEY_STORE_CERT_ALIAS = "keyStoreCertAlias";
+ String TRUST_STORE_PATH = "trustStorePath";
+ String TRUST_STORE_PASSWORD = "trustStorePassword";
+
+ /*
+ * A temporary attributes to set the broker group file.
+ * TODO: Remove them after adding a full support to configure authorization providers via management layers.
+ */
+ String GROUP_FILE = "groupFile";
// Attributes
- public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collection<String> AVAILABLE_ATTRIBUTES =
Collections.unmodifiableList(
Arrays.asList(BUILD_VERSION,
BYTES_RETAINED,
@@ -62,7 +110,32 @@ public interface Broker extends ConfiguredObject
NAME,
STATE,
TIME_TO_LIVE,
- UPDATED));
+ UPDATED,
+ DEFAULT_AUTHENTICATION_PROVIDER,
+ DEFAULT_VIRTUAL_HOST,
+ ALERT_THRESHOLD_MESSAGE_AGE,
+ ALERT_THRESHOLD_MESSAGE_COUNT,
+ ALERT_THRESHOLD_QUEUE_DEPTH,
+ ALERT_THRESHOLD_MESSAGE_SIZE,
+ ALERT_REPEAT_GAP,
+ FLOW_CONTROL_SIZE_BYTES,
+ FLOW_CONTROL_RESUME_SIZE_BYTES,
+ MAXIMUM_DELIVERY_ATTEMPTS,
+ DEAD_LETTER_QUEUE_ENABLED,
+ HOUSEKEEPING_CHECK_PERIOD,
+ SESSION_COUNT_LIMIT,
+ HEART_BEAT_DELAY,
+ STATISTICS_REPORTING_PERIOD,
+ STATISTICS_REPORTING_RESET_ENABLED,
+
+ ACL_FILE,
+ KEY_STORE_PATH,
+ KEY_STORE_PASSWORD,
+ KEY_STORE_CERT_ALIAS,
+ TRUST_STORE_PATH,
+ TRUST_STORE_PASSWORD,
+ GROUP_FILE
+ ));
//children
Collection < VirtualHost > getVirtualHosts();
@@ -75,6 +148,49 @@ public interface Broker extends ConfiguredObject
LifetimePolicy lifetime, long ttl, Map<String, Object> attributes)
throws AccessControlException, IllegalArgumentException;
- void deleteVirtualHost(VirtualHost virtualHost)
- throws AccessControlException, IllegalStateException;
+ AuthenticationProvider getDefaultAuthenticationProvider();
+
+ Collection<GroupProvider> getGroupProviders();
+
+ /**
+ * A temporary hack to expose root message logger via broker instance.
+ * TODO We need a better way to do operational logging, for example, via logging listeners
+ */
+ RootMessageLogger getRootMessageLogger();
+
+ /**
+ * A temporary hack to expose security manager via broker instance.
+ * TODO We need to add and implement an authorization provider configured object instead
+ */
+ SecurityManager getSecurityManager();
+
+ /**
+ * TODO: A temporary hack to expose log recorder via broker instance.
+ */
+ LogRecorder getLogRecorder();
+
+ VirtualHost findVirtualHostByName(String name);
+
+ /**
+ * Get the SubjectCreator for the given socket address.
+ * TODO: move the authentication related functionality into host aliases and AuthenticationProviders
+ *
+ * @param address The (listening) socket address for which the AuthenticationManager is required
+ */
+ SubjectCreator getSubjectCreator(SocketAddress localAddress);
+
+ Collection<KeyStore> getKeyStores();
+
+ Collection<TrustStore> getTrustStores();
+
+ /*
+ * TODO: Remove this method. Eventually the broker will become a registry.
+ */
+ VirtualHostRegistry getVirtualHostRegistry();
+
+ KeyStore getDefaultKeyStore();
+
+ TrustStore getDefaultTrustStore();
+
+ TaskExecutor getTaskExecutor();
}
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 78b98faffe..bd7da962ba 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
@@ -36,4 +36,5 @@ public interface ConfigurationChangeListener
void childRemoved(ConfiguredObject object, ConfiguredObject child);
+ void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue);
}
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 414b2d083a..d567a3aa44 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
@@ -25,6 +25,9 @@ import java.util.Collection;
import java.util.Map;
import java.util.UUID;
+/**
+ * An object that can be "managed" (eg via the web interface) and usually read from configuration.
+ */
public interface ConfiguredObject
{
@@ -47,7 +50,7 @@ public interface ConfiguredObject
* Attempt to change the name of the object
*
* Request a change to the name of the object. The caller must pass in the name it believes the object currently
- * has. If the current name differes from this expected value, then no name change will occur
+ * has. If the current name differs from this expected value, then no name change will occur
*
* @param currentName the name the caller believes the object to have
* @param desiredName the name the caller would like the object to have
@@ -198,14 +201,25 @@ public interface ConfiguredObject
/**
- * Return the value for the given attribute
+ * Return the value for the given attribute name. The actual attribute value
+ * is returned if the configured object has such attribute set. If not, the
+ * value is looked default attributes.
*
- * @param name the name of the attribute
- * @return the value of the attribute at the object (or null if the attribute is not set
+ * @param name
+ * the name of the attribute
+ * @return the value of the attribute at the object (or null if the
+ * attribute value is set neither on object itself no in defaults)
*/
Object getAttribute(String name);
/**
+ * Return the map containing only explicitly set attributes
+ *
+ * @return the map with the attributes
+ */
+ Map<String, Object> getActualAttributes();
+
+ /**
* Set the value of an attribute
*
* @param name the name of the attribute to be set
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Group.java b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java
new file mode 100644
index 0000000000..aacd515107
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java
@@ -0,0 +1,52 @@
+/*
+ * 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 Group 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";
+
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED
+ ));
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java
new file mode 100644
index 0000000000..6832cc6fa6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java
@@ -0,0 +1,52 @@
+/*
+ * 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 GroupMember 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";
+
+ // Attributes
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED
+ ));
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java
new file mode 100644
index 0000000000..9016f97927
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.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.security.Principal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+public interface GroupProvider 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));
+
+ Set<Principal> getGroupPrincipalsForUser(String username);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
new file mode 100644
index 0000000000..959714656b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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 KeyStore extends TrustStore
+{
+
+ String CERTIFICATE_ALIAS = "certificateAlias";
+
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ DESCRIPTION,
+ PATH,
+ PASSWORD,
+ TYPE,
+ KEY_MANAGER_FACTORY_ALGORITHM,
+ CERTIFICATE_ALIAS
+ ));
+
+}
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
index 36179fc105..2c05dce9cb 100644
--- 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
@@ -47,6 +47,10 @@ public class Model
addRelationship(Broker.class, VirtualHost.class);
addRelationship(Broker.class, Port.class);
addRelationship(Broker.class, AuthenticationProvider.class);
+ addRelationship(Broker.class, GroupProvider.class);
+ addRelationship(Broker.class, TrustStore.class);
+ addRelationship(Broker.class, KeyStore.class);
+ addRelationship(Broker.class, Plugin.class);
addRelationship(VirtualHost.class, Exchange.class);
addRelationship(VirtualHost.class, Queue.class);
@@ -54,6 +58,10 @@ public class Model
addRelationship(VirtualHost.class, VirtualHostAlias.class);
addRelationship(AuthenticationProvider.class, User.class);
+ addRelationship(User.class, GroupMember.class);
+
+ addRelationship(GroupProvider.class, Group.class);
+ addRelationship(Group.class, GroupMember.class);
addRelationship(Connection.class, Session.class);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java
new file mode 100644
index 0000000000..b9503a5841
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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 Plugin extends ConfiguredObject
+{
+ //Hack, using it for the class name only for consistency with the other things.
+ 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
+ ));
+}
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
index 50c0ebcd14..2f94c3cab7 100644
--- 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
@@ -39,6 +39,16 @@ public interface Port extends ConfiguredObject
String PORT = "port";
String PROTOCOLS = "protocols";
String TRANSPORTS = "transports";
+ String TCP_NO_DELAY = "tcpNoDelay";
+ String SEND_BUFFER_SIZE = "sendBufferSize";
+ String RECEIVE_BUFFER_SIZE = "receiveBufferSize";
+ String NEED_CLIENT_AUTH = "needClientAuth";
+ String WANT_CLIENT_AUTH = "wantClientAuth";
+
+ /**
+ * TODO: rename it to AUTHENTICATION_MANAGER_ID or introduce relationships
+ */
+ String AUTHENTICATION_MANAGER = "authenticationManager";
// Attributes
public static final Collection<String> AVAILABLE_ATTRIBUTES =
@@ -55,7 +65,13 @@ public interface Port extends ConfiguredObject
BINDING_ADDRESS,
PORT,
PROTOCOLS,
- TRANSPORTS
+ TRANSPORTS,
+ TCP_NO_DELAY,
+ SEND_BUFFER_SIZE,
+ RECEIVE_BUFFER_SIZE,
+ NEED_CLIENT_AUTH,
+ WANT_CLIENT_AUTH,
+ AUTHENTICATION_MANAGER
));
@@ -88,4 +104,8 @@ public interface Port extends ConfiguredObject
//children
Collection<VirtualHostAlias> getVirtualHostBindings();
Collection<Connection> getConnections();
+
+ AuthenticationProvider getAuthenticationProvider();
+
+ void setAuthenticationProvider(AuthenticationProvider authenticationProvider);
}
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
index 5d9de69f9a..6cd5eb23a4 100644
--- 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
@@ -20,14 +20,95 @@
*/
package org.apache.qpid.server.model;
+import java.util.Collection;
+import java.util.EnumSet;
+
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+
public enum Protocol
{
- AMQP_0_8,
- AMQP_0_9,
- AMQP_0_9_1,
- AMQP_0_10,
- AMQP_1_0,
- JMX,
- HTTP,
- HTTPS
+ AMQP_0_8(ProtocolType.AMQP),
+ AMQP_0_9(ProtocolType.AMQP),
+ AMQP_0_9_1(ProtocolType.AMQP),
+ AMQP_0_10(ProtocolType.AMQP),
+ AMQP_1_0(ProtocolType.AMQP),
+ JMX_RMI(ProtocolType.JMX),
+ HTTP(ProtocolType.HTTP),
+ HTTPS(ProtocolType.HTTP),
+ RMI(ProtocolType.RMI);
+
+ private final ProtocolType _protocolType;
+
+ private Protocol(ProtocolType type)
+ {
+ _protocolType = type;
+ }
+
+ public ProtocolType getProtocolType()
+ {
+ return _protocolType;
+ }
+
+ public boolean isAMQP()
+ {
+ return _protocolType == ProtocolType.AMQP;
+ }
+
+ public AmqpProtocolVersion toAmqpProtocolVersion()
+ {
+ switch(this)
+ {
+ case AMQP_0_8:
+ return AmqpProtocolVersion.v0_8;
+ case AMQP_0_9:
+ return AmqpProtocolVersion.v0_9;
+ case AMQP_0_9_1:
+ return AmqpProtocolVersion.v0_9_1;
+ case AMQP_0_10:
+ return AmqpProtocolVersion.v0_10;
+ case AMQP_1_0:
+ return AmqpProtocolVersion.v1_0_0;
+ default:
+ throw new IllegalArgumentException(this + " is not an known AMQP protocol");
+ }
+ }
+
+ public static Protocol valueOfObject(Object protocolObject)
+ {
+ Protocol protocol;
+ if (protocolObject instanceof Protocol)
+ {
+ protocol = (Protocol) protocolObject;
+ }
+ else
+ {
+ try
+ {
+ protocol = Protocol.valueOf(String.valueOf(protocolObject));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Can't convert '" + protocolObject
+ + "' to one of the supported protocols: " + EnumSet.allOf(Protocol.class), e);
+ }
+ }
+ return protocol;
+ }
+
+ public static boolean hasAmqpProtocol(Collection<Protocol> protocols)
+ {
+ for (Protocol protocol : protocols)
+ {
+ if (protocol.isAMQP())
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static enum ProtocolType
+ {
+ AMQP, HTTP, JMX, RMI;
+ }
}
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
index 03cd46be01..ae6e5ac43a 100644
--- 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
@@ -20,8 +20,32 @@
*/
package org.apache.qpid.server.model;
+import java.util.EnumSet;
+
public enum Transport
{
TCP,
- SSL
+ SSL;
+
+ public static Transport valueOfObject(Object transportObject)
+ {
+ Transport transport;
+ if (transportObject instanceof Transport)
+ {
+ transport = (Transport) transportObject;
+ }
+ else
+ {
+ try
+ {
+ transport = Transport.valueOf(String.valueOf(transportObject));
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Can't convert '" + transportObject
+ + "' to one of the supported transports: " + EnumSet.allOf(Transport.class), e);
+ }
+ }
+ return transport;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
new file mode 100644
index 0000000000..0c322ae02f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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 TrustStore extends ConfiguredObject
+{
+ String ID = "id";
+ String NAME = "name";
+ String DURABLE = "durable";
+ String LIFETIME_POLICY = "lifetimePolicy";
+ String STATE = "state";
+ String TIME_TO_LIVE = "timeToLive";
+ String CREATED = "created";
+ String UPDATED = "updated";
+ String DESCRIPTION = "description";
+
+ String PATH = "path";
+ String PASSWORD = "password";
+ String TYPE = "type";
+ String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm";
+
+ public static final Collection<String> AVAILABLE_ATTRIBUTES =
+ Collections.unmodifiableList(
+ Arrays.asList(
+ ID,
+ NAME,
+ STATE,
+ DURABLE,
+ LIFETIME_POLICY,
+ TIME_TO_LIVE,
+ CREATED,
+ UPDATED,
+ DESCRIPTION,
+ PATH,
+ PASSWORD,
+ TYPE,
+ KEY_MANAGER_FACTORY_ALGORITHM
+ ));
+
+ public String getPassword();
+
+ public void setPassword(String password);
+}
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 36b6a454dc..bcedd91596 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
@@ -63,6 +63,11 @@ public class UUIDGenerator
return createUUID(User.class.getName(), authenticationProviderName, userName);
}
+ public static UUID generateGroupUUID(String groupProviderName, String groupName)
+ {
+ return createUUID(Group.class.getName(), groupProviderName, groupName);
+ }
+
public static UUID generateVhostUUID(String virtualHostName)
{
return createUUID(VirtualHost.class.getName(), virtualHostName);
@@ -77,4 +82,14 @@ public class UUIDGenerator
{
return createUUID(Consumer.class.getName(), virtualHostName, queueName, connectionRemoteAddress, channelNumber, consumerName);
}
+
+ public static UUID generateGroupMemberUUID(String groupProviderName, String groupName, String groupMemberName)
+ {
+ return createUUID(GroupMember.class.getName(), groupProviderName, groupName, groupMemberName);
+ }
+
+ public static UUID generateBrokerChildUUID(String type, String childName)
+ {
+ return createUUID(type, childName);
+ }
}
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
index d97bf46d31..675dc8f0d3 100644
--- 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
@@ -52,8 +52,6 @@ public interface User extends ConfiguredObject
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
index 24a3d43386..5f4ec1d3a8 100644
--- 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
@@ -21,6 +21,9 @@
package org.apache.qpid.server.model;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.store.MessageStore;
+
import java.security.AccessControlException;
import java.util.Arrays;
import java.util.Collection;
@@ -60,17 +63,16 @@ public interface VirtualHost extends ConfiguredObject
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 STORE_PATH = "storePath";
String SUPPORTED_EXCHANGE_TYPES = "supportedExchangeTypes";
String SUPPORTED_QUEUE_TYPES = "supportedQueueTypes";
String CREATED = "created";
@@ -81,6 +83,8 @@ public interface VirtualHost extends ConfiguredObject
String STATE = "state";
String TIME_TO_LIVE = "timeToLive";
String UPDATED = "updated";
+ String CONFIG_PATH = "configPath";
+
// Attributes
public static final Collection<String> AVAILABLE_ATTRIBUTES =
Collections.unmodifiableList(
@@ -96,13 +100,12 @@ public interface VirtualHost extends ConfiguredObject
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_PATH,
STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE,
STORE_TRANSACTION_IDLE_TIMEOUT_WARN,
STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE,
@@ -111,7 +114,8 @@ public interface VirtualHost extends ConfiguredObject
ALERT_THRESHOLD_MESSAGE_AGE,
ALERT_THRESHOLD_MESSAGE_SIZE,
ALERT_THRESHOLD_QUEUE_DEPTH_BYTES,
- ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES));
+ ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES,
+ CONFIG_PATH));
@@ -149,4 +153,12 @@ public interface VirtualHost extends ConfiguredObject
}
void executeTransaction(TransactionalOperation op);
+
+ /**
+ * A temporary hack to expose host security manager.
+ * TODO We need to add and implement an authorization provider configured object instead
+ */
+ SecurityManager getSecurityManager();
+
+ MessageStore getMessageStore();
}
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
index 7d6aa9b2cb..73e1f1e970 100644
--- 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
@@ -24,12 +24,18 @@ import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
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;
+import org.apache.qpid.server.configuration.updater.ChangeStateTask;
+import org.apache.qpid.server.configuration.updater.CreateChildTask;
+import org.apache.qpid.server.configuration.updater.SetAttributeTask;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
abstract class AbstractAdapter implements ConfiguredObject
{
@@ -40,134 +46,78 @@ abstract class AbstractAdapter implements ConfiguredObject
new ArrayList<ConfigurationChangeListener>();
private final UUID _id;
+ private final Map<String, Object> _defaultAttributes = new HashMap<String, Object>();
+ private final TaskExecutor _taskExecutor;
- protected AbstractAdapter(UUID id)
+ protected AbstractAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor)
{
+ _taskExecutor = taskExecutor;
_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)
+ if (attributes != null)
{
- return (Map) value;
+ Collection<String> names = getAttributeNames();
+ for (String name : names)
+ {
+ if (attributes.containsKey(name))
+ {
+ _attributes.put(name, attributes.get(name));
+ }
+ }
}
- else
+ if (defaults != null)
{
- throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map");
+ _defaultAttributes.putAll(defaults);
}
}
-
- static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal)
+ protected AbstractAdapter(UUID id, TaskExecutor taskExecutor)
{
- 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());
- }
+ this(id, null, null, taskExecutor);
}
- static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue)
+ public final UUID getId()
{
- 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");
- }
+ return _id;
}
- static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue)
+ public State getDesiredState()
{
- 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");
- }
+ return null; //TODO
}
- static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue)
+ @Override
+ public final State setDesiredState(final State currentState, final State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
{
- Object obj = attributes.get(name);
- if(obj == null)
- {
- return defaultValue;
- }
- else if(obj instanceof Number)
+ if (_taskExecutor.isTaskExecutorThread())
{
- return ((Number) obj).longValue();
- }
- else if(obj instanceof String)
- {
- return Long.valueOf((String) obj);
+ if (setState(currentState, desiredState))
+ {
+ notifyStateChanged(currentState, desiredState);
+ }
}
else
{
- throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long");
+ _taskExecutor.submitAndWait(new ChangeStateTask(this, currentState, desiredState));
}
+ return getActualState();
}
- public final UUID getId()
- {
- return _id;
- }
+ /**
+ * @return true when the state has been successfully updated to desiredState or false otherwise
+ */
+ protected abstract boolean setState(State currentState, State desiredState);
- public State getDesiredState()
+ protected void notifyStateChanged(final State currentState, final State desiredState)
{
- return null; //TODO
- }
-
- public State setDesiredState(final State currentState, final State desiredState)
- throws IllegalStateTransitionException, AccessControlException
- {
- return null; //TODO
+ synchronized (_changeListeners)
+ {
+ List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
+ for(ConfigurationChangeListener listener : copy)
+ {
+ listener.stateChanged(this, currentState, desiredState);
+ }
+ }
}
public void addChangeListener(final ConfigurationChangeListener listener)
@@ -176,7 +126,7 @@ abstract class AbstractAdapter implements ConfiguredObject
{
throw new NullPointerException("Cannot add a null listener");
}
- synchronized (this)
+ synchronized (_changeListeners)
{
if(!_changeListeners.contains(listener))
{
@@ -191,39 +141,76 @@ abstract class AbstractAdapter implements ConfiguredObject
{
throw new NullPointerException("Cannot remove a null listener");
}
- synchronized (this)
+ synchronized (_changeListeners)
{
return _changeListeners.remove(listener);
}
}
-
protected void childAdded(ConfiguredObject child)
{
- synchronized (this)
+ synchronized (_changeListeners)
{
- for(ConfigurationChangeListener listener : _changeListeners)
+ List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
+ for(ConfigurationChangeListener listener : copy)
{
listener.childAdded(this, child);
}
}
}
-
protected void childRemoved(ConfiguredObject child)
{
- synchronized (this)
+ synchronized (_changeListeners)
{
- for(ConfigurationChangeListener listener : _changeListeners)
+ List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
+ for(ConfigurationChangeListener listener : copy)
{
listener.childRemoved(this, child);
}
}
}
- public Object getAttribute(final String name)
+ protected void attributeSet(String attrinuteName, Object oldAttributeValue, Object newAttributeValue)
{
- synchronized (this)
+ synchronized (_changeListeners)
+ {
+ List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners);
+ for(ConfigurationChangeListener listener : copy)
+ {
+ listener.attributeSet(this, attrinuteName, oldAttributeValue, newAttributeValue);
+ }
+ }
+ }
+
+ private final Object getDefaultAttribute(String name)
+ {
+ return _defaultAttributes.get(name);
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ Object value = getActualAttribute(name);
+ if (value == null)
+ {
+ value = getDefaultAttribute(name);
+ }
+ return value;
+ }
+
+ @Override
+ public final Map<String, Object> getActualAttributes()
+ {
+ synchronized (_attributes)
+ {
+ return new HashMap<String, Object>(_attributes);
+ }
+ }
+
+ private Object getActualAttribute(final String name)
+ {
+ synchronized (_attributes)
{
return _attributes.get(name);
}
@@ -232,25 +219,41 @@ abstract class AbstractAdapter implements ConfiguredObject
public Object setAttribute(final String name, final Object expected, final Object desired)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- synchronized (this)
+ if (_taskExecutor.isTaskExecutorThread())
{
- Object currentValue = _attributes.get(name);
+ if (changeAttribute(name, expected, desired))
+ {
+ attributeSet(name, expected, desired);
+ }
+ }
+ else
+ {
+ _taskExecutor.submitAndWait(new SetAttributeTask(this, name, expected, desired));
+ }
+ return getAttribute(name);
+ }
+
+ protected boolean changeAttribute(final String name, final Object expected, final Object desired)
+ {
+ synchronized (_attributes)
+ {
+ Object currentValue = getAttribute(name);
if((currentValue == null && expected == null)
|| (currentValue != null && currentValue.equals(expected)))
{
_attributes.put(name, desired);
- return desired;
+ return true;
}
else
{
- return currentValue;
+ return false;
}
}
}
public <T extends ConfiguredObject> T getParent(final Class<T> clazz)
{
- synchronized (this)
+ synchronized (_parents)
{
return (T) _parents.get(clazz);
}
@@ -258,7 +261,7 @@ abstract class AbstractAdapter implements ConfiguredObject
protected <T extends ConfiguredObject> void addParent(Class<T> clazz, T parent)
{
- synchronized (this)
+ synchronized (_parents)
{
_parents.put(clazz, parent);
}
@@ -280,4 +283,40 @@ abstract class AbstractAdapter implements ConfiguredObject
}
}
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + " [id=" + _id + ", name=" + getName() + "]";
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if (_taskExecutor.isTaskExecutorThread())
+ {
+ C child = addChild(childClass, attributes, otherParents);
+ if (child != null)
+ {
+ childAdded(child);
+ }
+ return child;
+ }
+ else
+ {
+ return (C)_taskExecutor.submitAndWait(new CreateChildTask(this, childClass, attributes, otherParents));
+ }
+ }
+
+ protected <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+
+ protected TaskExecutor getTaskExecutor()
+ {
+ return _taskExecutor;
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java
new file mode 100644
index 0000000000..ebd98f915d
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java
@@ -0,0 +1,198 @@
+/*
+ *
+ * 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 java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.KeyStore;
+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.TrustStore;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public abstract class AbstractKeyStoreAdapter extends AbstractAdapter
+{
+ private String _name;
+ private String _password;
+
+ protected AbstractKeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, broker.getTaskExecutor());
+ addParent(Broker.class, broker);
+ _name = MapValueConverter.getStringAttribute(TrustStore.NAME, attributes);
+ _password = MapValueConverter.getStringAttribute(TrustStore.PASSWORD, attributes);
+ setMandatoryAttribute(TrustStore.PATH, attributes);
+ setOptionalAttribute(TrustStore.TYPE, attributes);
+ setOptionalAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, attributes);
+ setOptionalAttribute(TrustStore.DESCRIPTION, attributes);
+ }
+
+ @Override
+ public String getName()
+ {
+ return _name;
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new IllegalStateException();
+ }
+
+ @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();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new IllegalStateException();
+ }
+
+ @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();
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if(KeyStore.ID.equals(name))
+ {
+ return getId();
+ }
+ else if(KeyStore.NAME.equals(name))
+ {
+ return getName();
+ }
+ else if(KeyStore.STATE.equals(name))
+ {
+ return getActualState();
+ }
+ else if(KeyStore.DURABLE.equals(name))
+ {
+ return isDurable();
+ }
+ else if(KeyStore.LIFETIME_POLICY.equals(name))
+ {
+ return getLifetimePolicy();
+ }
+ else if(KeyStore.TIME_TO_LIVE.equals(name))
+ {
+ return getTimeToLive();
+ }
+ else if(KeyStore.CREATED.equals(name))
+ {
+
+ }
+ else if(KeyStore.UPDATED.equals(name))
+ {
+
+ }
+ else if(KeyStore.PASSWORD.equals(name))
+ {
+ return null; // for security reasons we don't expose the password
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ return false;
+ }
+
+ public String getPassword()
+ {
+ return _password;
+ }
+
+ public void setPassword(String password)
+ {
+ _password = password;
+ }
+
+ private void setMandatoryAttribute(String name, Map<String, Object> attributeValues)
+ {
+ changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues));
+ }
+
+ private void setOptionalAttribute(String name, Map<String, Object> attributeValues)
+ {
+ if (attributeValues.get(name) != null)
+ {
+ changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues));
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java
new file mode 100644
index 0000000000..ed4af9881f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.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.adapter;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Statistics;
+
+public abstract class AbstractPluginAdapter extends AbstractAdapter implements Plugin
+{
+
+ protected AbstractPluginAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor)
+ {
+ super(id, defaults, attributes, taskExecutor);
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return true;
+ }
+
+ @Override
+ public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return LifetimePolicy.PERMANENT;
+ }
+
+ @Override
+ public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException,
+ AccessControlException, IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ @Override
+ public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Statistics getStatistics()
+ {
+ return null;
+ }
+
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (ID.equals(name))
+ {
+ return getId();
+ }
+ 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))
+ {
+
+ }
+ return super.getAttribute(name);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
new file mode 100644
index 0000000000..2f7e89bb2b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
@@ -0,0 +1,251 @@
+/*
+ * 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 static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.GeneralSecurityException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.NetworkTransportConfiguration;
+import org.apache.qpid.transport.network.IncomingNetworkTransport;
+
+public class AmqpPortAdapter extends PortAdapter
+{
+ private final Broker _broker;
+ private IncomingNetworkTransport _transport;
+
+ public AmqpPortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaultAttributes, TaskExecutor taskExecutor)
+ {
+ super(id, broker, attributes, defaultAttributes, taskExecutor);
+ _broker = broker;
+ }
+
+ @Override
+ protected void onActivate()
+ {
+ Collection<Transport> transports = getTransports();
+ Set<AmqpProtocolVersion> supported = convertFromModelProtocolsToAmqp(getProtocols());
+
+ SSLContext sslContext = null;
+ if (transports.contains(Transport.SSL))
+ {
+ sslContext = createSslContext();
+ }
+
+ AmqpProtocolVersion defaultSupportedProtocolReply = getDefaultAmqpSupportedReply();
+
+ String bindingAddress = (String) getAttribute(Port.BINDING_ADDRESS);
+ if (WILDCARD_ADDRESS.equals(bindingAddress))
+ {
+ bindingAddress = null;
+ }
+ Integer port = (Integer) getAttribute(Port.PORT);
+ InetSocketAddress bindingSocketAddress = null;
+ if ( bindingAddress == null )
+ {
+ bindingSocketAddress = new InetSocketAddress(port);
+ }
+ else
+ {
+ bindingSocketAddress = new InetSocketAddress(bindingAddress, port);
+ }
+
+ final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration(
+ bindingSocketAddress, (Boolean)getAttribute(TCP_NO_DELAY),
+ (Integer)getAttribute(SEND_BUFFER_SIZE), (Integer)getAttribute(RECEIVE_BUFFER_SIZE),
+ (Boolean)getAttribute(NEED_CLIENT_AUTH), (Boolean)getAttribute(WANT_CLIENT_AUTH));
+
+ _transport = org.apache.qpid.transport.network.Transport.getIncomingTransportInstance();
+ final MultiVersionProtocolEngineFactory protocolEngineFactory = new MultiVersionProtocolEngineFactory(
+ _broker, supported, defaultSupportedProtocolReply);
+
+ _transport.accept(settings, protocolEngineFactory, sslContext);
+ CurrentActor.get().message(BrokerMessages.LISTENING(getTransports().toString(), getPort()));
+ }
+
+ @Override
+ protected void onStop()
+ {
+ if (_transport != null)
+ {
+ CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(getTransports().toString(), getPort()));
+ _transport.close();
+ }
+ }
+
+ private Set<AmqpProtocolVersion> convertFromModelProtocolsToAmqp(Collection<Protocol> modelProtocols)
+ {
+ Set<AmqpProtocolVersion> amqpProtocols = new HashSet<AmqpProtocolVersion>();
+ for (Protocol protocol : modelProtocols)
+ {
+ amqpProtocols.add(protocol.toAmqpProtocolVersion());
+ }
+ return amqpProtocols;
+ }
+
+ private SSLContext createSslContext()
+ {
+ KeyStore keyStore = _broker.getDefaultKeyStore();
+ if (keyStore == null)
+ {
+ throw new IllegalConfigurationException("SSL was requested on AMQP port '"
+ + this.getName() + "' but no key store defined");
+ }
+
+ TrustStore trustStore = _broker.getDefaultTrustStore();
+ if (((Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH)) && trustStore == null)
+ {
+ throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '"
+ + this.getName() + "' but no trust store defined");
+ }
+
+ String keystorePath = (String)keyStore.getAttribute(KeyStore.PATH);
+ String keystorePassword = keyStore.getPassword();
+ String keystoreType = (String)keyStore.getAttribute(KeyStore.TYPE);
+ String keyManagerFactoryAlgorithm = (String)keyStore.getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
+ String certAlias = (String)keyStore.getAttribute(KeyStore.CERTIFICATE_ALIAS);
+
+ final SSLContext sslContext;
+ try
+ {
+ if(trustStore != null)
+ {
+ String trustStorePassword = trustStore.getPassword();
+ String trustStoreType = (String)trustStore.getAttribute(TrustStore.TYPE);
+ String trustManagerFactoryAlgorithm = (String)trustStore.getAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM);
+ String trustStorePath = (String)trustStore.getAttribute(TrustStore.PATH);
+
+ sslContext = SSLContextFactory.buildClientContext(trustStorePath,
+ trustStorePassword,
+ trustStoreType,
+ trustManagerFactoryAlgorithm,
+ keystorePath,
+ keystorePassword, keystoreType, keyManagerFactoryAlgorithm,
+ certAlias);
+ }
+ else
+ {
+ sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm);
+ }
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new RuntimeException("Unable to create SSLContext for key or trust store", e);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Unable to create SSLContext - unable to load key/trust store", e);
+ }
+ return sslContext;
+ }
+
+ private AmqpProtocolVersion getDefaultAmqpSupportedReply()
+ {
+ String defaultAmqpSupportedReply = System.getProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY);
+ if (defaultAmqpSupportedReply != null)
+ {
+ return AmqpProtocolVersion.valueOf(defaultAmqpSupportedReply);
+ }
+ return null;
+ }
+
+
+ class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
+ {
+ private final InetSocketAddress _bindingSocketAddress;
+ private final Boolean _tcpNoDelay;
+ private final Integer _sendBufferSize;
+ private final Integer _receiveBufferSize;
+ private final boolean _needClientAuth;
+ private final boolean _wantClientAuth;
+
+ public ServerNetworkTransportConfiguration(
+ InetSocketAddress bindingSocketAddress, boolean tcpNoDelay,
+ int sendBufferSize, int receiveBufferSize,
+ boolean needClientAuth, boolean wantClientAuth)
+ {
+ _bindingSocketAddress = bindingSocketAddress;
+ _tcpNoDelay = tcpNoDelay;
+ _sendBufferSize = sendBufferSize;
+ _receiveBufferSize = receiveBufferSize;
+ _needClientAuth = needClientAuth;
+ _wantClientAuth = wantClientAuth;
+ }
+
+ @Override
+ public boolean wantClientAuth()
+ {
+ return _wantClientAuth;
+ }
+
+ @Override
+ public boolean needClientAuth()
+ {
+ return _needClientAuth;
+ }
+
+ @Override
+ public Boolean getTcpNoDelay()
+ {
+ return _tcpNoDelay;
+ }
+
+ @Override
+ public Integer getSendBufferSize()
+ {
+ return _sendBufferSize;
+ }
+
+ @Override
+ public Integer getReceiveBufferSize()
+ {
+ return _receiveBufferSize;
+ }
+
+ @Override
+ public InetSocketAddress getAddress()
+ {
+ return _bindingSocketAddress;
+ }
+ };
+}
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
index 8c2bc98ba7..ac4b0255d5 100644
--- 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
@@ -29,38 +29,50 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
+
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.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
+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.User;
+import org.apache.qpid.server.model.VirtualHostAlias;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
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;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+import org.apache.qpid.server.security.SecurityManager;
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;
+ protected final Broker _broker;
- private AuthenticationProviderAdapter(BrokerAdapter brokerAdapter,
- final T authManager)
- {
- super(UUIDGenerator.generateRandomUUID());
- _broker = brokerAdapter;
- _authManager = authManager;
- }
+ private GroupPrincipalAccessor _groupAccessor;
- public static AuthenticationProviderAdapter createAuthenticationProviderAdapter(BrokerAdapter brokerAdapter,
- final AuthenticationManager authManager)
+ private Object _type;
+
+ private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes)
{
- return authManager instanceof PrincipalDatabaseAuthenticationManager
- ? new PrincipalDatabaseAuthenticationManagerAdapter(brokerAdapter, (PrincipalDatabaseAuthenticationManager) authManager)
- : new SimpleAuthenticationProviderAdapter(brokerAdapter, authManager);
+ super(id, null, attributes, broker.getTaskExecutor());
+ _authManager = authManager;
+ _broker = broker;
+ _type = authManager instanceof PrincipalDatabaseAuthenticationManager? PrincipalDatabaseAuthenticationManager.class.getSimpleName() : AuthenticationManager.class.getSimpleName() ;
+ addParent(Broker.class, broker);
}
T getAuthManager()
@@ -77,7 +89,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
@Override
public String getName()
{
- return _authManager.getClass().getSimpleName();
+ return (String)getAttribute(AuthenticationProvider.NAME);
}
@Override
@@ -147,7 +159,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
{
if(TYPE.equals(name))
{
- return _authManager.getClass().getSimpleName();
+ return _type;
}
else if(CREATED.equals(name))
{
@@ -165,10 +177,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
{
return LifetimePolicy.PERMANENT;
}
- else if(NAME.equals(name))
- {
- return getName();
- }
else if(STATE.equals(name))
{
return State.ACTIVE; // TODO
@@ -191,44 +199,86 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
}
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass,
- Map<String, Object> attributes,
- ConfiguredObject... otherParents)
+ public boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
{
- return null;
+ if(desiredState == State.DELETED)
+ {
+ return true;
+ }
+ else if(desiredState == State.ACTIVE)
+ {
+ if (_groupAccessor == null)
+ {
+ throw new IllegalStateTransitionException("Cannot transit into ACTIVE state with null group accessor!");
+ }
+ _authManager.initialise();
+ return true;
+ }
+ else if(desiredState == State.STOPPED)
+ {
+ _authManager.close();
+ return true;
+ }
+ return false;
}
- private static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager>
+ @Override
+ public SubjectCreator getSubjectCreator()
{
+ return new SubjectCreator(_authManager, _groupAccessor);
+ }
+
+ public void setGroupAccessor(GroupPrincipalAccessor groupAccessor)
+ {
+ _groupAccessor = groupAccessor;
+ }
+
+ public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager>
+ {
+
public SimpleAuthenticationProviderAdapter(
- BrokerAdapter brokerAdapter, AuthenticationManager authManager)
+ UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes)
+ {
+ super(id, broker,authManager, attributes);
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
{
- super(brokerAdapter,authManager);
+ throw new UnsupportedOperationException();
}
}
- private static class PrincipalDatabaseAuthenticationManagerAdapter
+ public static class PrincipalDatabaseAuthenticationManagerAdapter
extends AuthenticationProviderAdapter<PrincipalDatabaseAuthenticationManager>
implements PasswordCredentialManagingAuthenticationProvider
{
public PrincipalDatabaseAuthenticationManagerAdapter(
- BrokerAdapter brokerAdapter, PrincipalDatabaseAuthenticationManager authManager)
+ UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes)
{
- super(brokerAdapter, authManager);
+ super(id, broker, authManager, attributes);
}
@Override
public boolean createUser(String username, String password, Map<String, String> attributes)
{
- return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray());
+ if(getSecurityManager().authoriseUserOperation(Operation.CREATE, username))
+ {
+ return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray());
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission to create new user");
+ }
}
@Override
public void deleteUser(String username) throws AccountNotFoundException
{
- if(getSecurityManager().authoriseMethod(Operation.DELETE,
- "UserManagement",
- "deleteUser"))
+ if(getSecurityManager().authoriseUserOperation(Operation.DELETE, username))
{
getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username));
@@ -239,9 +289,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
}
}
- private org.apache.qpid.server.security.SecurityManager getSecurityManager()
+ private SecurityManager getSecurityManager()
{
- return ApplicationRegistry.getInstance().getSecurityManager();
+ return _broker.getSecurityManager();
}
private PrincipalDatabase getPrincipalDatabase()
@@ -252,18 +302,13 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
@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"))
+ if(getSecurityManager().authoriseUserOperation(Operation.UPDATE, username))
{
- getPrincipalDatabase().reload();
+ getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray());
}
else
{
- throw new AccessControlException("Do not have permission to reload principal database");
+ throw new AccessControlException("Do not have permission to set password");
}
}
@@ -274,34 +319,41 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
Map<String, Map<String,String>> users = new HashMap<String, Map<String, String>>();
for(Principal principal : getPrincipalDatabase().getUsers())
{
- users.put(principal.getName(), Collections.EMPTY_MAP);
+ users.put(principal.getName(), Collections.<String, String>emptyMap());
}
return users;
}
+ public void reload() throws IOException
+ {
+ getPrincipalDatabase().reload();
+ }
+
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass,
+ public <C extends ConfiguredObject> C addChild(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"))
+ String username = (String) attributes.get("name");
+ String password = (String) attributes.get("password");
+ Principal p = new UsernamePrincipal(username);
+
+ if(createUser(username, password,null))
{
- if(getPrincipalDatabase().createPrincipal(p, ((String)attributes.get("password")).toCharArray()))
- {
- return (C) new PrincipalAdapter(p);
- }
+ @SuppressWarnings("unchecked")
+ C pricipalAdapter = (C) new PrincipalAdapter(p, getTaskExecutor());
+ return pricipalAdapter;
}
else
{
- throw new AccessControlException("Do not have permission to create a new user");
+ //TODO? Silly interface on the PrincipalDatabase at fault
+ throw new RuntimeException("Failed to create user");
}
-
}
- return super.createChild(childClass, attributes, otherParents);
+ return super.addChild(childClass, attributes, otherParents);
}
@Override
@@ -313,9 +365,11 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
Collection<User> principals = new ArrayList<User>(users.size());
for(Principal user : users)
{
- principals.add(new PrincipalAdapter(user));
+ principals.add(new PrincipalAdapter(user, getTaskExecutor()));
}
- return (Collection<C>) Collections.unmodifiableCollection(principals);
+ @SuppressWarnings("unchecked")
+ Collection<C> unmodifiablePrincipals = (Collection<C>) Collections.unmodifiableCollection(principals);
+ return unmodifiablePrincipals;
}
else
{
@@ -328,20 +382,14 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
private final Principal _user;
- public PrincipalAdapter(Principal user)
+ public PrincipalAdapter(Principal user, TaskExecutor taskExecutor)
{
- super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()));
+ super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()), taskExecutor);
_user = user;
}
@Override
- public String getPassword()
- {
- return null;
- }
-
- @Override
public void setPassword(String password)
{
try
@@ -445,6 +493,10 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
{
return getId();
}
+ else if(PASSWORD.equals(name))
+ {
+ return null; // for security reasons we don't expose the password
+ }
else if(NAME.equals(name))
{
return getName();
@@ -453,20 +505,19 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
}
@Override
- public Object setAttribute(String name, Object expected, Object desired)
+ public boolean changeAttribute(String name, Object expected, Object desired)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
if(name.equals(PASSWORD))
{
setPassword((String)desired);
+ return true;
}
- return super.setAttribute(name,
- expected,
- desired);
+ return super.changeAttribute(name, expected, desired);
}
@Override
- public State setDesiredState(State currentState, State desiredState)
+ protected boolean setState(State currentState, State desiredState)
throws IllegalStateTransitionException, AccessControlException
{
if(desiredState == State.DELETED)
@@ -479,9 +530,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana
{
LOGGER.warn("Failed to delete user " + _user, e);
}
- return State.DELETED;
+ return true;
}
- return super.setDesiredState(currentState, desiredState);
+ return false;
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
new file mode 100644
index 0000000000..e5108ebbcf
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * 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 java.util.UUID;
+
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.PrincipalDatabaseAuthenticationManagerAdapter;
+import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.SimpleAuthenticationProviderAdapter;
+
+public class AuthenticationProviderFactory
+{
+ private final Iterable<AuthenticationManagerFactory> _factories;
+
+ public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader)
+ {
+ _factories = authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class);
+ }
+
+ /**
+ * Creates {@link AuthenticationProvider} for given ID, {@link Broker} and attributes.
+ * <p>
+ * The configured {@link AuthenticationManagerFactory}'s are used to try to create the {@link AuthenticationProvider}.
+ * The first non-null instance is returned. The factories are used in non-deterministic order.
+ * @param groupPrincipalAccessor TODO
+ */
+ public AuthenticationProvider create(UUID id, Broker broker, Map<String, Object> attributes, GroupPrincipalAccessor groupPrincipalAccessor)
+ {
+ for (AuthenticationManagerFactory factory : _factories)
+ {
+ AuthenticationManager manager = factory.createInstance(attributes);
+ if (manager != null)
+ {
+ AuthenticationProviderAdapter<?> authenticationProvider;
+ if (manager instanceof PrincipalDatabaseAuthenticationManager)
+ {
+ authenticationProvider = new PrincipalDatabaseAuthenticationManagerAdapter(id, broker,
+ (PrincipalDatabaseAuthenticationManager) manager, attributes);
+ }
+ else
+ {
+ authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes);
+ }
+ authenticationProvider.setGroupAccessor(groupPrincipalAccessor);
+ return authenticationProvider;
+ }
+ }
+
+ throw new IllegalArgumentException("No authentication provider factory found for configuration attributes " + attributes);
+ }
+
+}
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
index abd3160686..eb2d0dd7e2 100644
--- 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
@@ -48,7 +48,7 @@ final class BindingAdapter extends AbstractAdapter implements Binding
ExchangeAdapter exchangeAdapter,
QueueAdapter queueAdapter)
{
- super(binding.getId());
+ super(binding.getId(), queueAdapter.getTaskExecutor());
_binding = binding;
_exchange = exchangeAdapter;
_queue = queueAdapter;
@@ -206,27 +206,20 @@ final class BindingAdapter extends AbstractAdapter implements Binding
}
@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,
+ protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException,
AccessControlException
{
if (desiredState == State.DELETED)
{
delete();
- return State.DELETED;
+ return true;
}
- return super.setDesiredState(currentState, desiredState);
+ return false;
}
}
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
index f1cce2d45c..533ecfe937 100644
--- 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
@@ -21,82 +21,211 @@
package org.apache.qpid.server.model.adapter;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
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 java.util.UUID;
+
+import javax.net.ssl.KeyManagerFactory;
+
+import org.apache.log4j.Logger;
import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfigurationChangeListener;
import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Plugin;
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.TrustStore;
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.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.group.FileGroupManager;
+import org.apache.qpid.server.security.group.GroupManager;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.util.MapValueConverter;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHostRegistry.RegistryChangeListener,
- IApplicationRegistry.PortBindingListener,
- IAuthenticationManagerRegistry.RegistryChangeListener
+public class BrokerAdapter extends AbstractAdapter implements Broker, ConfigurationChangeListener
{
-
- 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));
- }
- }
-
+ private static final Logger LOGGER = Logger.getLogger(BrokerAdapter.class);
+
+ @SuppressWarnings("serial")
+ public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{
+ put(ALERT_THRESHOLD_MESSAGE_AGE, Long.class);
+ put(ALERT_THRESHOLD_MESSAGE_COUNT, Long.class);
+ put(ALERT_THRESHOLD_QUEUE_DEPTH, Long.class);
+ put(ALERT_THRESHOLD_MESSAGE_SIZE, Long.class);
+ put(ALERT_REPEAT_GAP, Long.class);
+ put(FLOW_CONTROL_SIZE_BYTES, Long.class);
+ put(FLOW_CONTROL_RESUME_SIZE_BYTES, Long.class);
+ put(HOUSEKEEPING_CHECK_PERIOD, Long.class);
+
+ put(DEAD_LETTER_QUEUE_ENABLED, Boolean.class);
+ put(STATISTICS_REPORTING_RESET_ENABLED, Boolean.class);
+
+ put(MAXIMUM_DELIVERY_ATTEMPTS, Integer.class);
+ put(SESSION_COUNT_LIMIT, Integer.class);
+ put(HEART_BEAT_DELAY, Integer.class);
+ put(STATISTICS_REPORTING_PERIOD, Integer.class);
+
+ put(ACL_FILE, String.class);
+ put(NAME, String.class);
+ put(DEFAULT_VIRTUAL_HOST, String.class);
+ put(DEFAULT_AUTHENTICATION_PROVIDER, String.class);
+
+ put(KEY_STORE_PATH, String.class);
+ put(KEY_STORE_PASSWORD, String.class);
+ put(KEY_STORE_CERT_ALIAS, String.class);
+ put(TRUST_STORE_PATH, String.class);
+ put(TRUST_STORE_PASSWORD, String.class);
+ put(GROUP_FILE, String.class);
+ }});
+
+ public static final int DEFAULT_STATISTICS_REPORTING_PERIOD = 0;
+ public static final boolean DEFAULT_STATISTICS_REPORTING_RESET_ENABLED = false;
+ public static final long DEFAULT_ALERT_REPEAT_GAP = 30000l;
+ public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE = 0l;
+ public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT = 0l;
+ public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE = 0l;
+ public static final long DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH = 0l;
+ public static final boolean DEFAULT_DEAD_LETTER_QUEUE_ENABLED = false;
+ public static final int DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS = 0;
+ public static final long DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES = 0l;
+ public static final long DEFAULT_FLOW_CONTROL_SIZE_BYTES = 0l;
+ public static final long DEFAULT_HOUSEKEEPING_CHECK_PERIOD = 30000l;
+ public static final int DEFAULT_HEART_BEAT_DELAY = 0;
+ public static final int DEFAULT_SESSION_COUNT_LIMIT = 256;
+ public static final String DEFAULT_NAME = "QpidBroker";
+ private static final String DEFAULT_KEY_STORE_NAME = "defaultKeyStore";
+ private static final String DEFAULT_TRUST_STORE_NAME = "defaultTrustStore";
+ private static final String DEFAULT_GROUP_PROFIDER_NAME = "defaultGroupProvider";
+
+ private static final String DUMMY_PASSWORD_MASK = "********";
+
+ @SuppressWarnings("serial")
+ private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{
+ put(Broker.STATISTICS_REPORTING_PERIOD, DEFAULT_STATISTICS_REPORTING_PERIOD);
+ put(Broker.STATISTICS_REPORTING_RESET_ENABLED, DEFAULT_STATISTICS_REPORTING_RESET_ENABLED);
+ put(Broker.ALERT_REPEAT_GAP, DEFAULT_ALERT_REPEAT_GAP);
+ put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE);
+ put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT);
+ put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE);
+ put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH);
+ put(Broker.DEAD_LETTER_QUEUE_ENABLED, DEFAULT_DEAD_LETTER_QUEUE_ENABLED);
+ put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS);
+ put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES);
+ put(Broker.FLOW_CONTROL_SIZE_BYTES, DEFAULT_FLOW_CONTROL_SIZE_BYTES);
+ put(Broker.HOUSEKEEPING_CHECK_PERIOD, DEFAULT_HOUSEKEEPING_CHECK_PERIOD);
+ put(Broker.HEART_BEAT_DELAY, DEFAULT_HEART_BEAT_DELAY);
+ put(Broker.SESSION_COUNT_LIMIT, DEFAULT_SESSION_COUNT_LIMIT);
+ put(Broker.NAME, DEFAULT_NAME);
+ }});
+
+
+
+
+ private final StatisticsGatherer _statisticsGatherer;
+ private final VirtualHostRegistry _virtualHostRegistry;
+ private final LogRecorder _logRecorder;
+ private final RootMessageLogger _rootMessageLogger;
+ private StatisticsAdapter _statistics;
+
+ private final Map<String, VirtualHost> _vhostAdapters = new HashMap<String, VirtualHost>();
+ private final Map<Integer, Port> _portAdapters = new HashMap<Integer, Port>();
+ private final Map<String, AuthenticationProvider> _authenticationProviders = new HashMap<String, AuthenticationProvider>();
+ private final Map<String, GroupProvider> _groupProviders = new HashMap<String, GroupProvider>();
+ private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>();
+ private final Map<UUID, KeyStore> _keyStores = new HashMap<UUID, KeyStore>();
+ private final Map<UUID, TrustStore> _trustStores = new HashMap<UUID, TrustStore>();
+
+ private final AuthenticationProviderFactory _authenticationProviderFactory;
+ private AuthenticationProvider _defaultAuthenticationProvider;
+
+ private final PortFactory _portFactory;
+ private final SecurityManager _securityManager;
+ private final UUID _defaultKeyStoreId;
+ private final UUID _defaultTrustStoreId;
+
+ public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry,
+ LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory,
+ PortFactory portFactory, TaskExecutor taskExecutor)
+ {
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor);
+ _statisticsGatherer = statisticsGatherer;
+ _virtualHostRegistry = virtualHostRegistry;
+ _logRecorder = logRecorder;
+ _rootMessageLogger = rootMessageLogger;
+ _statistics = new StatisticsAdapter(statisticsGatherer);
+ _authenticationProviderFactory = authenticationProviderFactory;
+ _portFactory = portFactory;
+ _securityManager = new SecurityManager((String)getAttribute(ACL_FILE));
+
+ _defaultKeyStoreId = UUIDGenerator.generateBrokerChildUUID(KeyStore.class.getSimpleName(), DEFAULT_KEY_STORE_NAME);
+ _defaultTrustStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_TRUST_STORE_NAME);
+ createBrokerChildrenFromAttributes();
+ }
+
+ /*
+ * A temporary method to create broker children that can be only configured via broker attributes
+ */
+ private void createBrokerChildrenFromAttributes()
+ {
+ String groupFile = (String) getAttribute(GROUP_FILE);
+ if (groupFile != null)
+ {
+ GroupManager groupManager = new FileGroupManager(groupFile);
+ UUID groupProviderId = UUIDGenerator.generateBrokerChildUUID(GroupProvider.class.getSimpleName(),
+ DEFAULT_GROUP_PROFIDER_NAME);
+ GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(groupProviderId, groupManager, this);
+ addGroupProvider(groupProviderAdapter);
+ }
+ Map<String, Object> actualAttributes = getActualAttributes();
+ String keyStorePath = (String) getAttribute(KEY_STORE_PATH);
+ if (keyStorePath != null)
+ {
+ Map<String, Object> keyStoreAttributes = new HashMap<String, Object>();
+ keyStoreAttributes.put(KeyStore.NAME, DEFAULT_KEY_STORE_NAME);
+ keyStoreAttributes.put(KeyStore.PATH, keyStorePath);
+ keyStoreAttributes.put(KeyStore.PASSWORD, (String) actualAttributes.get(KEY_STORE_PASSWORD));
+ keyStoreAttributes.put(KeyStore.TYPE, java.security.KeyStore.getDefaultType());
+ keyStoreAttributes.put(KeyStore.CERTIFICATE_ALIAS, getAttribute(KEY_STORE_CERT_ALIAS));
+ keyStoreAttributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
+ KeyStoreAdapter KeyStoreAdapter = new KeyStoreAdapter(_defaultKeyStoreId, this, keyStoreAttributes);
+ addKeyStore(KeyStoreAdapter);
+ }
+ String trustStorePath = (String) getAttribute(TRUST_STORE_PATH);
+ if (trustStorePath != null)
+ {
+ Map<String, Object> trsustStoreAttributes = new HashMap<String, Object>();
+ trsustStoreAttributes.put(TrustStore.NAME, DEFAULT_TRUST_STORE_NAME);
+ trsustStoreAttributes.put(TrustStore.PATH, trustStorePath);
+ trsustStoreAttributes.put(TrustStore.PASSWORD, (String) actualAttributes.get(TRUST_STORE_PASSWORD));
+ trsustStoreAttributes.put(TrustStore.TYPE, java.security.KeyStore.getDefaultType());
+ trsustStoreAttributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
+ TrustStoreAdapter trustStore = new TrustStoreAdapter(_defaultTrustStoreId, this, trsustStoreAttributes);
+ addTrustStore(trustStore);
}
}
-
public Collection<VirtualHost> getVirtualHosts()
{
synchronized(_vhostAdapters)
@@ -105,81 +234,57 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
}
}
- private void populatePorts()
+
+ public Collection<Port> getPorts()
{
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);
- }
+ final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values());
+ return ports;
}
}
- public Collection<Port> getPorts()
+ public Collection<AuthenticationProvider> getAuthenticationProviders()
{
- synchronized (_portAdapters)
+ synchronized (_authenticationProviders)
{
- final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values());
- if(_httpManagementPorts != null)
- {
- ports.addAll(_httpManagementPorts);
- }
- return ports;
+ return new ArrayList<AuthenticationProvider>(_authenticationProviders.values());
}
}
- private void populateAuthenticationManagers()
+ public AuthenticationProvider getAuthenticationProviderByName(String authenticationProviderName)
{
- synchronized (_authManagerAdapters)
+ Collection<AuthenticationProvider> providers = getAuthenticationProviders();
+ for (AuthenticationProvider authenticationProvider : providers)
{
- IAuthenticationManagerRegistry authenticationManagerRegistry =
- _applicationRegistry.getAuthenticationManagerRegistry();
- if(authenticationManagerRegistry != null)
+ if (authenticationProvider.getName().equals(authenticationProviderName))
{
- 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()));
- }
- }
+ return authenticationProvider;
}
}
+ return null;
}
- public Collection<AuthenticationProvider> getAuthenticationProviders()
+ @Override
+ public AuthenticationProvider getDefaultAuthenticationProvider()
+ {
+ return _defaultAuthenticationProvider;
+ }
+
+ public void setDefaultAuthenticationProvider(AuthenticationProvider provider)
+ {
+ _defaultAuthenticationProvider = provider;
+ }
+
+ @Override
+ public Collection<GroupProvider> getGroupProviders()
{
- synchronized (_authManagerAdapters)
+ synchronized (_groupProviders)
{
- final ArrayList<AuthenticationProvider> authManagers =
- new ArrayList<AuthenticationProvider>(_authManagerAdapters.values());
- return authManagers;
+ final ArrayList<GroupProvider> groupManagers =
+ new ArrayList<GroupProvider>(_groupProviders.values());
+ return groupManagers;
}
-
}
public VirtualHost createVirtualHost(final String name,
@@ -193,22 +298,29 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
return null; //TODO
}
- public VirtualHost createVirtualHost(final Map<String, Object> attributes)
+ private VirtualHost createVirtualHost(final Map<String, Object> attributes)
throws AccessControlException, IllegalArgumentException
{
- return null; //TODO
+ final VirtualHostAdapter virtualHostAdapter = new VirtualHostAdapter(UUID.randomUUID(), attributes, this,
+ _statisticsGatherer, getTaskExecutor());
+ addVirtualHost(virtualHostAdapter);
+ virtualHostAdapter.setDesiredState(State.INITIALISING, State.ACTIVE);
+ return virtualHostAdapter;
}
- public void deleteVirtualHost(final VirtualHost vhost)
- throws AccessControlException, IllegalStateException
+ private boolean deleteVirtualHost(final VirtualHost vhost) throws AccessControlException, IllegalStateException
{
- //TODO
- throw new UnsupportedOperationException("Not yet implemented");
+ synchronized (_vhostAdapters)
+ {
+ _vhostAdapters.remove(vhost);
+ }
+ vhost.removeChangeListener(this);
+ return true;
}
public String getName()
{
- return _name;
+ return (String)getAttribute(NAME);
}
public String setName(final String currentName, final String desiredName)
@@ -262,6 +374,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
return _statistics;
}
+ @SuppressWarnings("unchecked")
@Override
public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
{
@@ -277,12 +390,30 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
{
return (Collection<C>) getAuthenticationProviders();
}
+ else if(clazz == GroupProvider.class)
+ {
+ return (Collection<C>) getGroupProviders();
+ }
+ else if(clazz == KeyStore.class)
+ {
+ return (Collection<C>) getKeyStores();
+ }
+ else if(clazz == TrustStore.class)
+ {
+ return (Collection<C>) getTrustStores();
+ }
+ else if(clazz == Plugin.class)
+ {
+ return (Collection<C>) getPlugins();
+ }
return Collections.emptySet();
}
+ //TODO: ACL
+ @SuppressWarnings("unchecked")
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
if(childClass == VirtualHost.class)
{
@@ -302,111 +433,107 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
}
}
- private Port createPort(Map<String, Object> attributes)
+ private void addPort(Port port)
{
- // TODO
- return null;
+ synchronized (_portAdapters)
+ {
+ int portNumber = port.getPort();
+ if(_portAdapters.containsKey(portNumber))
+ {
+ throw new IllegalArgumentException("Cannot add port " + port + " because port number " + portNumber + " already configured");
+ }
+ _portAdapters.put(portNumber, port);
+ }
+ port.addChangeListener(this);
}
- private AuthenticationProvider createAuthenticationProvider(Map<String,Object> attributes)
+ private Port createPort(Map<String, Object> attributes)
{
- // TODO
- return null;
+ Port port = _portFactory.createPort(UUID.randomUUID(), this, attributes);
+ addPort(port);
+ return port;
}
+ private AuthenticationProvider createAuthenticationProvider(Map<String, Object> attributes)
+ {
+ // it's cheap to create the groupPrincipalAccessor on the fly
+ GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(_groupProviders.values());
+
+ AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create(UUID.randomUUID(), this, attributes, groupPrincipalAccessor);
+ addAuthenticationProvider(authenticationProvider);
+ return authenticationProvider;
+ }
- public void virtualHostRegistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ /**
+ * @throws IllegalConfigurationException if an AuthenticationProvider with the same name already exists
+ */
+ private void addAuthenticationProvider(AuthenticationProvider authenticationProvider)
{
- VirtualHostAdapter adapter = null;
- synchronized (_vhostAdapters)
+ String name = authenticationProvider.getName();
+ synchronized (_authenticationProviders)
{
- if(!_vhostAdapters.containsKey(virtualHost))
+ if(_authenticationProviders.containsKey(name))
{
- adapter = new VirtualHostAdapter(this, virtualHost);
- _vhostAdapters.put(virtualHost, adapter);
+ throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with name " + name + " already exists");
}
+ _authenticationProviders.put(name, authenticationProvider);
}
- if(adapter != null)
- {
- childAdded(adapter);
- }
+ authenticationProvider.addChangeListener(this);
}
- public void virtualHostUnregistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ private void addGroupProvider(GroupProvider groupProvider)
{
- VirtualHostAdapter adapter = null;
-
- synchronized (_vhostAdapters)
- {
- adapter = _vhostAdapters.remove(virtualHost);
- }
- if(adapter != null)
+ synchronized (_groupProviders)
{
- childRemoved(adapter);
+ String name = groupProvider.getName();
+ if(_groupProviders.containsKey(name))
+ {
+ throw new IllegalConfigurationException("Cannot add GroupProvider because one with name " + name + " already exists");
+ }
+ _groupProviders.put(name, groupProvider);
}
+ groupProvider.addChangeListener(this);
}
- @Override
- public void authenticationManagerRegistered(AuthenticationManager authenticationManager)
+ private boolean deleteGroupProvider(GroupProvider object)
+ {
+ throw new UnsupportedOperationException("Not implemented yet!");
+ }
+
+ private void addKeyStore(KeyStore keyStore)
{
- AuthenticationProviderAdapter adapter = null;
- synchronized (_authManagerAdapters)
+ synchronized (_keyStores)
{
- if(!_authManagerAdapters.containsKey(authenticationManager))
+ if(_keyStores.containsKey(keyStore.getId()))
{
- adapter =
- AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, authenticationManager);
- _authManagerAdapters.put(authenticationManager, adapter);
+ throw new IllegalConfigurationException("Cannot add KeyStore because one with id " + keyStore.getId() + " already exists");
}
+ _keyStores.put(keyStore.getId(), keyStore);
}
- if(adapter != null)
- {
- childAdded(adapter);
- }
+ keyStore.addChangeListener(this);
}
- @Override
- public void authenticationManagerUnregistered(AuthenticationManager authenticationManager)
+ private boolean deleteKeyStore(KeyStore object)
{
- AuthenticationProviderAdapter adapter;
- synchronized (_authManagerAdapters)
- {
- adapter = _authManagerAdapters.remove(authenticationManager);
- }
- if(adapter != null)
- {
- childRemoved(adapter);
- }
+ throw new UnsupportedOperationException("Not implemented yet!");
}
-
- @Override
- public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress)
+ private void addTrustStore(TrustStore trustStore)
{
- synchronized (_portAdapters)
+ synchronized (_trustStores)
{
- if(!_portAdapters.containsKey(acceptor))
+ if(_trustStores.containsKey(trustStore.getId()))
{
- PortAdapter adapter = new PortAdapter(this, acceptor, bindAddress);
- _portAdapters.put(acceptor, adapter);
- childAdded(adapter);
+ throw new IllegalConfigurationException("Cannot add TrustStore because one with id " + trustStore.getId() + " already exists");
}
+ _trustStores.put(trustStore.getId(), trustStore);
}
+ trustStore.addChangeListener(this);
}
- @Override
- public void unbound(QpidAcceptor acceptor)
+ private boolean deleteTrustStore(TrustStore object)
{
- PortAdapter adapter = null;
-
- synchronized (_portAdapters)
- {
- adapter = _portAdapters.remove(acceptor);
- }
- if(adapter != null)
- {
- childRemoved(adapter);
- }
+ throw new UnsupportedOperationException("Not implemented yet!");
}
@Override
@@ -422,10 +549,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
{
return getId();
}
- else if(NAME.equals(name))
- {
- return getName();
- }
else if(STATE.equals(name))
{
return State.ACTIVE;
@@ -481,14 +604,316 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos
{
// TODO
}
+ else if (DEFAULT_AUTHENTICATION_PROVIDER.equals(name))
+ {
+ return _defaultAuthenticationProvider == null ? null : _defaultAuthenticationProvider.getName();
+ }
+ else if (KEY_STORE_PASSWORD.equals(name))
+ {
+ return DUMMY_PASSWORD_MASK;
+ }
+ else if (TRUST_STORE_PASSWORD.equals(name))
+ {
+ return DUMMY_PASSWORD_MASK;
+ }
+ return super.getAttribute(name);
+ }
- return super.getAttribute(name); //TODO - Implement.
+ private boolean deletePort(Port portAdapter)
+ {
+ Port removedPort = null;
+ synchronized (_portAdapters)
+ {
+ removedPort = _portAdapters.remove(portAdapter.getPort());
+ }
+ return removedPort != null;
+ }
+
+ private boolean deleteAuthenticationProvider(AuthenticationProvider authenticationProvider)
+ {
+ AuthenticationProvider removedAuthenticationProvider = null;
+ synchronized (_authenticationProviders)
+ {
+ removedAuthenticationProvider = _authenticationProviders.remove(authenticationProvider.getName());
+ }
+ return removedAuthenticationProvider != null;
+ }
+
+ private void addVirtualHost(VirtualHost virtualHost)
+ {
+ synchronized (_vhostAdapters)
+ {
+ String name = virtualHost.getName();
+ if (_vhostAdapters.containsKey(name))
+ {
+ throw new IllegalConfigurationException("Virtual host with name " + name + " is already specified!");
+ }
+ _vhostAdapters.put(name, virtualHost);
+ }
+ virtualHost.addChangeListener(this);
}
@Override
- public Object setAttribute(String name, Object expected, Object desired)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
+ public boolean setState(State currentState, State desiredState)
+ {
+ if (desiredState == State.ACTIVE)
+ {
+ changeState(_groupProviders, currentState, State.ACTIVE, false);
+ changeState(_authenticationProviders, currentState, State.ACTIVE, false);
+
+ CurrentActor.set(new BrokerActor(getRootMessageLogger()));
+ try
+ {
+ changeState(_vhostAdapters, currentState, State.ACTIVE, false);
+ }
+ finally
+ {
+ CurrentActor.remove();
+ }
+
+ changeState(_portAdapters, currentState,State.ACTIVE, false);
+ changeState(_plugins, currentState,State.ACTIVE, false);
+ return true;
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ changeState(_plugins, currentState,State.STOPPED, true);
+ changeState(_portAdapters, currentState, State.STOPPED, true);
+ changeState(_vhostAdapters,currentState, State.STOPPED, true);
+ changeState(_authenticationProviders, currentState, State.STOPPED, true);
+ changeState(_groupProviders, currentState, State.STOPPED, true);
+ return true;
+ }
+ return false;
+ }
+
+ private void changeState(Map<?, ? extends ConfiguredObject> configuredObjectMap, State currentState, State desiredState, boolean swallowException)
+ {
+ synchronized(configuredObjectMap)
+ {
+ Collection<? extends ConfiguredObject> adapters = configuredObjectMap.values();
+ for (ConfiguredObject configuredObject : adapters)
+ {
+ if (State.ACTIVE.equals(desiredState) && State.QUIESCED.equals(configuredObject.getActualState()))
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(configuredObject + " cannot be activated as it is " +State.QUIESCED);
+ }
+ continue;
+ }
+ try
+ {
+ configuredObject.setDesiredState(currentState, desiredState);
+ }
+ catch(RuntimeException e)
+ {
+ if (swallowException)
+ {
+ LOGGER.error("Failed to stop " + configuredObject, e);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void stateChanged(ConfiguredObject object, State oldState, State newState)
+ {
+ if(newState == State.DELETED)
+ {
+ boolean childDeleted = false;
+ if(object instanceof AuthenticationProvider)
+ {
+ childDeleted = deleteAuthenticationProvider((AuthenticationProvider)object);
+ }
+ else if(object instanceof Port)
+ {
+ childDeleted = deletePort((Port)object);
+ }
+ else if(object instanceof VirtualHost)
+ {
+ childDeleted = deleteVirtualHost((VirtualHost)object);
+ }
+ else if(object instanceof GroupProvider)
+ {
+ childDeleted = deleteGroupProvider((GroupProvider)object);
+ }
+ else if(object instanceof KeyStore)
+ {
+ childDeleted = deleteKeyStore((KeyStore)object);
+ }
+ else if(object instanceof TrustStore)
+ {
+ childDeleted = deleteTrustStore((TrustStore)object);
+ }
+ if(childDeleted)
+ {
+ childRemoved(object);
+ }
+ }
+ }
+
+ @Override
+ public void childAdded(ConfiguredObject object, ConfiguredObject child)
+ {
+ // no-op
+ }
+
+ @Override
+ public void childRemoved(ConfiguredObject object, ConfiguredObject child)
+ {
+ // no-op
+ }
+
+ @Override
+ public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue)
+ {
+ // no-op
+ }
+
+ private void addPlugin(ConfiguredObject plugin)
+ {
+ synchronized(_plugins)
+ {
+ if (_plugins.containsKey(plugin.getId()))
+ {
+ throw new IllegalConfigurationException("Plugin with id '" + plugin.getId() + "' is already registered!");
+ }
+ _plugins.put(plugin.getId(), plugin);
+ }
+ plugin.addChangeListener(this);
+ }
+
+
+ private Collection<ConfiguredObject> getPlugins()
+ {
+ synchronized(_plugins)
+ {
+ return Collections.unmodifiableCollection(_plugins.values());
+ }
+ }
+
+ public void recoverChild(ConfiguredObject object)
+ {
+ if(object instanceof AuthenticationProvider)
+ {
+ addAuthenticationProvider((AuthenticationProvider)object);
+ }
+ else if(object instanceof Port)
+ {
+ addPort((Port)object);
+ }
+ else if(object instanceof VirtualHost)
+ {
+ addVirtualHost((VirtualHost)object);
+ }
+ else if(object instanceof GroupProvider)
+ {
+ addGroupProvider((GroupProvider)object);
+ }
+ else if(object instanceof KeyStore)
+ {
+ addKeyStore((KeyStore)object);
+ }
+ else if(object instanceof TrustStore)
+ {
+ addTrustStore((TrustStore)object);
+ }
+ else if(object instanceof Plugin)
+ {
+ addPlugin(object);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Attempted to recover unexpected type of configured object: " + object.getClass().getName());
+ }
+ }
+
+ @Override
+ public RootMessageLogger getRootMessageLogger()
+ {
+ return _rootMessageLogger;
+ }
+
+ @Override
+ public SecurityManager getSecurityManager()
+ {
+ return _securityManager;
+ }
+
+ @Override
+ public LogRecorder getLogRecorder()
+ {
+ return _logRecorder;
+ }
+
+ @Override
+ public VirtualHost findVirtualHostByName(String name)
+ {
+ return _vhostAdapters.get(name);
+ }
+
+ @Override
+ public SubjectCreator getSubjectCreator(SocketAddress localAddress)
+ {
+ InetSocketAddress inetSocketAddress = (InetSocketAddress)localAddress;
+ AuthenticationProvider provider = _defaultAuthenticationProvider;
+ Collection<Port> ports = getPorts();
+ for (Port p : ports)
+ {
+ if (inetSocketAddress.getPort() == p.getPort())
+ {
+ provider = p.getAuthenticationProvider();
+ break;
+ }
+ }
+ return provider.getSubjectCreator();
+ }
+
+ @Override
+ public Collection<KeyStore> getKeyStores()
+ {
+ synchronized(_trustStores)
+ {
+ return Collections.unmodifiableCollection(_keyStores.values());
+ }
+ }
+
+ @Override
+ public Collection<TrustStore> getTrustStores()
+ {
+ synchronized(_trustStores)
+ {
+ return Collections.unmodifiableCollection(_trustStores.values());
+ }
+ }
+
+ @Override
+ public VirtualHostRegistry getVirtualHostRegistry()
+ {
+ return _virtualHostRegistry;
+ }
+
+ @Override
+ public KeyStore getDefaultKeyStore()
+ {
+ return _keyStores.get(_defaultKeyStoreId);
+ }
+
+ @Override
+ public TrustStore getDefaultTrustStore()
+ {
+ return _trustStores.get(_defaultTrustStoreId);
+ }
+
+ @Override
+ public TaskExecutor getTaskExecutor()
{
- return super.setAttribute(name, expected, desired); //TODO - Implement.
+ return super.getTaskExecutor();
}
}
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
index 5439f6a560..84f99e1f17 100644
--- 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
@@ -38,6 +38,7 @@ 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.configuration.updater.TaskExecutor;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.stats.StatisticsGatherer;
@@ -50,9 +51,9 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
new HashMap<AMQSessionModel, SessionAdapter>();
private final Statistics _statistics;
- public ConnectionAdapter(final AMQConnectionModel conn)
+ public ConnectionAdapter(final AMQConnectionModel conn, TaskExecutor taskExecutor)
{
- super(UUIDGenerator.generateRandomUUID());
+ super(UUIDGenerator.generateRandomUUID(), taskExecutor);
_connection = conn;
_statistics = new ConnectionStatisticsAdapter(conn);
}
@@ -74,7 +75,7 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
{
if(!_sessionAdapters.containsKey(session))
{
- _sessionAdapters.put(session, new SessionAdapter(session));
+ _sessionAdapters.put(session, new SessionAdapter(session, getTaskExecutor()));
}
}
return new ArrayList<Session>(_sessionAdapters.values());
@@ -199,52 +200,6 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
}
@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());
@@ -270,7 +225,8 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
}
}
- public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ @Override
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
if(childClass == Session.class)
{
@@ -310,4 +266,11 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection
return super.getStatistic(name);
}
}
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ // TODO: add state management
+ return false;
+ }
}
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
index 031d518670..e6d3fab2f8 100644
--- 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
@@ -45,7 +45,7 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer
queueAdapter.getName(),
subscription.getSessionModel().getConnectionModel().getRemoteAddressString(),
String.valueOf(subscription.getSessionModel().getChannelId()),
- subscription.getConsumerName()));
+ subscription.getConsumerName()), queueAdapter.getTaskExecutor());
_subscription = subscription;
_queue = queueAdapter;
_statistics = new ConsumerStatistics();
@@ -108,13 +108,6 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer
}
@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))
@@ -222,4 +215,11 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer
return null; // TODO - Implement
}
}
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ // TODO : Add state management
+ return false;
+ }
}
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
index df0f29fbc3..5d5f3f7378 100644
--- 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
@@ -33,16 +33,15 @@ 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.util.MapValueConverter;
import org.apache.qpid.server.virtualhost.VirtualHost;
final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apache.qpid.server.exchange.Exchange.BindingListener
@@ -57,7 +56,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
public ExchangeAdapter(final VirtualHostAdapter virtualHostAdapter,
final org.apache.qpid.server.exchange.Exchange exchange)
{
- super(exchange.getId());
+ super(exchange.getId(), virtualHostAdapter.getTaskExecutor());
_statistics = new ExchangeStatistics();
_vhost = virtualHostAdapter;
_exchange = exchange;
@@ -113,8 +112,8 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
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);
+ String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, "");
+ Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap());
attributes.remove(org.apache.qpid.server.model.Binding.NAME);
attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS);
@@ -257,7 +256,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
}
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
if(childClass == org.apache.qpid.server.model.Binding.class)
{
@@ -369,28 +368,20 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa
}
@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
+ protected boolean setState(State currentState, State desiredState)
{
if (desiredState == State.DELETED)
{
delete();
- return State.DELETED;
+ return true;
}
- return super.setDesiredState(currentState, desiredState);
+ return false;
}
private class ExchangeStatistics implements Statistics
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
new file mode 100644
index 0000000000..0fa834bc28
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java
@@ -0,0 +1,550 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Group;
+import org.apache.qpid.server.model.GroupMember;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+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.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.group.GroupManager;
+import org.apache.qpid.server.security.SecurityManager;
+
+public class GroupProviderAdapter extends AbstractAdapter implements
+ GroupProvider
+{
+ private final GroupManager _groupManager;
+ private final Broker _broker;
+ public GroupProviderAdapter(UUID id, GroupManager groupManager, Broker broker)
+ {
+ super(id, broker.getTaskExecutor());
+
+ if (groupManager == null)
+ {
+ throw new IllegalArgumentException("GroupManager must not be null");
+ }
+ _groupManager = groupManager;
+ _broker = broker;
+ addParent(Broker.class, broker);
+ }
+
+ @Override
+ public String getName()
+ {
+ return _groupManager.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 GroupProvider.AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ if (TYPE.equals(name))
+ {
+ return getName();
+ }
+ 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> C addChild(Class<C> childClass,
+ Map<String, Object> attributes, ConfiguredObject... otherParents)
+ {
+ if (childClass == Group.class)
+ {
+ String groupName = (String) attributes.get(Group.NAME);
+
+ if (getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName))
+ {
+ _groupManager.createGroup(groupName);
+ return (C) new GroupAdapter(groupName, getTaskExecutor());
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission" +
+ " to create new group");
+ }
+ }
+
+ throw new IllegalArgumentException(
+ "This group provider does not support creating children of type: "
+ + childClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz)
+ {
+ if (clazz == Group.class)
+ {
+ Set<Principal> groups = _groupManager.getGroupPrincipals();
+ Collection<Group> principals = new ArrayList<Group>(groups.size());
+ for (Principal group : groups)
+ {
+ principals.add(new GroupAdapter(group.getName(), getTaskExecutor()));
+ }
+ return (Collection<C>) Collections
+ .unmodifiableCollection(principals);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private SecurityManager getSecurityManager()
+ {
+ return _broker.getSecurityManager();
+ }
+
+ private class GroupAdapter extends AbstractAdapter implements Group
+ {
+ private final String _group;
+
+ public GroupAdapter(String group, TaskExecutor taskExecutor)
+ {
+ super(UUIDGenerator.generateGroupUUID(GroupProviderAdapter.this.getName(), group), taskExecutor);
+ _group = group;
+
+ }
+
+ @Override
+ public String getName()
+ {
+ return _group;
+ }
+
+ @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)
+ {
+ if (clazz == GroupMember.class)
+ {
+ Set<Principal> usersInGroup = _groupManager
+ .getUserPrincipalsForGroup(_group);
+ Collection<GroupMember> members = new ArrayList<GroupMember>();
+ for (Principal principal : usersInGroup)
+ {
+ members.add(new GroupMemberAdapter(principal.getName(), getTaskExecutor()));
+ }
+ return (Collection<C>) Collections
+ .unmodifiableCollection(members);
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+ @Override
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass,
+ Map<String, Object> attributes,
+ ConfiguredObject... otherParents)
+ {
+ if (childClass == GroupMember.class)
+ {
+ String memberName = (String) attributes.get(GroupMember.NAME);
+
+ if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group))
+ {
+ _groupManager.addUserToGroup(memberName, _group);
+ return (C) new GroupMemberAdapter(memberName, getTaskExecutor());
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission" +
+ " to add new group member");
+ }
+ }
+
+ throw new IllegalArgumentException(
+ "This group provider does not support creating children of type: "
+ + childClass);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return Group.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
+ protected boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException, AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ if (getSecurityManager().authoriseGroupOperation(Operation.DELETE, _group))
+ {
+ _groupManager.removeGroup(_group);
+ return true;
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission to delete group");
+ }
+ }
+
+ return false;
+ }
+
+ private class GroupMemberAdapter extends AbstractAdapter implements
+ GroupMember
+ {
+ private String _memberName;
+
+ public GroupMemberAdapter(String memberName, TaskExecutor taskExecutor)
+ {
+ super(UUIDGenerator.generateGroupMemberUUID(GroupProviderAdapter.this.getName(), _group, memberName), taskExecutor);
+ _memberName = memberName;
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return GroupMember.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 String getName()
+ {
+ return _memberName;
+ }
+
+ @Override
+ public String setName(String currentName, String desiredName)
+ throws IllegalStateException, AccessControlException
+ {
+ return null;
+ }
+
+ @Override
+ public State getActualState()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isDurable()
+ {
+ return false;
+ }
+
+ @Override
+ public void setDurable(boolean durable)
+ throws IllegalStateException, AccessControlException,
+ IllegalArgumentException
+ {
+ }
+
+ @Override
+ public LifetimePolicy getLifetimePolicy()
+ {
+ return null;
+ }
+
+ @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 <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
+ protected boolean setState(State currentState, State desiredState)
+ throws IllegalStateTransitionException,
+ AccessControlException
+ {
+ if (desiredState == State.DELETED)
+ {
+ if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group))
+ {
+ _groupManager.removeUserFromGroup(_memberName, _group);
+ return true;
+ }
+ else
+ {
+ throw new AccessControlException("Do not have permission to remove group member");
+ }
+ }
+ return false;
+ }
+
+ }
+ }
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if (desiredState == State.ACTIVE)
+ {
+ return true;
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ return true;
+ }
+ // TODO: DELETE state is ignored for now
+ // in case if we need to delete group provider, then we need AuthenticationProvider to be a change listener of it
+ // in order to remove deleted group provider from its group provider list
+ return false;
+ }
+
+ public Set<Principal> getGroupPrincipalsForUser(String username)
+ {
+ return _groupManager.getGroupPrincipalsForUser(username);
+ }
+}
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
deleted file mode 100644
index 823d27160b..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java
+++ /dev/null
@@ -1,273 +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.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-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
index b504c9fa60..113d895e62 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslRestTest.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
@@ -18,25 +18,31 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.server.model.adapter;
-import java.util.List;
+import java.util.Collection;
import java.util.Map;
+import java.util.UUID;
-public class SaslRestTest extends QpidRestTestCase
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.KeyStore;
+
+public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore
{
- public void testGet() throws Exception
- {
- Map<String, Object> saslData = getJsonAsMap("/rest/sasl");
- assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
- @SuppressWarnings("unchecked")
- List<String> mechanisms = (List<String>) saslData.get("mechanisms");
- String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
- for (String mechanism : expectedMechanisms)
+ public KeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, broker, attributes);
+ if (attributes.get(CERTIFICATE_ALIAS) != null)
{
- assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+ changeAttribute(CERTIFICATE_ALIAS, null, attributes.get(CERTIFICATE_ALIAS));
}
}
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
}
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
index 7653fcc9b9..c4a531c923 100644
--- 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
@@ -21,7 +21,16 @@
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.List;
import java.util.Map;
+import java.util.UUID;
+
+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.Connection;
import org.apache.qpid.server.model.LifetimePolicy;
@@ -30,119 +39,82 @@ 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;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
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>();
+ private final Broker _broker;
+ private AuthenticationProvider _authenticationProvider;
- 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;
- }
- }
+ /*
+ * TODO register PortAceptor as a listener. For supporting multiple
+ * protocols on the same port we need to introduce a special entity like
+ * PortAceptor which will be responsible for port binding/unbinding
+ */
+ public PortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaults, TaskExecutor taskExecutor)
+ {
+ super(id, defaults, attributes, taskExecutor);
+ _broker = broker;
- _protocols = Collections.unmodifiableCollection(protocols);
+ addParent(Broker.class, broker);
}
@Override
public String getBindingAddress()
{
- return _address.getHostName();
+ return (String)getAttribute(BINDING_ADDRESS);
}
@Override
public int getPort()
{
- return _address.getPort();
+ return (Integer)getAttribute(PORT);
}
+ @SuppressWarnings("unchecked")
@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
+ return (Collection<Transport>)getAttribute(TRANSPORTS);
}
@Override
public void addTransport(Transport transport)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
public Transport removeTransport(Transport transport)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
+ @SuppressWarnings("unchecked")
@Override
public Collection<Protocol> getProtocols()
{
- return _protocols;
+ return (Collection<Protocol>)getAttribute(PROTOCOLS);
}
@Override
public void addProtocol(Protocol protocol)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
public Protocol removeProtocol(Protocol protocol)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
@@ -165,31 +137,36 @@ public class PortAdapter extends AbstractAdapter implements Port
@Override
public Collection<Connection> getConnections()
{
- return null; // TODO - Implement
+ return null;
}
@Override
public String getName()
{
- return getBindingAddress() + ":" + getPort(); // TODO - Implement
+ return (String)getAttribute(NAME);
}
@Override
public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
public State getActualState()
{
- return State.ACTIVE;
+ State state = (State)super.getAttribute(STATE);
+ if (state == null)
+ {
+ return State.ACTIVE;
+ }
+ return state;
}
@Override
public boolean isDurable()
{
- return false; // TODO - Implement
+ return false;
}
@Override
@@ -209,20 +186,20 @@ public class PortAdapter extends AbstractAdapter implements Port
public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
public long getTimeToLive()
{
- return 0; // TODO - Implement
+ return 0;
}
@Override
public long setTimeToLive(long expected, long desired)
throws IllegalStateException, AccessControlException, IllegalArgumentException
{
- throw new IllegalStateException(); // TODO - Implement
+ throw new IllegalStateException();
}
@Override
@@ -257,10 +234,6 @@ public class PortAdapter extends AbstractAdapter implements Port
{
return getId();
}
- else if(NAME.equals(name))
- {
- return getName();
- }
else if(STATE.equals(name))
{
return getActualState();
@@ -285,36 +258,54 @@ public class PortAdapter extends AbstractAdapter implements Port
{
}
- else if(BINDING_ADDRESS.equals(name))
- {
- return getBindingAddress();
- }
- else if(PORT.equals(name))
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+ @Override
+ public boolean setState(State currentState, State desiredState)
+ {
+ if (desiredState == State.DELETED)
{
- return getPort();
+ return true;
}
- else if(PROTOCOLS.equals(name))
+ else if (desiredState == State.ACTIVE)
{
- return getProtocols();
+ onActivate();
+ return true;
}
- else if(TRANSPORTS.equals(name))
+ else if (desiredState == State.STOPPED)
{
- return getTransports();
+ onStop();
+ return true;
}
+ return false;
+ }
- return super.getAttribute(name); //TODO - Implement
+ protected void onActivate()
+ {
+ // no-op: expected to be overridden by subclass
}
- @Override
- public Collection<String> getAttributeNames()
+ protected void onStop()
{
- return AVAILABLE_ATTRIBUTES;
+ // no-op: expected to be overridden by subclass
}
@Override
- public Object setAttribute(String name, Object expected, Object desired)
- throws IllegalStateException, AccessControlException, IllegalArgumentException
+ public AuthenticationProvider getAuthenticationProvider()
+ {
+ return _authenticationProvider;
+ }
+
+ public void setAuthenticationProvider(AuthenticationProvider authenticationProvider)
{
- return super.setAttribute(name, expected, desired); //TODO - Implement
+ _authenticationProvider = authenticationProvider;
}
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
new file mode 100644
index 0000000000..b7441b9f3b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
@@ -0,0 +1,222 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.model.adapter;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Protocol.ProtocolType;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.util.MapValueConverter;
+
+public class PortFactory
+{
+ public static final int DEFAULT_AMQP_SEND_BUFFER_SIZE = 262144;
+ public static final int DEFAULT_AMQP_RECEIVE_BUFFER_SIZE = 262144;
+ public static final boolean DEFAULT_AMQP_NEED_CLIENT_AUTH = false;
+ public static final boolean DEFAULT_AMQP_WANT_CLIENT_AUTH = false;
+ public static final boolean DEFAULT_AMQP_TCP_NO_DELAY = true;
+ public static final String DEFAULT_AMQP_BINDING = "*";
+ public static final Transport DEFAULT_TRANSPORT = Transport.TCP;
+
+ private final Collection<Protocol> _defaultProtocols;
+
+ public PortFactory()
+ {
+ Set<Protocol> defaultProtocols = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1,
+ Protocol.AMQP_0_10, Protocol.AMQP_1_0);
+ String excludedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES);
+ if (excludedProtocols != null)
+ {
+ String[] excludes = excludedProtocols.split(",");
+ for (String exclude : excludes)
+ {
+ Protocol protocol = Protocol.valueOf(exclude);
+ defaultProtocols.remove(protocol);
+ }
+ }
+ String includedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES);
+ if (includedProtocols != null)
+ {
+ String[] includes = includedProtocols.split(",");
+ for (String include : includes)
+ {
+ Protocol protocol = Protocol.valueOf(include);
+ defaultProtocols.add(protocol);
+ }
+ }
+ _defaultProtocols = Collections.unmodifiableCollection(defaultProtocols);
+ }
+
+ public Port createPort(UUID id, Broker broker, Map<String, Object> objectAttributes)
+ {
+ Map<String, Object> attributes = retrieveAttributes(objectAttributes);
+
+ final Port port;
+ Map<String, Object> defaults = new HashMap<String, Object>();
+ defaults.put(Port.TRANSPORTS, Collections.singleton(DEFAULT_TRANSPORT));
+ Object portValue = attributes.get(Port.PORT);
+ if (portValue == null)
+ {
+ throw new IllegalConfigurationException("Port attribute is not specified for port: " + attributes);
+ }
+ if (isAmqpProtocol(attributes))
+ {
+ Object binding = attributes.get(Port.BINDING_ADDRESS);
+ if (binding == null)
+ {
+ binding = DEFAULT_AMQP_BINDING;
+ defaults.put(Port.BINDING_ADDRESS, DEFAULT_AMQP_BINDING);
+ }
+ defaults.put(Port.NAME, binding + ":" + portValue);
+ defaults.put(Port.PROTOCOLS, _defaultProtocols);
+ defaults.put(Port.TCP_NO_DELAY, DEFAULT_AMQP_TCP_NO_DELAY);
+ defaults.put(Port.WANT_CLIENT_AUTH, DEFAULT_AMQP_WANT_CLIENT_AUTH);
+ defaults.put(Port.NEED_CLIENT_AUTH, DEFAULT_AMQP_NEED_CLIENT_AUTH);
+ defaults.put(Port.RECEIVE_BUFFER_SIZE, DEFAULT_AMQP_RECEIVE_BUFFER_SIZE);
+ defaults.put(Port.SEND_BUFFER_SIZE, DEFAULT_AMQP_SEND_BUFFER_SIZE);
+ port = new AmqpPortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor());
+ }
+ else
+ {
+ @SuppressWarnings("unchecked")
+ Collection<Protocol> protocols = (Collection<Protocol>)attributes.get(Port.PROTOCOLS);
+ if (protocols.size() > 1)
+ {
+ throw new IllegalConfigurationException("Only one protocol can be used on non AMQP port");
+ }
+ Protocol protocol = protocols.iterator().next();
+ defaults.put(Port.NAME, portValue + "-" + protocol.name());
+ port = new PortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor());
+ }
+ return port;
+ }
+
+ private Map<String, Object> retrieveAttributes(Map<String, Object> objectAttributes)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>(objectAttributes);
+
+ if (objectAttributes.containsKey(Port.PROTOCOLS))
+ {
+ final Set<Protocol> protocolSet = MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, objectAttributes, Protocol.class);
+ attributes.put(Port.PROTOCOLS, protocolSet);
+ }
+
+ if (objectAttributes.containsKey(Port.TRANSPORTS))
+ {
+ final Set<Transport> transportSet = MapValueConverter.getEnumSetAttribute(Port.TRANSPORTS, objectAttributes,
+ Transport.class);
+ attributes.put(Port.TRANSPORTS, transportSet);
+ }
+
+ if (objectAttributes.containsKey(Port.PORT))
+ {
+ Integer port = MapValueConverter.getIntegerAttribute(Port.PORT, objectAttributes);
+ attributes.put(Port.PORT, port);
+ }
+
+ if (objectAttributes.containsKey(Port.TCP_NO_DELAY))
+ {
+ boolean tcpNoDelay = MapValueConverter.getBooleanAttribute(Port.TCP_NO_DELAY, objectAttributes);
+ attributes.put(Port.TCP_NO_DELAY, tcpNoDelay);
+ }
+
+ if (objectAttributes.containsKey(Port.RECEIVE_BUFFER_SIZE))
+ {
+ int receiveBufferSize = MapValueConverter.getIntegerAttribute(Port.RECEIVE_BUFFER_SIZE, objectAttributes);
+ attributes.put(Port.RECEIVE_BUFFER_SIZE, receiveBufferSize);
+ }
+
+ if (objectAttributes.containsKey(Port.SEND_BUFFER_SIZE))
+ {
+ int sendBufferSize = MapValueConverter.getIntegerAttribute(Port.SEND_BUFFER_SIZE, objectAttributes);
+ attributes.put(Port.SEND_BUFFER_SIZE, sendBufferSize);
+ }
+
+ if (objectAttributes.containsKey(Port.NEED_CLIENT_AUTH))
+ {
+ boolean needClientAuth = MapValueConverter.getBooleanAttribute(Port.NEED_CLIENT_AUTH, objectAttributes);
+ attributes.put(Port.NEED_CLIENT_AUTH, needClientAuth);
+ }
+
+ if (objectAttributes.containsKey(Port.WANT_CLIENT_AUTH))
+ {
+ boolean wantClientAuth = MapValueConverter.getBooleanAttribute(Port.WANT_CLIENT_AUTH, objectAttributes);
+ attributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth);
+ }
+
+ if (objectAttributes.containsKey(Port.BINDING_ADDRESS))
+ {
+ String binding = MapValueConverter.getStringAttribute(Port.BINDING_ADDRESS, objectAttributes);
+ attributes.put(Port.BINDING_ADDRESS, binding);
+ }
+
+ if (objectAttributes.containsKey(Port.STATE))
+ {
+ State state = MapValueConverter.getEnumAttribute(State.class, Port.STATE, objectAttributes);
+ attributes.put(Port.STATE, state);
+ }
+ return attributes;
+ }
+
+ private boolean isAmqpProtocol(Map<String, Object> portAttributes)
+ {
+ @SuppressWarnings("unchecked")
+ Set<Protocol> protocols = (Set<Protocol>) portAttributes.get(Port.PROTOCOLS);
+ if (protocols == null || protocols.isEmpty())
+ {
+ // defaulting to AMQP if protocol is not specified
+ return true;
+ }
+
+ Set<ProtocolType> protocolTypes = new HashSet<ProtocolType>();
+ for (Protocol protocolObject : protocols)
+ {
+ protocolTypes.add(protocolObject.getProtocolType());
+ }
+
+ if (protocolTypes.size() > 1)
+ {
+ throw new IllegalConfigurationException("Found different protocol types '" + protocolTypes
+ + "' on port configuration: " + portAttributes);
+ }
+
+ return protocolTypes.contains(ProtocolType.AMQP);
+ }
+
+ public Collection<Protocol> getDefaultProtocols()
+ {
+ return _defaultProtocols;
+ }
+
+}
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
index 78f6d38d93..f3ddf32e5a 100644
--- 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
@@ -43,6 +43,7 @@ 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;
+import org.apache.qpid.server.util.MapValueConverter;
final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.SubscriptionRegistrationListener, AMQQueue.NotificationListener
{
@@ -50,15 +51,16 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
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.ALERT_REPEAT_GAP, AMQQueueFactory.X_QPID_MINIMUM_ALERT_REPEAT_GAP);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_AGE);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_SIZE);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_COUNT);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_BYTES, AMQQueueFactory.X_QPID_MAXIMUM_QUEUE_DEPTH);
- QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, "x-qpid-maximum-delivery-count");
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, AMQQueueFactory.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.QUEUE_FLOW_CONTROL_SIZE_BYTES, AMQQueueFactory.X_QPID_CAPACITY);
+ QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, AMQQueueFactory.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);
@@ -78,7 +80,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
public QueueAdapter(final VirtualHostAdapter virtualHostAdapter, final AMQQueue queue)
{
- super(queue.getId());
+ super(queue.getId(), virtualHostAdapter.getTaskExecutor());
_vhost = virtualHostAdapter;
addParent(org.apache.qpid.server.model.VirtualHost.class, virtualHostAdapter);
@@ -205,47 +207,47 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
}
@Override
- public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException
+ public boolean changeAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException
{
try
{
if(ALERT_REPEAT_GAP.equals(name))
{
_queue.setMinimumAlertRepeatGap((Long)desired);
- return desired;
+ return true;
}
else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name))
{
_queue.setMaximumMessageAge((Long)desired);
- return desired;
+ return true;
}
else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name))
{
_queue.setMaximumMessageSize((Long)desired);
- return desired;
+ return true;
}
else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name))
{
_queue.setMaximumQueueDepth((Long)desired);
- return desired;
+ return true;
}
else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name))
{
_queue.setMaximumMessageCount((Long)desired);
- return desired;
+ return true;
}
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;
+ return true;
}
else if(EXCLUSIVE.equals(name))
{
Boolean exclusiveFlag = (Boolean) desired;
_queue.setExclusive(exclusiveFlag);
- return desired;
+ return true;
}
else if(MESSAGE_GROUP_KEY.equals(name))
{
@@ -266,7 +268,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name))
{
_queue.setMaximumDeliveryCount((Integer)desired);
- return desired;
+ return true;
}
else if(NO_LOCAL.equals(name))
{
@@ -279,12 +281,12 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name))
{
_queue.setCapacity((Long)desired);
- return desired;
+ return true;
}
else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name))
{
_queue.setFlowResumeCapacity((Long)desired);
- return desired;
+ return true;
}
else if(QUEUE_FLOW_STOPPED.equals(name))
{
@@ -301,10 +303,10 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
else if (DESCRIPTION.equals(name))
{
_queue.setDescription((String) desired);
- return desired;
+ return true;
}
- return super.setAttribute(name, expected, desired);
+ return super.changeAttribute(name, expected, desired);
}
finally
{
@@ -495,8 +497,8 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
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);
+ String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, "");
+ Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap());
attributes.remove(org.apache.qpid.server.model.Binding.NAME);
attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS);
@@ -508,7 +510,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
if(childClass == org.apache.qpid.server.model.Binding.class)
{
@@ -712,15 +714,15 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs
}
@Override
- public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException,
+ protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException,
AccessControlException
{
if (desiredState == State.DELETED)
{
delete();
- return State.DELETED;
+ return true;
}
- return super.setDesiredState(currentState, desiredState);
+ return false;
}
}
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
index d802697d67..2fffdb32f8 100644
--- 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
@@ -34,6 +34,7 @@ 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.configuration.updater.TaskExecutor;
import org.apache.qpid.server.protocol.AMQSessionModel;
final class SessionAdapter extends AbstractAdapter implements Session
@@ -44,9 +45,9 @@ final class SessionAdapter extends AbstractAdapter implements Session
private AMQSessionModel _session;
private SessionStatistics _statistics;
- public SessionAdapter(final AMQSessionModel session)
+ public SessionAdapter(final AMQSessionModel session, TaskExecutor taskExecutor)
{
- super(UUIDGenerator.generateRandomUUID());
+ super(UUIDGenerator.generateRandomUUID(), taskExecutor);
_session = session;
_statistics = new SessionStatistics();
}
@@ -141,13 +142,6 @@ final class SessionAdapter extends AbstractAdapter implements Session
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;
@@ -237,4 +231,11 @@ final class SessionAdapter extends AbstractAdapter implements Session
return null; // TODO - Implement
}
}
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ // TODO : add state management
+ return false;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
new file mode 100644
index 0000000000..bdffe605ec
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.Collection;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.TrustStore;
+
+public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustStore
+{
+ public TrustStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
+ {
+ super(id, broker, attributes);
+ }
+
+ @Override
+ public Collection<String> getAttributeNames()
+ {
+ return AVAILABLE_ATTRIBUTES;
+ }
+
+}
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
index 35838e51d2..1d50be279f 100644
--- 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
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.model.adapter;
+import java.io.File;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.ArrayList;
@@ -31,17 +32,27 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.configuration.SystemConfiguration;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.XmlConfigurationUtilities.MyConfiguration;
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.Broker;
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.Protocol;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.QueueType;
import org.apache.qpid.server.model.State;
@@ -49,22 +60,38 @@ 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.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.plugin.ExchangeType;
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.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener,
+public final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener,
QueueRegistry.RegistryChangeListener,
IConnectionRegistry.RegistryChangeListener
{
- private final org.apache.qpid.server.virtualhost.VirtualHost _virtualHost;
+ @SuppressWarnings("serial")
+ public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{
+ put(NAME, String.class);
+ put(STORE_PATH, String.class);
+ put(STORE_TYPE, String.class);
+ put(CONFIG_PATH, String.class);
+ put(STATE, State.class);
+ }});
+
+ private org.apache.qpid.server.virtualhost.VirtualHost _virtualHost;
private final Map<AMQConnectionModel, ConnectionAdapter> _connectionAdapters =
new HashMap<AMQConnectionModel, ConnectionAdapter>();
@@ -74,37 +101,52 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
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 StatisticsAdapter _statistics;
+ private final Broker _broker;
private final List<VirtualHostAlias> _aliases = new ArrayList<VirtualHostAlias>();
+ private StatisticsGatherer _brokerStatisticsGatherer;
-
- VirtualHostAdapter(BrokerAdapter brokerAdapter,
- final org.apache.qpid.server.virtualhost.VirtualHost virtualHost)
+ public VirtualHostAdapter(UUID id, Map<String, Object> attributes, Broker broker, StatisticsGatherer brokerStatisticsGatherer, TaskExecutor taskExecutor)
{
- 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();
-
+ super(id, null, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor);
+ validateAttributes();
+ _broker = broker;
+ _brokerStatisticsGatherer = brokerStatisticsGatherer;
+ addParent(Broker.class, broker);
+ }
+ private void validateAttributes()
+ {
+ String name = getName();
+ if (name == null || "".equals(name.trim()))
+ {
+ throw new IllegalConfigurationException("Virtual host name must be specified");
+ }
- for(Port port :_broker.getPorts())
+ String configurationFile = (String) getAttribute(CONFIG_PATH);
+ String storePath = (String) getAttribute(STORE_PATH);
+ String storeType = (String) getAttribute(STORE_TYPE);
+ boolean invalidAttributes = false;
+ if (configurationFile == null)
+ {
+ if (storePath == null || storeType == null)
+ {
+ invalidAttributes = true;
+ }
+ }
+ else
+ {
+ if (storePath != null || storeType != null)
+ {
+ invalidAttributes = true;
+ }
+ }
+ if (invalidAttributes)
{
- _aliases.add(new VirtualHostAliasAdapter(this, port));
+ throw new IllegalConfigurationException("Please specify either the 'configPath' attribute or both 'storePath' and 'storeType' attributes");
}
}
-
private void populateExchanges()
{
Collection<org.apache.qpid.server.exchange.Exchange> actualExchanges =
@@ -126,37 +168,22 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
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)
+ if ( actualQueues != null )
{
- for(AMQConnectionModel conn : actualConnections)
+ synchronized(_queueAdapters)
{
- if(!_connectionAdapters.containsKey(conn))
+ for(AMQQueue queue : actualQueues)
{
- _connectionAdapters.put(conn, new ConnectionAdapter(conn));
+ if(!_queueAdapters.containsKey(queue))
+ {
+ _queueAdapters.put(queue, new QueueAdapter(this, queue));
+ }
}
}
}
-
}
+ @Override
public String getReplicationGroupName()
{
return null; //TODO
@@ -198,12 +225,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
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);
+ String name = MapValueConverter.getStringAttribute(Exchange.NAME, attributes, null);
+ State state = MapValueConverter.getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE);
+ boolean durable = MapValueConverter.getBooleanAttribute(Exchange.DURABLE, attributes, false);
+ LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT);
+ String type = MapValueConverter.getStringAttribute(Exchange.TYPE, attributes, null);
+ long ttl = MapValueConverter.getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l);
attributes.remove(Exchange.NAME);
attributes.remove(Exchange.STATE);
@@ -266,7 +293,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
if (attributes.containsKey(Queue.TYPE))
{
- String typeAttribute = getStringAttribute(Queue.TYPE, attributes, null);
+ String typeAttribute = MapValueConverter.getStringAttribute(Queue.TYPE, attributes, null);
QueueType queueType = null;
try
{
@@ -289,12 +316,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
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);
+ String name = MapValueConverter.getStringAttribute(Queue.NAME, attributes, null);
+ State state = MapValueConverter.getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE);
+ boolean durable = MapValueConverter.getBooleanAttribute(Queue.DURABLE, attributes, false);
+ LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT);
+ long ttl = MapValueConverter.getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l);
+ boolean exclusive= MapValueConverter.getBooleanAttribute(Queue.EXCLUSIVE, attributes, false);
attributes.remove(Queue.NAME);
attributes.remove(Queue.STATE);
@@ -328,11 +355,10 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
String owner = null;
if(exclusive)
{
- Set<Principal> principals =
- SecurityManager.getThreadSubject().getPrincipals();
- if(principals != null && !principals.isEmpty())
+ Principal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(SecurityManager.getThreadSubject());
+ if(authenticatedPrincipal != null)
{
- owner = principals.iterator().next().getName();
+ owner = authenticatedPrincipal.getName();
}
}
try
@@ -370,7 +396,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
public String getName()
{
- return _virtualHost.getName();
+ return (String)getAttribute(NAME);
}
public String setName(final String currentName, final String desiredName)
@@ -379,9 +405,36 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
throw new IllegalStateException();
}
+ @Override
public State getActualState()
{
- return getDesiredState();
+ if (_virtualHost == null)
+ {
+ State state = (State)super.getAttribute(STATE);
+ if (state == null)
+ {
+ return State.INITIALISING;
+ }
+ return state;
+ }
+ else
+ {
+ org.apache.qpid.server.virtualhost.State implementationState = _virtualHost.getState();
+ switch(implementationState)
+ {
+ case INITIALISING:
+ return State.INITIALISING;
+ case ACTIVE:
+ return State.ACTIVE;
+ case PASSIVE:
+ return State.QUIESCED;
+ case STOPPED:
+ return State.STOPPED;
+ default:
+ // unexpected state
+ return null;
+ }
+ }
}
public boolean isDurable()
@@ -448,7 +501,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
@Override
- public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
+ public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents)
{
if(childClass == Exchange.class)
{
@@ -548,7 +601,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
if(!_connectionAdapters.containsKey(connection))
{
- adapter = new ConnectionAdapter(connection);
+ adapter = new ConnectionAdapter(connection, getTaskExecutor());
_connectionAdapters.put(connection, adapter);
}
@@ -709,13 +762,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
return getId();
}
- else if(NAME.equals(name))
- {
- return getName();
- }
else if(STATE.equals(name))
{
- return State.ACTIVE;
+ return getActualState();
}
else if(DURABLE.equals(name))
{
@@ -737,10 +786,19 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
// TODO
}
- else if(SUPPORTED_EXCHANGE_TYPES.equals(name))
+ else if (_virtualHost != null)
+ {
+ return getAttributeFromVirtualHostImplementation(name);
+ }
+ return super.getAttribute(name);
+ }
+
+ private Object getAttributeFromVirtualHostImplementation(String name)
+ {
+ if(SUPPORTED_EXCHANGE_TYPES.equals(name))
{
List<String> types = new ArrayList<String>();
- for(ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes())
+ for(@SuppressWarnings("rawtypes") ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes())
{
types.add(type.getName().asString());
}
@@ -754,10 +812,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
return _virtualHost.getConfiguration().isDeadLetterQueueEnabled();
}
- else if(FEDERATION_TAG.equals(name))
- {
- return _virtualHost.getFederationTag();
- }
else if(HOUSEKEEPING_CHECK_PERIOD.equals(name))
{
return _virtualHost.getConfiguration().getHousekeepingCheckPeriod();
@@ -778,9 +832,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
{
return _virtualHost.getMessageStore().getStoreType();
}
- else if(STORE_CONFIGURATION.equals(name))
+ else if(STORE_PATH.equals(name))
{
- // TODO
+ return _virtualHost.getMessageStore().getStoreLocation();
}
else if(STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE.equals(name))
{
@@ -822,13 +876,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
@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;
@@ -889,4 +936,111 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E
}
}
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ if (desiredState == State.ACTIVE)
+ {
+ activate();
+ return true;
+ }
+ else if (desiredState == State.STOPPED)
+ {
+ if (_virtualHost != null)
+ {
+ try
+ {
+ _virtualHost.close();
+ }
+ finally
+ {
+ _broker.getVirtualHostRegistry().unregisterVirtualHost(_virtualHost);
+ }
+ }
+ return true;
+ }
+ else if (desiredState == State.DELETED)
+ {
+ //TODO: add ACL check to authorize the operation
+ if (_virtualHost != null && _virtualHost.getState() == org.apache.qpid.server.virtualhost.State.ACTIVE)
+ {
+ setDesiredState(currentState, State.STOPPED);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private void activate()
+ {
+ VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry();
+ String virtualHostName = getName();
+ try
+ {
+ VirtualHostConfiguration configuration = createVirtualHostConfiguration(virtualHostName);
+ _virtualHost = new VirtualHostImpl(_broker.getVirtualHostRegistry(), _brokerStatisticsGatherer, _broker.getSecurityManager(), configuration);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Failed to create virtual host " + virtualHostName, e);
+ }
+
+ virtualHostRegistry.registerVirtualHost(_virtualHost);
+
+ _statistics = new VirtualHostStatisticsAdapter(_virtualHost);
+ _virtualHost.getQueueRegistry().addRegistryChangeListener(this);
+ populateQueues();
+ _virtualHost.getExchangeRegistry().addRegistryChangeListener(this);
+ populateExchanges();
+ _virtualHost.getConnectionRegistry().addRegistryChangeListener(this);
+
+ synchronized(_aliases)
+ {
+ for(Port port :_broker.getPorts())
+ {
+ if (Protocol.hasAmqpProtocol(port.getProtocols()))
+ {
+ _aliases.add(new VirtualHostAliasAdapter(this, port));
+ }
+ }
+ }
+ }
+
+ private VirtualHostConfiguration createVirtualHostConfiguration(String virtualHostName) throws ConfigurationException
+ {
+ VirtualHostConfiguration configuration;
+ String configurationFile = (String)getAttribute(CONFIG_PATH);
+ if (configurationFile == null)
+ {
+ final MyConfiguration basicConfiguration = new MyConfiguration();
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("store.type", (String)getAttribute(STORE_TYPE));
+ config.addProperty("store.environment-path", (String)getAttribute(STORE_PATH));
+ basicConfiguration.addConfiguration(config);
+
+ CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
+ compositeConfiguration.addConfiguration(new SystemConfiguration());
+ compositeConfiguration.addConfiguration(basicConfiguration);
+ configuration = new VirtualHostConfiguration(virtualHostName, compositeConfiguration , _broker);
+ }
+ else
+ {
+ configuration = new VirtualHostConfiguration(virtualHostName, new File(configurationFile) , _broker);
+ }
+ return configuration;
+ }
+
+ @Override
+ public SecurityManager getSecurityManager()
+ {
+ return _virtualHost.getSecurityManager();
+ }
+
+ @Override
+ public MessageStore getMessageStore()
+ {
+ return _virtualHost.getMessageStore();
+ }
+
}
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
index 367d1ff518..91b705b004 100644
--- 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
@@ -43,7 +43,7 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual
public VirtualHostAliasAdapter(VirtualHostAdapter virtualHostAdapter, Port port)
{
- super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName()));
+ super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName()), virtualHostAdapter.getTaskExecutor());
_vhost = virtualHostAdapter;
_port = port;
}
@@ -140,4 +140,11 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual
{
throw new UnsupportedOperationException();
}
+
+ @Override
+ protected boolean setState(State currentState, State desiredState)
+ {
+ // TODO: state is not supported at the moment
+ return false;
+ }
}
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 a68ac5439c..917215a42f 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
@@ -218,55 +218,71 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
final boolean isRedelivered = entry.isRedelivered();
- final AMQBody returnBlock = new AMQBody()
- {
-
- private AMQBody _underlyingBody;
-
- public AMQBody createAMQBody()
- {
- return _methodRegistry.createBasicDeliverBody(consumerTag,
- deliveryTag,
- isRedelivered,
- exchangeName,
- routingKey);
-
-
+ final AMQBody returnBlock = new EncodedDeliveryBody(deliveryTag, routingKey, exchangeName, consumerTag, isRedelivered);
+ return returnBlock;
+ }
+ private class EncodedDeliveryBody implements AMQBody
+ {
+ private final long _deliveryTag;
+ private final AMQShortString _routingKey;
+ private final AMQShortString _exchangeName;
+ private final AMQShortString _consumerTag;
+ private final boolean _isRedelivered;
+ private AMQBody _underlyingBody;
+
+ private EncodedDeliveryBody(long deliveryTag, AMQShortString routingKey, AMQShortString exchangeName, AMQShortString consumerTag, boolean isRedelivered)
+ {
+ _deliveryTag = deliveryTag;
+ _routingKey = routingKey;
+ _exchangeName = exchangeName;
+ _consumerTag = consumerTag;
+ _isRedelivered = isRedelivered;
+ }
+ public AMQBody createAMQBody()
+ {
+ return _methodRegistry.createBasicDeliverBody(_consumerTag,
+ _deliveryTag,
+ _isRedelivered,
+ _exchangeName,
+ _routingKey);
+ }
- }
+ public byte getFrameType()
+ {
+ return AMQMethodBody.TYPE;
+ }
- public byte getFrameType()
+ public int getSize()
+ {
+ if(_underlyingBody == null)
{
- return AMQMethodBody.TYPE;
+ _underlyingBody = createAMQBody();
}
+ return _underlyingBody.getSize();
+ }
- public int getSize()
+ public void writePayload(DataOutput buffer) throws IOException
+ {
+ if(_underlyingBody == null)
{
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- return _underlyingBody.getSize();
+ _underlyingBody = createAMQBody();
}
+ _underlyingBody.writePayload(buffer);
+ }
- public void writePayload(DataOutput buffer) throws IOException
- {
- if(_underlyingBody == null)
- {
- _underlyingBody = createAMQBody();
- }
- _underlyingBody.writePayload(buffer);
- }
+ public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
+ throws AMQException
+ {
+ throw new AMQException("This block should never be dispatched!");
+ }
- public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession)
- throws AMQException
- {
- throw new AMQException("This block should never be dispatched!");
- }
- };
- return returnBlock;
+ @Override
+ public String toString()
+ {
+ return "[" + getClass().getSimpleName() + " underlyingBody: " + String.valueOf(_underlyingBody) + "]";
+ }
}
private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize)
@@ -368,7 +384,6 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
_methodBody = methodBody;
_headerBody = headerBody;
_contentBody = contentBody;
-
}
public long getSize()
@@ -380,6 +395,19 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
{
AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody);
}
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("[").append(getClass().getSimpleName())
+ .append(" methodBody=").append(_methodBody)
+ .append(", headerBody=").append(_headerBody)
+ .append(", contentBody=").append(_contentBody)
+ .append(", channel=").append(_channel).append("]");
+ return builder.toString();
+ }
+
}
public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock
@@ -408,6 +436,17 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter
{
AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody);
}
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getClass().getSimpleName())
+ .append("methodBody=").append(_methodBody)
+ .append(", headerBody=").append(_headerBody)
+ .append(", channel=").append(_channel).append("]");
+ return builder.toString();
+ }
}
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java
new file mode 100644
index 0000000000..7708b90efc
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.plugin;
+
+import java.util.Map;
+
+import org.apache.qpid.server.security.AccessControl;
+
+public interface AccessControlFactory
+{
+ AccessControl createInstance(Map<String, Object> attributes);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
new file mode 100644
index 0000000000..95e6b4feb0
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.plugin;
+
+import java.util.Map;
+
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+
+
+public interface AuthenticationManagerFactory
+{
+ public static final String ATTRIBUTE_TYPE = "authenticationProviderType";
+
+ AuthenticationManager createInstance(Map<String, Object> attributes);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java
index a01e41f039..40ef6ad6a2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java
@@ -18,19 +18,18 @@
* under the License.
*
*/
-package org.apache.qpid.server.exchange;
+package org.apache.qpid.server.plugin;
import java.util.UUID;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.virtualhost.VirtualHost;
-
public interface ExchangeType<T extends Exchange>
{
public AMQShortString getName();
- public Class<T> getExchangeClass();
public T newInstance(UUID id, VirtualHost host, AMQShortString name,
boolean durable, int ticket, boolean autoDelete) throws AMQException;
public AMQShortString getDefaultExchangeName();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java
new file mode 100644
index 0000000000..5d80ca24fd
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.plugin;
+
+import java.util.Map;
+
+import org.apache.qpid.server.security.group.GroupManager;
+
+public interface GroupManagerFactory
+{
+ GroupManager createInstance(Map<String, Object> attributes);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java
new file mode 100644
index 0000000000..af24f62e28
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.plugin;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Plugin;
+
+public interface PluginFactory
+{
+ static final String PLUGIN_TYPE = "pluginType";
+
+ Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java
new file mode 100644
index 0000000000..a0e0346ce0
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java
@@ -0,0 +1,72 @@
+/*
+ * 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.plugin;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Simple facade over a {@link ServiceLoader} to instantiate all configured implementations of an interface.
+ */
+public class QpidServiceLoader<C>
+{
+ private static final Logger _logger = Logger.getLogger(QpidServiceLoader.class);
+
+ public Iterable<C> instancesOf(Class<C> clazz)
+ {
+ return instancesOf(clazz, false);
+ }
+
+ /**
+ * @throws RuntimeException if at least one implementation is not found.
+ */
+ public Iterable<C> atLeastOneInstanceOf(Class<C> clazz)
+ {
+ return instancesOf(clazz, true);
+ }
+
+ private Iterable<C> instancesOf(Class<C> clazz, boolean atLeastOne)
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ Iterator<C> serviceLoaderIterator = ServiceLoader.load(clazz, classLoader).iterator();
+
+ // create a new list so we can log the count
+ List<C> serviceImplementations = new ArrayList<C>();
+ while(serviceLoaderIterator.hasNext())
+ {
+ serviceImplementations.add(serviceLoaderIterator.next());
+ }
+
+ if(atLeastOne && serviceImplementations.isEmpty())
+ {
+ throw new RuntimeException("At least one implementation of " + clazz + " expected");
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Found " + serviceImplementations.size() + " implementations of " + clazz);
+ }
+
+ return serviceImplementations;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java
deleted file mode 100644
index 12e1eee9ca..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java
+++ /dev/null
@@ -1,51 +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.plugins;
-
-import org.apache.log4j.Logger;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-public class Activator implements BundleActivator
-{
- private static final Logger _logger = Logger.getLogger(Activator.class);
-
- private BundleContext _context = null;
-
- public void start(BundleContext ctx) throws Exception
- {
- _context = ctx;
- _logger.info("Registering bundle: " + _context.getBundle().getSymbolicName());
- ctx.registerService(ServerConfiguration.class.getName(), ApplicationRegistry.getInstance().getConfiguration(), null);
- }
-
- public void stop(BundleContext ctx) throws Exception
- {
- _logger.info("Stopping bundle: " + _context.getBundle().getSymbolicName());
- _context = null;
- }
-
- public BundleContext getContext()
- {
- return _context;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java
deleted file mode 100644
index d2bb3e037c..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java
+++ /dev/null
@@ -1,91 +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.plugins;
-
-import org.osgi.framework.Version;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Utility class to convert a map of package name to version numbers into the string
- * with the format expected of a OSGi system package declaration:
- *
- * <code>
- * org.xyz; version=1.0.0, org.xyz.xyz; version=1.0.0,...
- * </code>
- *
- * Additionally, if the caller has provided a qpidPackageReleaseNumber and the package
- * begins org.apache.qpid, this release number will be used, in preference to the one
- * found in the Map.
- *
- * @see org.osgi.framework.Constants#FRAMEWORK_SYSTEMPACKAGES
- *
- */
-public class OsgiSystemPackageUtil
-{
- private static final String APACHE_QPID_PKG_PREFIX = "org.apache.qpid";
-
- private final Map<String, String> _packageNameVersionMap;
- private final Version _qpidPackageReleaseNumber;
-
- public OsgiSystemPackageUtil(final Version qpidPackageReleaseNumber, final Map<String, String> packageNameVersionMap)
- {
- _qpidPackageReleaseNumber = qpidPackageReleaseNumber;
- _packageNameVersionMap = packageNameVersionMap;
- }
-
- public String getFormattedSystemPackageString()
- {
- if (_packageNameVersionMap == null || _packageNameVersionMap.size() == 0)
- {
- return null;
- }
-
- final StringBuilder packages = new StringBuilder();
-
- for(Iterator<String> itr = _packageNameVersionMap.keySet().iterator(); itr.hasNext();)
- {
- final String packageName = itr.next();
- final String packageVersion;
-
- if (_qpidPackageReleaseNumber != null && packageName.startsWith(APACHE_QPID_PKG_PREFIX))
- {
- packageVersion = _qpidPackageReleaseNumber.toString();
- }
- else
- {
- packageVersion = _packageNameVersionMap.get(packageName);
- }
-
- packages.append(packageName);
- packages.append("; ");
- packages.append("version=");
- packages.append(packageVersion);
-
- if (itr.hasNext())
- {
- packages.append(", ");
- }
- }
-
- return packages.toString();
- }
-
-}
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
deleted file mode 100644
index 6479546355..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties
+++ /dev/null
@@ -1,135 +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.
-#
-
-#
-# OSGi framework system package list
-#
-# PluginManager uses these properties to construct the FRAMEWORK_SYSTEMPACKAGES list
-#
-
-# Format is:
-# <package>=<version>
-# and PluginManager will convert this into:
-# <package>; version=<version>
-# e.g. org.osgi.framework; version=1.3.0
-
-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
-
-org.osgi.framework=1.3.0
-org.osgi.service.packageadmin=1.2.0
-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.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=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.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
-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/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
deleted file mode 100644
index 6dcf688f2a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
+++ /dev/null
@@ -1,32 +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.plugins;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-
-public interface Plugin
-{
-
- /**
- * Provide Configuration to this plugin
- */
- public void configure(ConfigurationPlugin config) throws ConfigurationException;
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java
deleted file mode 100644
index 7ea2b95b89..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java
+++ /dev/null
@@ -1,32 +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.plugins;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-
-public interface PluginFactory<P extends Plugin>
-{
- public Class<P> getPluginClass();
-
- public String getPluginName();
-
- public P newInstance(ConfigurationPlugin config) throws ConfigurationException;
-}
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
deleted file mode 100644
index 74abbccd2b..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
+++ /dev/null
@@ -1,403 +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.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.apache.qpid.common.Closeable;
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.server.configuration.TopicConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration.SlowConsumerDetectionConfigurationFactory;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionPolicyConfiguration.SlowConsumerDetectionPolicyConfigurationFactory;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration.SlowConsumerDetectionQueueConfigurationFactory;
-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 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;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_DIR_PROPERY;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_START_VALUE;
-import static org.apache.felix.main.AutoProcessor.process;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT;
-import static org.osgi.framework.Constants.FRAMEWORK_SYSTEMPACKAGES;
-
-/**
- * Provides access to pluggable elements, such as exchanges
- */
-@SuppressWarnings("unchecked")
-public class PluginManager implements Closeable
-{
- private static final Logger _logger = Logger.getLogger(PluginManager.class);
-
- private static final int FELIX_STOP_TIMEOUT = 30000;
-
- private Framework _felix;
-
- private ServiceTracker _exchangeTracker = null;
- private ServiceTracker _securityTracker = null;
- private ServiceTracker _configTracker = null;
- private ServiceTracker _virtualHostTracker = null;
- private ServiceTracker _policyTracker = null;
- private ServiceTracker _authenticationManagerTracker = null;
-
- private Activator _activator;
-
- private final List<ServiceTracker> _trackers = new ArrayList<ServiceTracker>();
- private Map<String, SecurityPluginFactory> _securityPlugins = new HashMap<String, SecurityPluginFactory>();
- private Map<List<String>, ConfigurationPluginFactory> _configPlugins = new IdentityHashMap<List<String>, ConfigurationPluginFactory>();
- private Map<String, VirtualHostPluginFactory> _vhostPlugins = new HashMap<String, VirtualHostPluginFactory>();
- private Map<String, SlowConsumerPolicyPluginFactory> _policyPlugins = new HashMap<String, SlowConsumerPolicyPluginFactory>();
- private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> _authenticationManagerPlugins = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>();
-
- /** 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
- {
- final String filename = System.getProperty(FILE_PROPERTY);
- final InputStream is = FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME,
- PluginManager.class.getClassLoader());
-
- try
- {
- Version qpidReleaseVersion;
- try
- {
- qpidReleaseVersion = Version.parseVersion(QpidProperties.getReleaseVersion());
- }
- catch (IllegalArgumentException iae)
- {
- 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)
- {
- _logger.error("Error reading OSGI system package list", e);
- throw new ExceptionInInitializerError(e);
- }
- }
-
-
- public PluginManager(String pluginPath, String cachePath, BundleContext bundleContext) throws Exception
- {
- // Store all non-OSGi plugins
- // A little gross that we have to add them here, but not all the plugins are OSGIfied
- for (SecurityPluginFactory<?> pluginFactory : Arrays.asList(LegacyAccess.FACTORY))
- {
- _securityPlugins.put(pluginFactory.getPluginName(), pluginFactory);
- }
- for (ConfigurationPluginFactory configFactory : Arrays.asList(
- TopicConfiguration.FACTORY,
- SecurityManager.SecurityConfiguration.FACTORY,
- LegacyAccess.LegacyAccessConfiguration.FACTORY,
- new SlowConsumerDetectionConfigurationFactory(),
- new SlowConsumerDetectionPolicyConfigurationFactory(),
- new SlowConsumerDetectionQueueConfigurationFactory(),
- PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY,
- AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY,
- KerberosAuthenticationManager.KerberosAuthenticationManagerConfiguration.FACTORY,
- SimpleLDAPAuthenticationManager.SimpleLDAPAuthenticationManagerConfiguration.FACTORY,
- ExternalAuthenticationManager.ExternalAuthenticationManagerConfiguration.FACTORY
- ))
- {
- _configPlugins.put(configFactory.getParentPaths(), configFactory);
- }
- for (SlowConsumerPolicyPluginFactory pluginFactory : Arrays.asList(
- new TopicDeletePolicy.TopicDeletePolicyFactory()))
- {
- _policyPlugins.put(pluginFactory.getPluginName(), pluginFactory);
- }
- for (VirtualHostPluginFactory pluginFactory : Arrays.asList(
- new SlowConsumerDetection.SlowConsumerFactory()))
- {
- _vhostPlugins.put(pluginFactory.getClass().getName(), pluginFactory);
- }
-
- for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList(
- PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY,
- KerberosAuthenticationManager.FACTORY, SimpleLDAPAuthenticationManager.FACTORY,
- ExternalAuthenticationManager.FACTORY))
- {
- _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory);
- }
-
- if(bundleContext == null)
- {
- // Check the plugin directory path is set and exist
- if (pluginPath == null)
- {
- _logger.info("No plugin path specified, no plugins will be loaded.");
- return;
- }
- File pluginDir = new File(pluginPath);
- if (!pluginDir.exists())
- {
- _logger.warn("Plugin dir : " + pluginDir + " does not exist.");
- return;
- }
-
- // Add the bundle provided service interface package and the core OSGi
- // packages to be exported from the class path via the system bundle.
-
- // Setup OSGi configuration property map
- final StringMap configMap = new StringMap(false);
- configMap.put(FRAMEWORK_SYSTEMPACKAGES, OSGI_SYSTEM_PACKAGES);
-
- // No automatic shutdown hook
- configMap.put("felix.shutdown.hook", "false");
-
- // Add system activator
- List<BundleActivator> activators = new ArrayList<BundleActivator>();
- _activator = new Activator();
- activators.add(_activator);
- configMap.put(SYSTEMBUNDLE_ACTIVATORS_PROP, activators);
-
- if (cachePath != null)
- {
- File cacheDir = new File(cachePath);
- if (!cacheDir.exists() && cacheDir.canWrite())
- {
- _logger.info("Creating plugin cache directory: " + cachePath);
- cacheDir.mkdir();
- }
-
- // Set plugin cache directory and empty it
- _logger.info("Cache bundles in directory " + cachePath);
- configMap.put(FRAMEWORK_STORAGE, cachePath);
- }
- configMap.put(FRAMEWORK_STORAGE_CLEAN, FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
-
- // Set directory with plugins to auto-deploy
- _logger.info("Auto deploying bundles from directory " + pluginPath);
- configMap.put(AUTO_DEPLOY_DIR_PROPERY, pluginPath);
- configMap.put(AUTO_DEPLOY_ACTION_PROPERY, AUTO_DEPLOY_INSTALL_VALUE + "," + AUTO_DEPLOY_START_VALUE);
-
- // Start plugin manager
- _felix = new Felix(configMap);
- try
- {
- _logger.info("Starting plugin manager framework");
- _felix.init();
- process(configMap, _felix.getBundleContext());
- _felix.start();
- _logger.info("Started plugin manager framework");
- }
- catch (BundleException e)
- {
- throw new ConfigurationException("Could not start plugin manager: " + e.getMessage(), e);
- }
-
- bundleContext = _activator.getContext();
- }
- else
- {
- _logger.info("Using the specified external BundleContext");
- }
-
- _exchangeTracker = new ServiceTracker(bundleContext, ExchangeType.class.getName(), null);
- _exchangeTracker.open();
- _trackers.add(_exchangeTracker);
-
- _securityTracker = new ServiceTracker(bundleContext, SecurityPluginFactory.class.getName(), null);
- _securityTracker.open();
- _trackers.add(_securityTracker);
-
- _configTracker = new ServiceTracker(bundleContext, ConfigurationPluginFactory.class.getName(), null);
- _configTracker.open();
- _trackers.add(_configTracker);
-
- _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);
-
- _authenticationManagerTracker = new ServiceTracker(bundleContext, AuthenticationManagerPluginFactory.class.getName(), null);
- _authenticationManagerTracker.open();
- _trackers.add(_authenticationManagerTracker);
-
- _logger.info("Opened service trackers");
- }
-
- 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())
- {
- if (service instanceof PluginFactory<?>)
- {
- services.put(((PluginFactory<?>) service).getPluginName(), (T) service);
- }
- else
- {
- services.put(service.getClass().getName(), (T) service);
- }
- }
- }
-
- return services;
- }
-
- 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())
- {
- ConfigurationPluginFactory factory = (ConfigurationPluginFactory) service;
- 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);
- }
-
- public Map<String, ExchangeType<?>> getExchanges()
- {
- return getServices(_exchangeTracker);
- }
-
- public Map<String, SecurityPluginFactory> getSecurityPlugins()
- {
- return getServices(_securityTracker, _securityPlugins);
- }
-
- public Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> getAuthenticationManagerPlugins()
- {
- return getServices(_authenticationManagerTracker, _authenticationManagerPlugins);
- }
-
- public void close()
- {
- try
- {
- // Close all bundle trackers
- for(ServiceTracker tracker : _trackers)
- {
- tracker.close();
- }
- }
- finally
- {
- if (_felix != null)
- {
- _logger.info("Stopping plugin manager framework");
- try
- {
- // FIXME should be stopAndWait() but hangs VM, need upgrade in felix
- _felix.stop();
- }
- catch (BundleException e)
- {
- // Ignore
- }
-
- try
- {
- _felix.waitForStop(FELIX_STOP_TIMEOUT);
- }
- catch (InterruptedException e)
- {
- // Ignore
- }
- _logger.info("Stopped plugin manager framework");
- }
- else
- {
- _logger.info("Plugin manager was started with an external BundleContext, " +
- "skipping remaining shutdown tasks");
- }
- }
- }
-}
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 1e649c3cb7..ee1ef2418a 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
@@ -29,11 +29,11 @@ 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.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -52,10 +52,7 @@ import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.protocol.ServerProtocolEngine;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ConnectionConfig;
-import org.apache.qpid.server.configuration.ConnectionConfigType;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.handler.ServerMethodDispatcherImpl;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
@@ -64,10 +61,11 @@ 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.model.Broker;
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.AuthenticatedPrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.stats.StatisticsCounter;
@@ -75,13 +73,12 @@ import org.apache.qpid.server.subscription.ClientDeliveryMethod;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.TransportException;
import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.util.BytesDataOutput;
-public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession, ConnectionConfig
+public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession
{
private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class);
@@ -115,7 +112,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
private volatile boolean _closed;
// maximum number of channels this session should have
- private long _maxNoOfChannels = ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount();
+ private long _maxNoOfChannels;
/* AMQP Version for this session */
private ProtocolVersion _protocolVersion = ProtocolVersion.getLatestSupportedVersion();
@@ -142,8 +139,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
private long _maxFrameSize;
private final AtomicBoolean _closing = new AtomicBoolean(false);
- private final UUID _qmfId;
- private final ConfigStore _configStore;
private long _createTime = System.currentTimeMillis();
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
@@ -156,23 +151,25 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
private boolean _blocking;
private final Lock _receivedLock;
+ private AtomicLong _lastWriteTime = new AtomicLong(System.currentTimeMillis());
+ private final Broker _broker;
- public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network, final long connectionId)
+
+ public AMQProtocolEngine(Broker broker, NetworkConnection network, final long connectionId)
{
+ _broker = broker;
+ _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT);
_receivedLock = new ReentrantLock();
- _stateManager = new AMQStateManager(virtualHostRegistry, this);
+ _stateManager = new AMQStateManager(broker, this);
_codecFactory = new AMQCodecFactory(true, this);
setNetworkConnection(network);
_connectionID = connectionId;
- _actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger());
+ _actor = new AMQPConnectionActor(this, _broker.getRootMessageLogger());
_logSubject = new ConnectionLogSubject(this);
- _configStore = virtualHostRegistry.getConfigStore();
- _qmfId = _configStore.createId();
-
_actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false));
initialiseStatistics();
@@ -309,9 +306,13 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
try
{
+ long startTime = 0;
+ String frameToString = null;
if (_logger.isDebugEnabled())
{
- _logger.debug("Frame Received: " + frame);
+ startTime = System.currentTimeMillis();
+ frameToString = frame.toString();
+ _logger.debug("RECV: " + frame);
}
// Check that this channel is not closing
@@ -346,6 +347,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
closeChannel(channelId);
throw e;
}
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Frame handled in " + (System.currentTimeMillis() - startTime) + " ms. Frame: " + frameToString);
+ }
}
finally
{
@@ -367,7 +373,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
// This sets the protocol version (and hence framing classes) for this session.
setProtocolVersion(pv);
- String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager(getLocalAddress()).getMechanisms();
+ String mechanisms = _broker.getSubjectCreator(getLocalAddress()).getMechanisms();
String locales = "en_US";
@@ -549,8 +555,17 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
final ByteBuffer buf = asByteBuffer(frame);
_writtenBytes += buf.remaining();
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("SEND: " + frame);
+ }
+
_sender.send(buf);
- _lastIoTime = System.currentTimeMillis();
+ final long time = System.currentTimeMillis();
+ _lastIoTime = time;
+ _lastWriteTime.set(time);
+
if(!_deferFlush)
{
_sender.flush();
@@ -749,7 +764,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
if (delay > 0)
{
_network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
+ _network.setMaxReadIdle(BrokerProperties.DEFAULT_HEART_BEAT_TIMEOUT_FACTOR * delay);
}
}
@@ -796,8 +811,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
closeAllChannels();
- getConfigStore().removeConfiguredObject(this);
-
for (Task task : _taskList)
{
task.doTask(this);
@@ -983,7 +996,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
_virtualHost.getConnectionRegistry().registerConnection(this);
- _configStore.addConfiguredObject(this);
}
public void addSessionCloseTask(Task task)
@@ -1017,7 +1029,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
public Principal getAuthorizedPrincipal()
{
- return _authorizedSubject == null ? null : _authorizedSubject.getPrincipals().iterator().next();
+ return _authorizedSubject == null ? null : AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(_authorizedSubject);
}
public SocketAddress getRemoteAddress()
@@ -1070,12 +1082,12 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
public void readerIdle()
{
- // Nothing
+ // TODO - enforce disconnect on lack of inbound data
}
public synchronized void writerIdle()
{
- _sender.send(asByteBuffer(HeartbeatBody.FRAME));
+ writeFrame(HeartbeatBody.FRAME);
}
public void exception(Throwable throwable)
@@ -1185,32 +1197,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
return null;
}
- public ConfigStore getConfigStore()
- {
- return _configStore;
- }
-
- public ConnectionConfigType getConfigType()
- {
- return ConnectionConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
public boolean isDurable()
{
return false;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
public long getConnectionId()
{
return getSessionID();
@@ -1494,4 +1485,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi
{
return _receivedLock;
}
+
+ @Override
+ public long getLastReadTime()
+ {
+ return _lastReceivedTime;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime.get();
+ }
}
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 a8f62b0fa2..9d9bbe807b 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
@@ -36,8 +36,7 @@ import org.apache.qpid.server.queue.SimpleAMQQueue;
*/
public interface AMQSessionModel extends Comparable<AMQSessionModel>
{
- /** Unique session ID across entire broker*/
- public UUID getQMFId();
+ public UUID getId();
public AMQConnectionModel getConnectionModel();
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 5c92aa95b6..d9e5e1c473 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
@@ -28,7 +28,7 @@ import java.util.Set;
import org.apache.log4j.Logger;
import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.transport.ConnectionDelegate;
import org.apache.qpid.transport.Sender;
@@ -42,24 +42,24 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
private Set<AmqpProtocolVersion> _supported;
private String _fqdn;
- private IApplicationRegistry _appRegistry;
+ private final Broker _broker;
private NetworkConnection _network;
private Sender<ByteBuffer> _sender;
private final AmqpProtocolVersion _defaultSupportedReply;
private volatile ServerProtocolEngine _delegate = new SelfDelegateProtocolEngine();
- public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry,
+ public MultiVersionProtocolEngine(final Broker broker,
final Set<AmqpProtocolVersion> supported,
final AmqpProtocolVersion defaultSupportedReply,
final long id,
final NetworkConnection network)
{
- this(appRegistry, supported, defaultSupportedReply, id);
+ this(broker, supported, defaultSupportedReply, id);
setNetworkConnection(network);
}
- public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry,
+ public MultiVersionProtocolEngine(final Broker broker,
final Set<AmqpProtocolVersion> supported,
final AmqpProtocolVersion defaultSupportedReply,
final long id)
@@ -71,7 +71,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
}
_id = id;
- _appRegistry = appRegistry;
+ _broker = broker;
_supported = supported;
_defaultSupportedReply = defaultSupportedReply;
}
@@ -217,6 +217,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
_sender = sender;
}
+ @Override
+ public long getLastReadTime()
+ {
+ return _delegate.getLastReadTime();
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _delegate.getLastWriteTime();
+ }
+
private static interface DelegateCreator
{
@@ -240,7 +252,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id);
+ return new AMQProtocolEngine(_broker, _network, _id);
}
};
@@ -260,7 +272,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id);
+ return new AMQProtocolEngine(_broker, _network, _id);
}
};
@@ -280,7 +292,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id);
+ return new AMQProtocolEngine(_broker, _network, _id);
}
};
@@ -301,13 +313,15 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- final ConnectionDelegate connDelegate =
- new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn, _appRegistry.getAuthenticationManager(getLocalAddress()));
+ final ConnectionDelegate connDelegate = new org.apache.qpid.server.transport.ServerConnectionDelegate(_broker,
+ _fqdn, _broker.getSubjectCreator(getLocalAddress()));
ServerConnection conn = new ServerConnection(_id);
- conn.setConnectionDelegate(connDelegate);
- return new ProtocolEngine_0_10( conn, _network, _appRegistry);
+ conn.setConnectionDelegate(connDelegate);
+ conn.setRemoteAddress(_network.getRemoteAddress());
+ conn.setLocalAddress(_network.getLocalAddress());
+ return new ProtocolEngine_0_10( conn, _network);
}
};
@@ -327,7 +341,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- return new ProtocolEngine_1_0_0(_appRegistry,_id);
+ return new ProtocolEngine_1_0_0(_network, _broker, _id);
}
};
@@ -347,7 +361,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public ServerProtocolEngine getProtocolEngine()
{
- return new ProtocolEngine_1_0_0_SASL(_network, _appRegistry, _id);
+ return new ProtocolEngine_1_0_0_SASL(_network, _broker, _id);
}
};
@@ -407,6 +421,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
}
+ @Override
+ public long getLastReadTime()
+ {
+ return 0;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return 0;
+ }
+
public long getConnectionId()
{
return _id;
@@ -547,7 +573,29 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
public void closed()
{
-
+ try
+ {
+ _delegate = new ClosedDelegateProtocolEngine();
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Connection from " + getRemoteAddress() + " was closed before any protocol version was established.");
+ }
+ }
+ catch(Exception e)
+ {
+ //ignore
+ }
+ finally
+ {
+ try
+ {
+ _network.close();
+ }
+ catch(Exception e)
+ {
+ //ignore
+ }
+ }
}
public void writerIdle()
@@ -564,5 +612,17 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine
{
}
+
+ @Override
+ public long getLastReadTime()
+ {
+ return 0;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return 0;
+ }
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
index 552b1c7054..9f078c8999 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
@@ -22,8 +22,7 @@ package org.apache.qpid.server.protocol;
import org.apache.qpid.protocol.ProtocolEngineFactory;
import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.model.Broker;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@@ -32,11 +31,12 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
{
private static final AtomicLong ID_GENERATOR = new AtomicLong(0);
- private final IApplicationRegistry _appRegistry;
+ private final Broker _broker;
private final Set<AmqpProtocolVersion> _supported;
private final AmqpProtocolVersion _defaultSupportedReply;
- public MultiVersionProtocolEngineFactory(final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply)
+ public MultiVersionProtocolEngineFactory(Broker broker,
+ final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply)
{
if(defaultSupportedReply != null && !supportedVersions.contains(defaultSupportedReply))
{
@@ -44,14 +44,14 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
+ ") to an unsupported protocol version initiation is itself not supported!");
}
- _appRegistry = ApplicationRegistry.getInstance();
+ _broker = broker;
_supported = supportedVersions;
_defaultSupportedReply = defaultSupportedReply;
}
public ServerProtocolEngine newProtocolEngine()
{
- return new MultiVersionProtocolEngine(_appRegistry, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement());
+ return new MultiVersionProtocolEngine(_broker, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement());
}
}
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 fd6e9300ec..d5f7fe486c 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
@@ -21,13 +21,7 @@
package org.apache.qpid.server.protocol;
import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.ConnectionConfig;
-import org.apache.qpid.server.configuration.ConnectionConfigType;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
-import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.Assembler;
@@ -37,9 +31,9 @@ import org.apache.qpid.transport.network.NetworkConnection;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
-import java.util.UUID;
-public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine, ConnectionConfig
+
+public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine
{
public static final int MAX_FRAME_SIZE = 64 * 1024 - 1;
@@ -47,20 +41,17 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
private long _readBytes;
private long _writtenBytes;
private ServerConnection _connection;
- private final UUID _qmfId;
- private final IApplicationRegistry _appRegistry;
+
private long _createTime = System.currentTimeMillis();
+ private long _lastReadTime;
+ private long _lastWriteTime;
public ProtocolEngine_0_10(ServerConnection conn,
- NetworkConnection network,
- final IApplicationRegistry appRegistry)
+ NetworkConnection network)
{
super(new Assembler(conn));
_connection = conn;
- _connection.setConnectionConfig(this);
- _qmfId = appRegistry.getConfigStore().createId();
- _appRegistry = appRegistry;
if(network != null)
{
@@ -68,14 +59,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
}
- _connection.onOpen(new Runnable()
- {
- public void run()
- {
- getConfigStore().addConfiguredObject(ProtocolEngine_0_10.this);
- }
- });
-
}
public void setNetworkConnection(NetworkConnection network)
@@ -87,13 +70,61 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
{
_network = network;
- _connection.setSender(new Disassembler(sender, MAX_FRAME_SIZE));
+ _connection.setNetworkConnection(network);
+ _connection.setSender(new Disassembler(wrapSender(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));
}
+ private Sender<ByteBuffer> wrapSender(final Sender<ByteBuffer> sender)
+ {
+ return new Sender<ByteBuffer>()
+ {
+ @Override
+ public void setIdleTimeout(int i)
+ {
+ sender.setIdleTimeout(i);
+
+ }
+
+ @Override
+ public void send(ByteBuffer msg)
+ {
+ _lastWriteTime = System.currentTimeMillis();
+ sender.send(msg);
+
+ }
+
+ @Override
+ public void flush()
+ {
+ sender.flush();
+
+ }
+
+ @Override
+ public void close()
+ {
+ sender.close();
+
+ }
+ };
+ }
+
+ @Override
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime;
+ }
+
public SocketAddress getRemoteAddress()
{
return _network.getRemoteAddress();
@@ -106,6 +137,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
public void received(final ByteBuffer buf)
{
+ _lastReadTime = System.currentTimeMillis();
super.received(buf);
_connection.receivedComplete();
}
@@ -122,7 +154,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
public void writerIdle()
{
- //Todo
+ _connection.doHeartbeat();
}
public void readerIdle()
@@ -130,72 +162,16 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
//Todo
}
- public VirtualHostConfig getVirtualHost()
- {
- return _connection.getVirtualHost();
- }
-
public String getAddress()
{
return getRemoteAddress().toString();
}
- public Boolean isIncoming()
- {
- return true;
- }
-
- public Boolean isSystemConnection()
- {
- return false;
- }
-
- public Boolean isFederationLink()
- {
- return false;
- }
-
public String getAuthId()
{
return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName();
}
- public String getRemoteProcessName()
- {
- return null;
- }
-
- public Integer getRemotePID()
- {
- return null;
- }
-
- public Integer getRemoteParentPID()
- {
- return null;
- }
-
- public ConfigStore getConfigStore()
- {
- return _appRegistry.getConfigStore();
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public ConnectionConfigType getConfigType()
- {
- return ConnectionConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
public boolean isDurable()
{
return false;
@@ -205,7 +181,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
public void closed()
{
super.closed();
- getConfigStore().removeConfiguredObject(this);
}
public long getCreateTime()
@@ -213,16 +188,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol
return _createTime;
}
- public Boolean isShadow()
- {
- return false;
- }
-
- public void mgmtClose()
- {
- _connection.mgmtClose();
- }
-
public long getConnectionId()
{
return _connection.getConnectionId();
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 e6282315c6..f6b8e1e5c9 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
@@ -22,7 +22,6 @@ package org.apache.qpid.server.protocol;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
-import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -39,11 +38,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.FrameBody;
import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConnectionConfigType;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.v1_0.Connection_1_0;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.NetworkConnection;
@@ -54,8 +52,9 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
//private NetworkConnection _networkDriver;
private long _readBytes;
private long _writtenBytes;
- private final UUID _id;
- private final IApplicationRegistry _appRegistry;
+ private long _lastReadTime;
+ private long _lastWriteTime;
+ private final Broker _broker;
private long _createTime = System.currentTimeMillis();
private ConnectionEndpoint _conn;
private final long _connectionId;
@@ -99,11 +98,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
- public ProtocolEngine_1_0_0(final IApplicationRegistry appRegistry, long id)
+ public ProtocolEngine_1_0_0(final NetworkConnection networkDriver, final Broker broker, long id)
{
- _id = appRegistry.getConfigStore().createId();
- _appRegistry = appRegistry;
+ _broker = broker;
_connectionId = id;
+ if(networkDriver != null)
+ {
+ setNetworkConnection(networkDriver, networkDriver.getSender());
+ }
}
@@ -142,13 +144,15 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
_network = network;
_sender = sender;
- Container container = new Container(_appRegistry.getBrokerId().toString());
+ Container container = new Container(_broker.getId().toString());
+
+ VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST));
- _conn = new ConnectionEndpoint(container, asSaslServerProvider(_appRegistry.getAuthenticationManager(
+ _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator(
getLocalAddress())));
- _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId));
- _conn.setFrameOutputHandler(this);
_conn.setRemoteAddress(_network.getRemoteAddress());
+ _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId));
+ _conn.setFrameOutputHandler(this);
_frameWriter = new FrameWriter(_conn.getDescribedTypeRegistry());
_frameHandler = new FrameHandler(_conn);
@@ -157,14 +161,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
_sender.flush();
}
- private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager)
+ private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator)
{
return new SaslServerProvider()
{
@Override
public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException
{
- return authenticationManager.createSaslServer(mechanism, fqdn, null);
+ return subjectCreator.createSaslServer(mechanism, fqdn, null);
}
};
}
@@ -174,22 +178,6 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
return getRemoteAddress().toString();
}
-
- public ConfigStore getConfigStore()
- {
- return _appRegistry.getConfigStore();
- }
-
- public UUID getId()
- {
- return _id;
- }
-
- public ConnectionConfigType getConfigType()
- {
- return ConnectionConfigType.getInstance();
- }
-
public boolean isDurable()
{
return false;
@@ -197,6 +185,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
public synchronized void received(ByteBuffer msg)
{
+ _lastReadTime = System.currentTimeMillis();
if(RAW_LOGGER.isLoggable(Level.FINE))
{
ByteBuffer dup = msg.duplicate();
@@ -339,6 +328,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
synchronized(_sendLock)
{
+ _lastWriteTime = System.currentTimeMillis();
if(FRAME_LOGGER.isLoggable(Level.FINE))
{
FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody());
@@ -393,4 +383,13 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa
return _connectionId;
}
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime;
+ }
}
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 a48441bf30..3b02ef2e5b 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
@@ -23,7 +23,6 @@ package org.apache.qpid.server.protocol;
import java.io.PrintWriter;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
-import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.sasl.SaslException;
@@ -40,12 +39,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler;
import org.apache.qpid.amqp_1_0.type.Binary;
import org.apache.qpid.amqp_1_0.type.FrameBody;
import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConnectionConfigType;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.v1_0.Connection_1_0;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.NetworkConnection;
@@ -53,8 +50,10 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
{
private long _readBytes;
private long _writtenBytes;
- private final UUID _id;
- private final IApplicationRegistry _appRegistry;
+
+ private long _lastReadTime;
+ private long _lastWriteTime;
+ private final Broker _broker;
private long _createTime = System.currentTimeMillis();
private ConnectionEndpoint _conn;
private long _connectionId;
@@ -113,13 +112,11 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
private State _state = State.A;
- public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final IApplicationRegistry appRegistry,
+ public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final Broker broker,
long id)
{
- _id = appRegistry.getConfigStore().createId();
_connectionId = id;
- _appRegistry = appRegistry;
-
+ _broker = broker;
if(networkDriver != null)
{
setNetworkConnection(networkDriver, networkDriver.getSender());
@@ -162,21 +159,17 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
_network = network;
_sender = sender;
- Container container = new Container(_appRegistry.getBrokerId().toString());
+ Container container = new Container(_broker.getId().toString());
- _conn = new ConnectionEndpoint(container, asSaslServerProvider(ApplicationRegistry.getInstance()
- .getAuthenticationManager(getLocalAddress())));
- _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId));
+ VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST));
+ _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator(getLocalAddress())));
_conn.setRemoteAddress(getRemoteAddress());
-
-
+ _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId));
_conn.setFrameOutputHandler(this);
_conn.setSaslFrameOutput(this);
_conn.setOnSaslComplete(new Runnable()
{
-
-
public void run()
{
if(_conn.isAuthenticated())
@@ -201,14 +194,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
}
- private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager)
+ private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator)
{
return new SaslServerProvider()
{
@Override
public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException
{
- return authenticationManager.createSaslServer(mechanism, fqdn, null);
+ return subjectCreator.createSaslServer(mechanism, fqdn, null);
}
};
}
@@ -218,22 +211,6 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
return getRemoteAddress().toString();
}
-
- public ConfigStore getConfigStore()
- {
- return _appRegistry.getConfigStore();
- }
-
- public UUID getId()
- {
- return _id;
- }
-
- public ConnectionConfigType getConfigType()
- {
- return ConnectionConfigType.getInstance();
- }
-
public boolean isDurable()
{
return false;
@@ -244,6 +221,7 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
public synchronized void received(ByteBuffer msg)
{
+ _lastReadTime = System.currentTimeMillis();
if(RAW_LOGGER.isLoggable(Level.FINE))
{
ByteBuffer dup = msg.duplicate();
@@ -386,17 +364,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
synchronized(_sendLock)
{
-
+ _lastWriteTime = System.currentTimeMillis();
if(FRAME_LOGGER.isLoggable(Level.FINE))
{
FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody());
}
-
_frameWriter.setValue(amqFrame);
-
-
ByteBuffer dup = ByteBuffer.allocate(_conn.getMaxFrameSize());
int size = _frameWriter.writeToBuffer(dup);
@@ -447,4 +422,13 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut
return _connectionId;
}
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime;
+ }
}
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 f429d8ba9f..cf4164c244 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
@@ -31,7 +31,6 @@ 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;
@@ -44,7 +43,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTIO
public class Connection_1_0 implements ConnectionEventListener
{
- private IApplicationRegistry _appRegistry;
private VirtualHost _vhost;
private final ConnectionEndpoint _conn;
private final long _connectionId;
@@ -62,10 +60,9 @@ public class Connection_1_0 implements ConnectionEventListener
- public Connection_1_0(IApplicationRegistry appRegistry, ConnectionEndpoint conn, long connectionId)
+ public Connection_1_0(VirtualHost virtualHost, ConnectionEndpoint conn, long connectionId)
{
- _appRegistry = appRegistry;
- _vhost = _appRegistry.getVirtualHostRegistry().getDefaultVirtualHost();
+ _vhost = virtualHost;
_conn = conn;
_connectionId = connectionId;
_vhost.getConnectionRegistry().registerConnection(_model);
@@ -74,7 +71,7 @@ public class Connection_1_0 implements ConnectionEventListener
public void remoteSessionCreation(SessionEndpoint endpoint)
{
- Session_1_0 session = new Session_1_0(_vhost, _appRegistry, this);
+ Session_1_0 session = new Session_1_0(_vhost, this);
_sessions.add(session);
endpoint.setSessionEventListener(session);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
index ba1a1ca45c..2cef27267b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java
@@ -80,7 +80,7 @@ public class ExchangeDestination implements ReceivingDestination, SendingDestina
{
// NO-OP
}
- }, System.currentTimeMillis());
+ });
return ACCEPTED;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
index 140a815f57..fbce1666b7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java
@@ -23,9 +23,10 @@ package org.apache.qpid.server.protocol.v1_0;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.SessionConfig;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.MessageMetaData_1_0;
import org.apache.qpid.server.message.MessageReference;
@@ -34,11 +35,45 @@ import org.apache.qpid.server.store.StoredMessage;
public class Message_1_0 implements ServerMessage, InboundMessage
{
+
+
+ private static final AtomicIntegerFieldUpdater<Message_1_0> _refCountUpdater =
+ AtomicIntegerFieldUpdater.newUpdater(Message_1_0.class, "_referenceCount");
+
+ private volatile int _referenceCount = 0;
+
private final StoredMessage<MessageMetaData_1_0> _storedMessage;
private List<ByteBuffer> _fragments;
private WeakReference<Session_1_0> _session;
+ public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage)
+ {
+ _storedMessage = storedMessage;
+ _session = null;
+ _fragments = restoreFragments(storedMessage);
+ }
+
+ private static List<ByteBuffer> restoreFragments(StoredMessage<MessageMetaData_1_0> storedMessage)
+ {
+ ArrayList<ByteBuffer> fragments = new ArrayList<ByteBuffer>();
+ final int FRAGMENT_SIZE = 2048;
+ int offset = 0;
+ ByteBuffer b;
+ do
+ {
+
+ b = storedMessage.getContent(offset,FRAGMENT_SIZE);
+ if(b.hasRemaining())
+ {
+ fragments.add(b);
+ offset+= b.remaining();
+ }
+ }
+ while(b.hasRemaining());
+ return fragments;
+ }
+
public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage,
final List<ByteBuffer> fragments,
final Session_1_0 session)
@@ -136,11 +171,6 @@ public class Message_1_0 implements ServerMessage, InboundMessage
return buf;
}
- public SessionConfig getSessionConfig()
- {
- return null; //TODO
- }
-
public List<ByteBuffer> getFragments()
{
return _fragments;
@@ -148,7 +178,61 @@ public class Message_1_0 implements ServerMessage, InboundMessage
public Session_1_0 getSession()
{
- return _session.get();
+ return _session == null ? null : _session.get();
+ }
+
+
+ public boolean incrementReference()
+ {
+ if(_refCountUpdater.incrementAndGet(this) <= 0)
+ {
+ _refCountUpdater.decrementAndGet(this);
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ /**
+ * Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the
+ * message store.
+ *
+ *
+ * @throws org.apache.qpid.server.queue.MessageCleanupException when an attempt was made to remove the message from the message store and that
+ * failed
+ */
+ public void decrementReference()
+ {
+ int count = _refCountUpdater.decrementAndGet(this);
+
+ // note that the operation of decrementing the reference count and then removing the message does not
+ // have to be atomic since the ref count starts at 1 and the exchange itself decrements that after
+ // the message has been passed to all queues. i.e. we are
+ // not relying on the all the increments having taken place before the delivery manager decrements.
+ if (count == 0)
+ {
+ // set the reference count way below 0 so that we can detect that the message has been deleted
+ // this is to guard against the message being spontaneously recreated (from the mgmt console)
+ // by copying from other queues at the same time as it is being removed.
+ _refCountUpdater.set(this,Integer.MIN_VALUE/2);
+
+ // must check if the handle is null since there may be cases where we decide to throw away a message
+ // and the handle has not yet been constructed
+ if (_storedMessage != null)
+ {
+ _storedMessage.remove();
+ }
+ }
+ else
+ {
+ if (count < 0)
+ {
+ throw new RuntimeException("Reference count for message id " + getMessageNumber()
+ + " has gone below 0.");
+ }
+ }
}
public static class Reference extends MessageReference<Message_1_0>
@@ -160,13 +244,13 @@ public class Message_1_0 implements ServerMessage, InboundMessage
protected void onReference(Message_1_0 message)
{
-
+ message.incrementReference();
}
protected void onRelease(Message_1_0 message)
{
-
+ message.decrementReference();
}
-}
+ }
}
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 999ffc55e5..a0ed824c58 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
@@ -36,7 +36,6 @@ 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;
@@ -45,8 +44,6 @@ 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;
@@ -58,7 +55,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F
public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSubject
{
private static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy");
- private IApplicationRegistry _appRegistry;
private VirtualHost _vhost;
private AutoCommitTransaction _transaction;
@@ -68,9 +64,8 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu
private UUID _id = UUID.randomUUID();
- public Session_1_0(VirtualHost vhost, IApplicationRegistry appRegistry, final Connection_1_0 connection)
+ public Session_1_0(VirtualHost vhost, final Connection_1_0 connection)
{
- _appRegistry = appRegistry;
_vhost = vhost;
_transaction = new AutoCommitTransaction(vhost.getMessageStore());
_connection = connection;
@@ -456,8 +451,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu
{
}
+
@Override
- public UUID getQMFId()
+ public UUID getId()
{
return _id;
}
@@ -580,13 +576,6 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu
return 0;
}
- @Override
- public int compareTo(AMQSessionModel o)
- {
- return getQMFId().compareTo(o.getQMFId());
- }
-
-
public String toLogString()
{
@@ -604,4 +593,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu
+ "] ";
}
+ @Override
+ public int compareTo(AMQSessionModel o)
+ {
+ return getId().compareTo(o.getId());
+ }
}
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 d3efd63ee0..4f610cc925 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
@@ -23,8 +23,7 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.QueueConfig;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeReferrer;
import org.apache.qpid.server.logging.LogSubject;
@@ -39,9 +38,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue,
- QueueConfig
+public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue
{
+ String getName();
+
public interface NotificationListener
{
void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg);
@@ -277,9 +277,7 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa
public void doTask(AMQQueue queue) throws AMQException;
}
- void configure(ConfigurationPlugin config);
-
- ConfigurationPlugin getConfiguration();
+ void configure(QueueConfiguration config);
void setExclusive(boolean exclusive);
@@ -315,4 +313,18 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa
*/
String getDescription();
+ long getPersistentByteDequeues();
+
+ long getPersistentMsgDequeues();
+
+ long getPersistentByteEnqueues();
+
+ long getPersistentMsgEnqueues();
+
+ long getTotalDequeueSize();
+
+ long getTotalEnqueueSize();
+
+ long getUnackedMessageCount();
+
}
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 3a18fae2ec..a65a6a8eb2 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
@@ -30,17 +30,25 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.configuration.QueueConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.exchange.DefaultExchangeFactory;
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.model.UUIDGenerator;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
public class AMQQueueFactory
{
+ public static final String X_QPID_FLOW_RESUME_CAPACITY = "x-qpid-flow-resume-capacity";
+ public static final String X_QPID_CAPACITY = "x-qpid-capacity";
+ public static final String X_QPID_MINIMUM_ALERT_REPEAT_GAP = "x-qpid-minimum-alert-repeat-gap";
+ public static final String X_QPID_MAXIMUM_MESSAGE_COUNT = "x-qpid-maximum-message-count";
+ public static final String X_QPID_MAXIMUM_MESSAGE_SIZE = "x-qpid-maximum-message-size";
+ public static final String X_QPID_MAXIMUM_MESSAGE_AGE = "x-qpid-maximum-message-age";
+ public static final String X_QPID_MAXIMUM_QUEUE_DEPTH = "x-qpid-maximum-queue-depth";
+
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";
@@ -119,42 +127,49 @@ public class AMQQueueFactory
}
private static final QueueProperty[] DECLAREABLE_PROPERTIES = {
- new QueueLongProperty("x-qpid-maximum-message-age")
+ new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_AGE)
{
public void setPropertyValue(AMQQueue queue, long value)
{
queue.setMaximumMessageAge(value);
}
},
- new QueueLongProperty("x-qpid-maximum-message-size")
+ new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_SIZE)
{
public void setPropertyValue(AMQQueue queue, long value)
{
queue.setMaximumMessageSize(value);
}
},
- new QueueLongProperty("x-qpid-maximum-message-count")
+ new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_COUNT)
{
public void setPropertyValue(AMQQueue queue, long value)
{
queue.setMaximumMessageCount(value);
}
},
- new QueueLongProperty("x-qpid-minimum-alert-repeat-gap")
+ new QueueLongProperty(X_QPID_MAXIMUM_QUEUE_DEPTH)
+ {
+ public void setPropertyValue(AMQQueue queue, long value)
+ {
+ queue.setMaximumQueueDepth(value);
+ }
+ },
+ new QueueLongProperty(X_QPID_MINIMUM_ALERT_REPEAT_GAP)
{
public void setPropertyValue(AMQQueue queue, long value)
{
queue.setMinimumAlertRepeatGap(value);
}
},
- new QueueLongProperty("x-qpid-capacity")
+ new QueueLongProperty(X_QPID_CAPACITY)
{
public void setPropertyValue(AMQQueue queue, long value)
{
queue.setCapacity(value);
}
},
- new QueueLongProperty("x-qpid-flow-resume-capacity")
+ new QueueLongProperty(X_QPID_FLOW_RESUME_CAPACITY)
{
public void setPropertyValue(AMQQueue queue, long value)
{
@@ -411,9 +426,7 @@ public class AMQQueueFactory
*/
protected static String getDeadLetterQueueName(String name)
{
- ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration();
- String dlQueueName = name + serverConfig.getDeadLetterQueueSuffix();
- return dlQueueName;
+ return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, DEFAULT_DLQ_NAME_SUFFIX);
}
/**
@@ -425,9 +438,7 @@ public class AMQQueueFactory
*/
protected static String getDeadLetterExchangeName(String name)
{
- ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration();
- String dlExchangeName = name + serverConfig.getDeadLetterExchangeSuffix();
- return dlExchangeName;
+ return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
}
private static Map<String, Object> createQueueArgumentsFromConfig(QueueConfiguration config)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
index bbc33ca846..d7dbd58537 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java
@@ -47,7 +47,7 @@ public class InboundMessageAdapter implements InboundMessage
public AMQShortString getRoutingKeyShortString()
{
- return AMQShortString.valueOf(_entry.getMessage());
+ return AMQShortString.valueOf(_entry.getMessage().getRoutingKey());
}
public String getRoutingKey()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
index c5a610c7b6..18affc7161 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java
@@ -34,7 +34,6 @@ import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.MessageContentSource;
import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoredMessage;
import java.nio.ByteBuffer;
@@ -47,9 +46,6 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
/** Used for debugging purposes. */
private static final Logger _logger = Logger.getLogger(IncomingMessage.class);
- private static final boolean SYNCHED_CLOCKS =
- ApplicationRegistry.getInstance().getConfiguration().getSynchedClocks();
-
private final MessagePublishInfo _messagePublishInfo;
private ContentHeaderBody _contentHeaderBody;
@@ -101,33 +97,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public void setExpiration()
{
- long expiration =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration();
- long timestamp =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getTimestamp();
-
- if (SYNCHED_CLOCKS)
- {
- _expiration = expiration;
- }
- else
- {
- // Update TTL to be in broker time.
- if (expiration != 0L)
- {
- if (timestamp != 0L)
- {
- // todo perhaps use arrival time
- long diff = (System.currentTimeMillis() - timestamp);
-
- if ((diff > 1000L) || (diff < 1000L))
- {
- _expiration = expiration + diff;
- }
- }
- }
- }
-
+ _expiration = ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration();
}
public MessageMetaData headersReceived(long currentTime)
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 25e771a9cf..9aa8d1da83 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
@@ -454,7 +454,7 @@ public abstract class QueueEntryImpl implements QueueEntry
{
}
- }, 0L);
+ });
txn.dequeue(currentQueue, message, new ServerTransaction.Action()
{
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 d42bd6cf03..73c2870b9b 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
@@ -41,11 +41,8 @@ import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.QueueConfigType;
import org.apache.qpid.server.configuration.QueueConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.AbstractConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
@@ -55,7 +52,6 @@ import org.apache.qpid.server.logging.messages.QueueMessages;
import org.apache.qpid.server.logging.subjects.QueueLogSubject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.protocol.AMQSessionModel;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.AuthorizationHolder;
import org.apache.qpid.server.subscription.AssignedSubscriptionMessageGroupManager;
import org.apache.qpid.server.subscription.DefinedGroupMessageGroupManager;
@@ -135,23 +131,23 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
private final AtomicInteger _bindingCountHigh = new AtomicInteger();
/** max allowed size(KB) of a single message */
- private long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize();
+ private long _maximumMessageSize;
/** max allowed number of messages on a queue. */
- private long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount();
+ private long _maximumMessageCount;
/** max queue depth for the queue */
- private long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth();
+ private long _maximumQueueDepth;
/** maximum message age before alerts occur */
- private long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge();
+ private long _maximumMessageAge;
/** the minimum interval between sending out consecutive alerts of the same type */
- private long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap();
+ private long _minimumAlertRepeatGap;
- private long _capacity = ApplicationRegistry.getInstance().getConfiguration().getCapacity();
+ private long _capacity;
- private long _flowResumeCapacity = ApplicationRegistry.getInstance().getConfiguration().getFlowResumeCapacity();
+ private long _flowResumeCapacity;
private final Set<NotificationCheck> _notificationChecks = EnumSet.noneOf(NotificationCheck.class);
@@ -185,11 +181,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
//TODO : persist creation time
private long _createTime = System.currentTimeMillis();
- private UUID _qmfId;
- private ConfigurationPlugin _queueConfiguration;
+ private AbstractConfiguration _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 int _maximumDeliveryCount;
private final MessageGroupManager _messageGroupManager;
private final Collection<SubscriptionRegistrationListener> _subscriptionListeners =
@@ -243,7 +238,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
_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);
@@ -259,8 +253,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
durable, !durable,
_entries.getPriorities() > 0));
- getConfigStore().addConfiguredObject(this);
-
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"))
@@ -331,22 +323,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
return _id;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public QueueConfigType getConfigType()
- {
- return QueueConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
- }
-
public boolean isDurable()
{
return _durable;
@@ -621,24 +597,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
break;
}
}
-
- reconfigure();
- }
-
- private void reconfigure()
- {
- //Reconfigure the queue for to reflect this new binding.
- ConfigurationPlugin config = getVirtualHost().getConfiguration().getQueueConfiguration(this);
-
- if (config != null)
- {
- if (_logger.isDebugEnabled())
- {
- _logger.debug("Reconfiguring queue(" + this + ") with config:" + config + " was "+ _queueConfiguration);
- }
- // Reconfigure with new config.
- configure(config);
- }
}
public int getBindingCountHigh()
@@ -649,8 +607,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
public void removeBinding(final Binding binding)
{
_bindings.remove(binding);
-
- reconfigure();
}
public List<Binding> getBindings()
@@ -1383,7 +1339,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
_virtualHost.getQueueRegistry().unregisterQueue(_name);
- getConfigStore().removeConfiguredObject(this);
List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter()
{
@@ -1442,7 +1397,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
{
}
- }, 0L);
+ });
txn.dequeue(this, entry.getMessage(),
new ServerTransaction.Action()
{
@@ -2161,39 +2116,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes
}
- public void configure(ConfigurationPlugin config)
+ public void configure(QueueConfiguration config)
{
if (config != null)
{
- if (config instanceof QueueConfiguration)
- {
-
- setMaximumMessageAge(((QueueConfiguration)config).getMaximumMessageAge());
- setMaximumQueueDepth(((QueueConfiguration)config).getMaximumQueueDepth());
- setMaximumMessageSize(((QueueConfiguration)config).getMaximumMessageSize());
- setMaximumMessageCount(((QueueConfiguration)config).getMaximumMessageCount());
- setMinimumAlertRepeatGap(((QueueConfiguration)config).getMinimumAlertRepeatGap());
- setMaximumDeliveryCount(((QueueConfiguration)config).getMaxDeliveryCount());
- _capacity = ((QueueConfiguration)config).getCapacity();
- _flowResumeCapacity = ((QueueConfiguration)config).getFlowResumeCapacity();
- }
-
- _queueConfiguration = config;
-
+ setMaximumMessageAge(config.getMaximumMessageAge());
+ setMaximumQueueDepth(config.getMaximumQueueDepth());
+ setMaximumMessageSize(config.getMaximumMessageSize());
+ setMaximumMessageCount(config.getMaximumMessageCount());
+ setMinimumAlertRepeatGap(config.getMinimumAlertRepeatGap());
+ setMaximumDeliveryCount(config.getMaxDeliveryCount());
+ _capacity = config.getCapacity();
+ _flowResumeCapacity = config.getFlowResumeCapacity();
}
}
-
- public ConfigurationPlugin getConfiguration()
- {
- return _queueConfiguration;
- }
-
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
public long getMessageDequeueCount()
{
return _dequeueCount.get();
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 e0e317f75d..1379b375cf 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
@@ -20,44 +20,39 @@
*/
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 java.util.Collection;
+import java.util.Timer;
+import java.util.TimerTask;
+import org.apache.log4j.Logger;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.qmf.QMFService;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfigurationManager;
-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.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider;
+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.LogRecorder;
+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.actors.GenericActor;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.model.Broker;
-import org.apache.qpid.server.model.adapter.BrokerAdapter;
-import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerRegistry;
-import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.stats.StatisticsCounter;
-import org.apache.qpid.server.transport.QpidAcceptor;
+import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicReference;
-
/**
* An abstract application registry that provides access to configuration information and handles the
@@ -65,321 +60,90 @@ import java.util.concurrent.atomic.AtomicReference;
* <p/>
* Subclasses should handle the construction of the "registered objects" such as the exchange registry.
*/
-public abstract class ApplicationRegistry implements IApplicationRegistry
+public 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 =
- Collections.synchronizedMap(new HashMap<InetSocketAddress, QpidAcceptor>());
-
- private IAuthenticationManagerRegistry _authenticationManagerRegistry;
-
- private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(this);
-
- private SecurityManager _securityManager;
+ private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry();
- private PluginManager _pluginManager;
-
- private ConfigurationManager _configurationManager;
-
- private RootMessageLogger _rootMessageLogger;
-
- private CompositeStartupMessageLogger _startupMessageLogger;
-
- private UUID _brokerId = UUID.randomUUID();
-
- private QMFService _qmfService;
-
- private BrokerConfig _brokerConfig;
+ private volatile RootMessageLogger _rootMessageLogger;
private Broker _broker;
- private ConfigStore _configStore;
-
private Timer _reportingTimer;
private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
- private BundleContext _bundleContext;
-
- private final List<PortBindingListener> _portBindingListeners = new ArrayList<PortBindingListener>();
-
- private int _httpManagementPort = -1, _httpsManagementPort = -1;
-
private LogRecorder _logRecorder;
- private List<IAuthenticationManagerRegistry.RegistryChangeListener> _authManagerChangeListeners =
- new ArrayList<IAuthenticationManagerRegistry.RegistryChangeListener>();
-
- public Map<InetSocketAddress, QpidAcceptor> getAcceptors()
- {
- synchronized (_acceptors)
- {
- return new HashMap<InetSocketAddress, QpidAcceptor>(_acceptors);
- }
- }
-
- protected void setSecurityManager(SecurityManager securityManager)
- {
- _securityManager = securityManager;
- }
-
- protected void setPluginManager(PluginManager pluginManager)
- {
- _pluginManager = pluginManager;
- }
-
- protected void setConfigurationManager(ConfigurationManager configurationManager)
- {
- _configurationManager = configurationManager;
- }
+ private ConfigurationEntryStore _store;
+ private TaskExecutor _taskExecutor;
protected void setRootMessageLogger(RootMessageLogger rootMessageLogger)
{
_rootMessageLogger = rootMessageLogger;
}
- protected CompositeStartupMessageLogger getStartupMessageLogger()
- {
- return _startupMessageLogger;
- }
-
- protected void setStartupMessageLogger(CompositeStartupMessageLogger startupMessageLogger)
+ public ApplicationRegistry(ConfigurationEntryStore store)
{
- _startupMessageLogger = startupMessageLogger;
- }
-
- protected void setBrokerId(UUID brokerId)
- {
- _brokerId = brokerId;
- }
-
- protected QMFService getQmfService()
- {
- return _qmfService;
- }
-
- protected void setQmfService(QMFService qmfService)
- {
- _qmfService = qmfService;
- }
-
- public static void initialise(IApplicationRegistry instance) throws Exception
- {
- if(instance == null)
- {
- throw new IllegalArgumentException("ApplicationRegistry instance must not be null");
- }
-
- if(!_instance.compareAndSet(null, instance))
- {
- throw new IllegalStateException("An ApplicationRegistry is already initialised");
- }
-
- _logger.info("Initialising Application Registry(" + instance + ")");
-
-
- final ConfigStore store = ConfigStore.newInstance();
- store.setRoot(new SystemConfigImpl(store));
- instance.setConfigStore(store);
-
- final BrokerConfig brokerConfig = new BrokerConfigAdapter(instance);
-
- final SystemConfig system = store.getRoot();
- system.addBroker(brokerConfig);
- instance.setBrokerConfig(brokerConfig);
-
- try
- {
- instance.initialise();
- }
- catch (Exception e)
- {
- _instance.set(null);
-
- //remove the Broker instance, then re-throw
- try
- {
- system.removeBroker(brokerConfig);
- }
- catch(Throwable t)
- {
- //ignore
- }
-
- throw e;
- }
- }
-
- public ConfigStore getConfigStore()
- {
- return _configStore;
- }
-
- public void setConfigStore(final ConfigStore configStore)
- {
- _configStore = configStore;
- }
-
- public static boolean isConfigured()
- {
- return _instance.get() != null;
- }
-
- public static void remove()
- {
- IApplicationRegistry instance = _instance.getAndSet(null);
- try
- {
- if (instance != null)
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Shutting down ApplicationRegistry(" + instance + ")");
- }
- instance.close();
- }
- }
- catch (Exception e)
- {
- _logger.error("Error shutting down Application Registry(" + instance + "): " + e, e);
- }
- }
-
- protected ApplicationRegistry(ServerConfiguration configuration)
- {
- this(configuration, null);
- }
-
- protected ApplicationRegistry(ServerConfiguration configuration, BundleContext bundleContext)
- {
- _configuration = configuration;
- _bundleContext = bundleContext;
- }
-
- public void configure() throws ConfigurationException
- {
- _configurationManager = new ConfigurationManager();
-
- try
- {
- _pluginManager = new PluginManager(_configuration.getPluginDirectory(), _configuration.getCacheDirectory(), _bundleContext);
- }
- catch (Exception e)
- {
- throw new ConfigurationException(e);
- }
-
- _configuration.initialise();
+ _store = store;
+ initialiseStatistics();
}
public void initialise() throws Exception
{
+ // Create the RootLogger to be used during broker operation
+ boolean statusUpdatesEnabled = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_STATUS_UPDATES, "true"));
+ _rootMessageLogger = new Log4jMessageLogger(statusUpdatesEnabled);
+
_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);
+ CompositeStartupMessageLogger startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers);
- BrokerActor actor = new BrokerActor(_startupMessageLogger);
- CurrentActor.setDefault(actor);
+ BrokerActor actor = new BrokerActor(startupMessageLogger);
CurrentActor.set(actor);
-
+ CurrentActor.setDefault(actor);
+ GenericActor.setDefaultMessageLogger(_rootMessageLogger);
try
{
- initialiseStatistics();
-
- if(_configuration.getHTTPManagementEnabled())
- {
- _httpManagementPort = _configuration.getHTTPManagementPort();
- }
- if (_configuration.getHTTPSManagementEnabled())
- {
- _httpsManagementPort = _configuration.getHTTPSManagementPort();
- }
-
- _broker = new BrokerAdapter(this);
-
- configure();
-
- _qmfService = new QMFService(getConfigStore(), this);
-
logStartupMessages(CurrentActor.get());
- _securityManager = new SecurityManager(_configuration, _pluginManager);
+ _taskExecutor = new TaskExecutor();
+ _taskExecutor.start();
- _authenticationManagerRegistry = createAuthenticationManagerRegistry(_configuration, _pluginManager);
+ RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor);
+ ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName());
+ _broker = (Broker) brokerRecoverer.create(provider, _store.getRootEntry());
- if(!_authManagerChangeListeners.isEmpty())
- {
- for(IAuthenticationManagerRegistry.RegistryChangeListener listener : _authManagerChangeListeners)
- {
+ _virtualHostRegistry.setDefaultVirtualHostName((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST));
- _authenticationManagerRegistry.addRegistryChangeListener(listener);
- for(AuthenticationManager authMgr : _authenticationManagerRegistry.getAvailableAuthenticationManagers().values())
- {
- listener.authenticationManagerRegistered(authMgr);
- }
- }
- _authManagerChangeListeners.clear();
- }
- }
- finally
- {
- CurrentActor.remove();
- }
-
- CurrentActor.set(new BrokerActor(_rootMessageLogger));
- try
- {
- initialiseVirtualHosts();
initialiseStatisticsReporting();
+
+ // starting the broker
+ _broker.setDesiredState(State.INITIALISING, State.ACTIVE);
+
+ CurrentActor.get().message(BrokerMessages.READY());
}
finally
{
- // Startup complete, so pop the current actor
CurrentActor.remove();
}
- }
- protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(ServerConfiguration _configuration, PluginManager _pluginManager)
- throws ConfigurationException
- {
- return new AuthenticationManagerRegistry(_configuration, _pluginManager);
+ CurrentActor.setDefault(new BrokerActor(_rootMessageLogger));
}
- protected void initialiseVirtualHosts() throws Exception
+ private void initialiseStatisticsReporting()
{
- for (String name : _configuration.getVirtualHosts())
- {
- createVirtualHost(_configuration.getVirtualHostConfig(name));
- }
- getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost());
- }
-
- 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();
+ long report = ((Number)_broker.getAttribute(Broker.STATISTICS_REPORTING_PERIOD)).intValue() * 1000; // convert to ms
+ final boolean reset = (Boolean)_broker.getAttribute(Broker.STATISTICS_REPORTING_RESET_ENABLED);
/* add a timer task to report statistics if generation is enabled for broker or virtualhosts */
- if (report > 0L && (broker || virtualhost))
+ if (report > 0L)
{
_reportingTimer = new Timer("Statistics-Reporting", true);
-
-
-
- _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(broker, virtualhost, reset),
- report / 2,
- report);
+ StatisticsReportingTask task = new StatisticsReportingTask(reset, _rootMessageLogger);
+ _reportingTimer.scheduleAtFixedRate(task, report / 2, report);
}
}
@@ -388,76 +152,62 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private final int DELIVERED = 0;
private final int RECEIVED = 1;
- private boolean _broker;
- private boolean _virtualhost;
- private boolean _reset;
+ private final boolean _reset;
+ private final RootMessageLogger _logger;
-
- public StatisticsReportingTask(boolean broker, boolean virtualhost, boolean reset)
+ public StatisticsReportingTask(boolean reset, RootMessageLogger logger)
{
- _broker = broker;
- _virtualhost = virtualhost;
_reset = reset;
+ _logger = logger;
}
public void run()
{
- CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) {
+ CurrentActor.set(new AbstractActor(_logger)
+ {
public String getLogMessage()
{
return "[" + Thread.currentThread().getName() + "] ";
}
});
-
- if (_broker)
+ try
{
CurrentActor.get().message(BrokerMessages.STATS_DATA(DELIVERED, _dataDelivered.getPeak() / 1024.0, _dataDelivered.getTotal()));
CurrentActor.get().message(BrokerMessages.STATS_MSGS(DELIVERED, _messagesDelivered.getPeak(), _messagesDelivered.getTotal()));
CurrentActor.get().message(BrokerMessages.STATS_DATA(RECEIVED, _dataReceived.getPeak() / 1024.0, _dataReceived.getTotal()));
CurrentActor.get().message(BrokerMessages.STATS_MSGS(RECEIVED, _messagesReceived.getPeak(), _messagesReceived.getTotal()));
- }
+ Collection<VirtualHost> hosts = _virtualHostRegistry.getVirtualHosts();
- if (_virtualhost)
- {
- for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts())
+ if (hosts.size() > 1)
{
- String name = vhost.getName();
- StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics();
- StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics();
- StatisticsCounter dataReceived = vhost.getDataReceiptStatistics();
- StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics();
-
- CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal()));
+ for (VirtualHost vhost : hosts)
+ {
+ String name = vhost.getName();
+ StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics();
+ StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics();
+ StatisticsCounter dataReceived = vhost.getDataReceiptStatistics();
+ StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics();
+
+ CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal()));
+ CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal()));
+ CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal()));
+ CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal()));
+ }
}
- }
- if (_reset)
+ if (_reset)
+ {
+ resetStatistics();
+ }
+ }
+ catch(Exception e)
{
- resetStatistics();
+ ApplicationRegistry._logger.warn("Unexpected exception occured while reporting the statistics", e);
+ }
+ finally
+ {
+ CurrentActor.remove();
}
-
- CurrentActor.remove();
- }
- }
-
- /**
- * Get the ApplicationRegistry
- * @return the IApplicationRegistry instance
- * @throws IllegalStateException if no registry instance has been initialised.
- */
- public static IApplicationRegistry getInstance() throws IllegalStateException
- {
- IApplicationRegistry iApplicationRegistry = _instance.get();
- if (iApplicationRegistry == null)
- {
- throw new IllegalStateException("No ApplicationRegistry has been initialised");
- }
- else
- {
- return iApplicationRegistry;
}
}
@@ -488,7 +238,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
//Set the Actor for Broker Shutdown
- CurrentActor.set(new BrokerActor(getRootMessageLogger()));
+ CurrentActor.set(new BrokerActor(_rootMessageLogger));
try
{
//Stop Statistics Reporting
@@ -497,154 +247,34 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_reportingTimer.cancel();
}
- //Stop incoming connections
- unbind();
+ if (_broker != null)
+ {
+ _broker.setDesiredState(_broker.getActualState(), State.STOPPED);
+ }
//Shutdown virtualhosts
close(_virtualHostRegistry);
- close(_authenticationManagerRegistry);
-
- close(_qmfService);
-
- close(_pluginManager);
-
- BrokerConfig broker = getBrokerConfig();
- if(broker != null)
+ if (_taskExecutor != null)
{
- broker.getSystem().removeBroker(broker);
+ _taskExecutor.stop();
}
CurrentActor.get().message(BrokerMessages.STOPPED());
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- 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();
- }
- catch (Throwable e)
- {
- _logger.error("Unable to close network driver due to:" + e.getMessage());
- }
+ _logRecorder.closeLogRecorder();
- 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()
- {
- return _configuration;
- }
-
- public void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor)
- {
- synchronized (_acceptors)
- {
- _acceptors.put(bindAddress, acceptor);
- }
- synchronized (_portBindingListeners)
+ finally
{
- for(PortBindingListener listener : _portBindingListeners)
+ if (_taskExecutor != null)
{
- listener.bound(acceptor, bindAddress);
+ _taskExecutor.stopImmediately();
}
+ CurrentActor.remove();
}
- }
-
- public VirtualHostRegistry getVirtualHostRegistry()
- {
- return _virtualHostRegistry;
- }
-
- public SecurityManager getSecurityManager()
- {
- return _securityManager;
- }
-
- @Override
- public AuthenticationManager getAuthenticationManager(SocketAddress address)
- {
- return _authenticationManagerRegistry.getAuthenticationManager(address);
- }
-
- @Override
- public IAuthenticationManagerRegistry getAuthenticationManagerRegistry()
- {
- return _authenticationManagerRegistry;
- }
-
- public PluginManager getPluginManager()
- {
- return _pluginManager;
- }
-
- public ConfigurationManager getConfigurationManager()
- {
- return _configurationManager;
- }
-
- public RootMessageLogger getRootMessageLogger()
- {
- return _rootMessageLogger;
- }
-
- public RootMessageLogger getCompositeStartupMessageLogger()
- {
- return _startupMessageLogger;
- }
-
- public UUID getBrokerId()
- {
- return _brokerId;
- }
-
- public QMFService getQMFService()
- {
- return _qmfService;
- }
-
- public BrokerConfig getBrokerConfig()
- {
- return _brokerConfig;
- }
-
- public void setBrokerConfig(final BrokerConfig broker)
- {
- _brokerConfig = broker;
- }
-
- public VirtualHost createVirtualHost(final VirtualHostConfiguration vhostConfig) throws Exception
- {
- VirtualHostImpl virtualHost = new VirtualHostImpl(this, vhostConfig);
- _virtualHostRegistry.registerVirtualHost(virtualHost);
- getBrokerConfig().addVirtualHost(virtualHost);
- return virtualHost;
+ _store = null;
+ _broker = null;
}
public void registerMessageDelivered(long messageSize)
@@ -713,60 +343,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
logActor.message(BrokerMessages.MAX_MEMORY(Runtime.getRuntime().maxMemory()));
}
+ @Override
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
deleted file mode 100644
index 950a090b43..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.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.registry;
-
-import org.apache.qpid.common.QpidProperties;
-import org.apache.qpid.common.ServerPropertyNames;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.BrokerConfigType;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.SystemConfig;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class BrokerConfigAdapter implements BrokerConfig
-{
- private final IApplicationRegistry _instance;
- private SystemConfig _system;
-
- private final Map<UUID, VirtualHostConfig> _vhosts = new ConcurrentHashMap<UUID, VirtualHostConfig>();
- private final long _createTime = System.currentTimeMillis();
- private UUID _qmfId;
- private String _federationTag;
-
- public BrokerConfigAdapter(final IApplicationRegistry instance)
- {
- _instance = instance;
- _qmfId = instance.getConfigStore().createId();
- _federationTag = UUID.randomUUID().toString();
- }
-
- public void setSystem(final SystemConfig system)
- {
- _system = system;
- }
-
- public SystemConfig getSystem()
- {
- return _system;
- }
-
- public Integer getPort()
- {
- List ports = _instance.getConfiguration().getPorts();
- if(ports.size() > 0)
- {
- return Integer.valueOf(ports.get(0).toString());
- }
- else
- {
- return 0;
- }
- }
-
- public Integer getWorkerThreads()
- {
- return _instance.getConfiguration().getConnectorProcessors();
- }
-
- public Integer getMaxConnections()
- {
- return 0;
- }
-
- public Integer getConnectionBacklogLimit()
- {
- return 0;
- }
-
- public Long getStagingThreshold()
- {
- return 0L;
- }
-
- public Integer getManagementPublishInterval()
- {
- return 10000;
- }
-
- public String getVersion()
- {
- return QpidProperties.getReleaseVersion() + " [Build: " + QpidProperties.getBuildVersion() + "]";
- }
-
- public String getDataDirectory()
- {
- return _instance.getConfiguration().getQpidWork();
- }
-
- public void addVirtualHost(final VirtualHostConfig virtualHost)
- {
- _vhosts.put(virtualHost.getQMFId(), virtualHost);
- getConfigStore().addConfiguredObject(virtualHost);
-
- }
-
- private ConfigStore getConfigStore()
- {
- return _instance.getConfigStore();
- }
-
- public long getCreateTime()
- {
- return _createTime;
- }
-
- public void createBrokerConnection(final String transport,
- final String host,
- final int port,
- final boolean durable,
- final String authMechanism,
- final String username,
- final String password)
- {
- VirtualHost vhost = _instance.getVirtualHostRegistry().getDefaultVirtualHost();
- vhost.createBrokerConnection(transport, host, port, "", durable, authMechanism, username, password);
- }
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public BrokerConfigType getConfigType()
- {
- return BrokerConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return _system;
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public String getFederationTag()
- {
- return _federationTag;
- }
-
- /**
- * @see org.apache.qpid.server.configuration.BrokerConfig#getFeatures()
- */
- public List<String> getFeatures()
- {
- final List<String> features = new ArrayList<String>();
- if (!_instance.getConfiguration().getDisabledFeatures().contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR))
- {
- features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR);
- }
-
- return Collections.unmodifiableList(features);
- }
-
- @Override
- public String toString()
- {
- return "BrokerConfigAdapter{" +
- "_id=" + _qmfId +
- ", _system=" + _system +
- ", _vhosts=" + _vhosts +
- ", _createTime=" + _createTime +
- ", _federationTag='" + _federationTag + '\'' +
- '}';
- }
-}
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
deleted file mode 100644
index 774d0338ef..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ /dev/null
@@ -1,42 +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.registry;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.osgi.framework.BundleContext;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-
-import java.io.File;
-
-public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
-{
- public ConfigurationFileApplicationRegistry(File configurationURL) throws ConfigurationException
- {
- this(configurationURL, null);
- }
-
- public ConfigurationFileApplicationRegistry(File configurationURL, BundleContext bundleContext) throws ConfigurationException
- {
- super(new ServerConfiguration(configurationURL), bundleContext);
- }
-}
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 88c3c93156..d12258d194 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
@@ -20,27 +20,8 @@
*/
package org.apache.qpid.server.registry;
-import org.apache.qpid.qmf.QMFService;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.ConfigStore;
-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.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
{
@@ -56,80 +37,5 @@ public interface IApplicationRegistry extends StatisticsGatherer
*/
void close();
- /**
- * Get the low level configuration. For use cases where the configured object approach is not required
- * you can get the complete configuration information.
- * @return a Commons Configuration instance
- */
- ServerConfiguration getConfiguration();
-
- /**
- * 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);
-
- IAuthenticationManagerRegistry getAuthenticationManagerRegistry();
-
- VirtualHostRegistry getVirtualHostRegistry();
-
- SecurityManager getSecurityManager();
-
- PluginManager getPluginManager();
-
- ConfigurationManager getConfigurationManager();
-
- RootMessageLogger getRootMessageLogger();
-
- /**
- * Register any acceptors for this registry
- * @param bindAddress The address that the acceptor has been bound with
- * @param acceptor The acceptor in use
- */
- void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor);
-
- public UUID getBrokerId();
-
- QMFService getQMFService();
-
- void setBrokerConfig(BrokerConfig broker);
-
- 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/AbstractPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
deleted file mode 100644
index 704e50da5c..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
+++ /dev/null
@@ -1,57 +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;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-
-/**
- * This is intended as the parent for all simple plugins.
- */
-public abstract class AbstractPlugin implements SecurityPlugin
-{
- private final Logger _logger = Logger.getLogger(getClass());
-
- private ConfigurationPlugin _config;
-
- public Result getDefault()
- {
- return Result.ABSTAIN;
- }
-
- public abstract Result access(ObjectType object, Object instance);
-
- public abstract Result authorise(Operation operation, ObjectType object, ObjectProperties properties);
-
- public void configure(ConfigurationPlugin config)
- {
- _config = config;
- }
-
- public ConfigurationPlugin getConfig()
- {
- return _config;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
deleted file mode 100644
index 236931e8cd..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
+++ /dev/null
@@ -1,122 +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;
-
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-
-/**
- * This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}.
- *
- */
-public abstract class AbstractProxyPlugin extends AbstractPlugin
-{
- public Result authoriseConsume(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authorisePublish(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseCreate(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseAccess(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseBind(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseUnbind(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseDelete(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authorisePurge(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result authoriseUpdate(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
- public Result accessVirtualhost(Object instance)
- {
- return getDefault();
- }
-
- @Override
- public Result access(ObjectType objectType, Object instance)
- {
- switch (objectType)
- {
- case VIRTUALHOST:
- return accessVirtualhost(instance);
- }
-
- return getDefault();
- }
-
- @Override
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- switch (operation)
- {
- case CONSUME:
- return authoriseConsume(objectType, properties);
- case PUBLISH:
- return authorisePublish(objectType, properties);
- case CREATE:
- return authoriseCreate(objectType, properties);
- case ACCESS:
- return authoriseAccess(objectType, properties);
- case BIND:
- return authoriseBind(objectType, properties);
- case UNBIND:
- return authoriseUnbind(objectType, properties);
- case DELETE:
- return authoriseDelete(objectType, properties);
- case PURGE:
- return authorisePurge(objectType, properties);
- case UPDATE:
- return authoriseUpdate(objectType, properties);
- }
-
- return getDefault();
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java
index c3c06bf206..b4831f83e5 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java
@@ -18,28 +18,26 @@
*/
package org.apache.qpid.server.security;
-import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
/**
- * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)},
- * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made
- * by this plugin.
+ * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)},
+ * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made.
*/
-public interface SecurityPlugin extends Plugin
-{
+public interface AccessControl
+{
/**
* Default result for {@link #access(ObjectType, Object)} or {@link #authorise(Operation, ObjectType, ObjectProperties)}.
*/
Result getDefault();
-
+
/**
* Authorise access granted to an object instance.
*/
Result access(ObjectType objectType, Object instance);
-
+
/**
* Authorise an operation on an object defined by a set of properties.
*/
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
index 8f3bdf7738..8243fc3f75 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
@@ -24,14 +24,14 @@ import javax.security.auth.Subject;
import java.security.Principal;
/**
- * Represents the authorization of the logged on user.
- *
+ * Represents the authorization of the logged on user.
+ *
*/
public interface AuthorizationHolder
{
- /**
+ /**
* Returns the {@link Subject} of the authorized user. This is guaranteed to
- * contain at least one {@link org.apache.qpid.server.security.auth.sasl.UsernamePrincipal}, representing the the identity
+ * contain at least one {@link org.apache.qpid.server.security.auth.UsernamePrincipal}, representing the the identity
* used when the user logged on to the application, and zero or more {@link org.apache.qpid.server.security.auth.sasl.GroupPrincipal}
* representing the group(s) to which the user belongs.
*
@@ -39,10 +39,10 @@ public interface AuthorizationHolder
*/
Subject getAuthorizedSubject();
- /**
+ /**
* Returns the {@link Principal} representing the the identity
* used when the user logged on to the application.
- *
+ *
* @return a Principal
*/
Principal getAuthorizedPrincipal();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index 436660cfaf..1a1cce171b 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -18,22 +18,23 @@
*/
package org.apache.qpid.server.security;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.plugins.PluginManager;
+
+import org.apache.qpid.server.plugin.AccessControlFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE;
+import static org.apache.qpid.server.security.access.ObjectType.GROUP;
import static org.apache.qpid.server.security.access.ObjectType.METHOD;
import static org.apache.qpid.server.security.access.ObjectType.QUEUE;
+import static org.apache.qpid.server.security.access.ObjectType.USER;
import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST;
import static org.apache.qpid.server.security.access.Operation.BIND;
import static org.apache.qpid.server.security.access.Operation.CONSUME;
@@ -45,103 +46,105 @@ import static org.apache.qpid.server.security.access.Operation.UNBIND;
import javax.security.auth.Subject;
import java.net.SocketAddress;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
/**
- * The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based
+ * The security manager contains references to all loaded {@link AccessControl}s and delegates security decisions to them based
* on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal
* objects for simpler plugins.
- *
- * @see SecurityPlugin
+ *
+ * @see AccessControl
*/
public class SecurityManager
{
private static final Logger _logger = Logger.getLogger(SecurityManager.class);
-
+
/** Container for the {@link java.security.Principal} that is using to this thread. */
private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>();
- private static final ThreadLocal<Boolean> _accessChecksDisabled = new ThreadLocal<Boolean>()
+
+ public static final ThreadLocal<Boolean> _accessChecksDisabled = new ClearingThreadLocal(false);
+
+ private Map<String, AccessControl> _globalPlugins = new HashMap<String, AccessControl>();
+ private Map<String, AccessControl> _hostPlugins = new HashMap<String, AccessControl>();
+
+ /**
+ * A special ThreadLocal, which calls remove() on itself whenever the value is
+ * the default, to avoid leaving a default value set after its use has passed.
+ */
+ private static final class ClearingThreadLocal extends ThreadLocal<Boolean>
{
- protected Boolean initialValue()
+ private Boolean _defaultValue;
+
+ public ClearingThreadLocal(Boolean defaultValue)
{
- return false;
+ super();
+ _defaultValue = defaultValue;
}
- };
- private PluginManager _pluginManager;
- private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>();
- private Map<String, SecurityPlugin> _globalPlugins = new HashMap<String, SecurityPlugin>();
- private Map<String, SecurityPlugin> _hostPlugins = new HashMap<String, SecurityPlugin>();
+ @Override
+ protected Boolean initialValue()
+ {
+ return _defaultValue;
+ }
- public static class SecurityConfiguration extends ConfigurationPlugin
- {
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ @Override
+ public void set(Boolean value)
{
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ if (value == _defaultValue)
{
- ConfigurationPlugin instance = new SecurityConfiguration();
- instance.setConfiguration(path, config);
- return instance;
+ super.remove();
}
-
- public List<String> getParentPaths()
+ else
{
- return Arrays.asList("security", "virtualhosts.virtualhost.security");
+ super.set(value);
}
- };
-
- @Override
- public String[] getElementsProcessed()
- {
- return new String[]{"security"};
}
- public void validateConfiguration() throws ConfigurationException
+ @Override
+ public Boolean get()
{
- if (getConfig().isEmpty())
+ Boolean value = super.get();
+ if (value == _defaultValue)
{
- throw new ConfigurationException("security section is incomplete, no elements found.");
+ super.remove();
}
+ return value;
}
}
-
- public SecurityManager(SecurityManager parent) throws ConfigurationException
+ /*
+ * Used by the VirtualHost to allow deferring to the broker level security plugins if required.
+ */
+ public SecurityManager(SecurityManager parent, String aclFile)
{
- _pluginManager = parent._pluginManager;
- _pluginFactories = parent._pluginFactories;
-
+ this(aclFile);
+
// our global plugins are the parent's host plugins
_globalPlugins = parent._hostPlugins;
}
- public SecurityManager(ConfigurationPlugin configuration, PluginManager manager) throws ConfigurationException
+ public SecurityManager(String aclFile)
{
- this(configuration, manager, null);
- }
-
- public SecurityManager(ConfigurationPlugin configuration, PluginManager manager, SecurityPluginFactory plugin) throws ConfigurationException
- {
- _pluginManager = manager;
- if (manager == null) // No plugin manager, no plugins
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put("aclFile", aclFile);
+ for (AccessControlFactory provider : (new QpidServiceLoader<AccessControlFactory>()).instancesOf(AccessControlFactory.class))
{
- return;
+ AccessControl accessControl = provider.createInstance(attributes);
+ if(accessControl != null)
+ {
+ addHostPlugin(accessControl);
+ }
}
- _pluginFactories = _pluginManager.getSecurityPlugins();
- if (plugin != null)
+ if(_logger.isDebugEnabled())
{
- _pluginFactories.put(plugin.getPluginName(), plugin);
+ _logger.debug("Configured " + _hostPlugins.size() + " access control plugins");
}
-
- configureHostPlugins(configuration);
}
public static Subject getThreadSubject()
@@ -154,41 +157,6 @@ public class SecurityManager
_subject.set(subject);
}
- public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
- {
- _hostPlugins = configurePlugins(hostConfig);
- }
-
- public void configureGlobalPlugins(ConfigurationPlugin configuration) throws ConfigurationException
- {
- _globalPlugins = configurePlugins(configuration);
- }
-
- public Map<String, SecurityPlugin> configurePlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
- {
- Map<String, SecurityPlugin> plugins = new HashMap<String, SecurityPlugin>();
- SecurityConfiguration securityConfig = hostConfig.getConfiguration(SecurityConfiguration.class.getName());
-
- // If we have no security Configuration then there is nothing to configure.
- if (securityConfig != null)
- {
- for (SecurityPluginFactory<?> factory : _pluginFactories.values())
- {
- SecurityPlugin plugin = factory.newInstance(securityConfig);
- if (plugin != null)
- {
- plugins.put(factory.getPluginName(), plugin);
- }
- }
- }
- return plugins;
- }
-
- public void addHostPlugin(SecurityPlugin plugin)
- {
- _hostPlugins.put(plugin.getClass().getName(), plugin);
- }
-
public static Logger getLogger()
{
return _logger;
@@ -205,7 +173,7 @@ public class SecurityManager
private abstract class AccessCheck
{
- abstract Result allowed(SecurityPlugin plugin);
+ abstract Result allowed(AccessControl plugin);
}
private boolean checkAllPlugins(AccessCheck checker)
@@ -215,16 +183,16 @@ public class SecurityManager
return true;
}
- Map<String, SecurityPlugin> remainingPlugins = _globalPlugins.isEmpty()
- ? Collections.<String, SecurityPlugin>emptyMap()
- : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, SecurityPlugin>(_globalPlugins);
-
- if(!_hostPlugins.isEmpty())
+ Map<String, AccessControl> remainingPlugins = _globalPlugins.isEmpty()
+ ? Collections.<String, AccessControl>emptyMap()
+ : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, AccessControl>(_globalPlugins);
+
+ if(!_hostPlugins.isEmpty())
{
- for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet())
+ for (Entry<String, AccessControl> hostEntry : _hostPlugins.entrySet())
{
// Create set of global only plugins
- SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey());
+ AccessControl globalPlugin = remainingPlugins.get(hostEntry.getKey());
if (globalPlugin != null)
{
remainingPlugins.remove(hostEntry.getKey());
@@ -272,7 +240,7 @@ public class SecurityManager
}
}
- for (SecurityPlugin plugin : remainingPlugins.values())
+ for (AccessControl plugin : remainingPlugins.values())
{
Result remaining = checker.allowed(plugin);
if (remaining == Result.DEFER)
@@ -284,16 +252,16 @@ public class SecurityManager
return false;
}
}
-
+
// getting here means either allowed or abstained from all plugins
return true;
}
-
+
public boolean authoriseBind(final Exchange exch, final AMQQueue queue, final AMQShortString routingKey)
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(BIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey));
}
@@ -304,7 +272,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
ObjectProperties properties = new ObjectProperties();
properties.setName(methodName);
@@ -318,11 +286,22 @@ public class SecurityManager
});
}
+ public boolean accessManagement()
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(AccessControl plugin)
+ {
+ return plugin.access(ObjectType.MANAGEMENT, null);
+ }
+ });
+ }
+
public boolean accessVirtualhost(final String vhostname, final SocketAddress remoteAddress)
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.access(VIRTUALHOST, remoteAddress);
}
@@ -333,7 +312,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(CONSUME, QUEUE, new ObjectProperties(queue));
}
@@ -345,7 +324,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(CREATE, EXCHANGE, new ObjectProperties(autoDelete, durable, exchangeName,
internal, nowait, passive, exchangeType));
@@ -358,7 +337,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(CREATE, QUEUE, new ObjectProperties(autoDelete, durable, exclusive, nowait, passive, queueName, owner));
}
@@ -369,7 +348,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(DELETE, QUEUE, new ObjectProperties(queue));
}
@@ -380,13 +359,34 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(DELETE, EXCHANGE, new ObjectProperties(exchange.getName()));
}
});
}
+ public boolean authoriseGroupOperation(final Operation operation, final String groupName)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(AccessControl plugin)
+ {
+ return plugin.authorise(operation, GROUP, new ObjectProperties(groupName));
+ }
+ });
+ }
+
+ public boolean authoriseUserOperation(final Operation operation, final String userName)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(AccessControl plugin)
+ {
+ return plugin.authorise(operation, USER, new ObjectProperties(userName));
+ }
+ });
+ }
private ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> _immediatePublishPropsCache
= new ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>>();
@@ -428,7 +428,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(PURGE, QUEUE, new ObjectProperties(queue));
}
@@ -439,7 +439,7 @@ public class SecurityManager
{
return checkAllPlugins(new AccessCheck()
{
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(UNBIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey));
}
@@ -465,9 +465,16 @@ public class SecurityManager
_props = props;
}
- Result allowed(SecurityPlugin plugin)
+ Result allowed(AccessControl plugin)
{
return plugin.authorise(PUBLISH, EXCHANGE, _props);
}
}
+
+
+ public void addHostPlugin(AccessControl plugin)
+ {
+ _hostPlugins.put(plugin.getClass().getName(), plugin);
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
deleted file mode 100644
index 21c2d1cda5..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
+++ /dev/null
@@ -1,75 +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;
-
-import org.apache.log4j.Logger;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-
-/**
- * An OSGi {@link BundleActivator} that loads a {@link SecurityPluginFactory}.
- */
-public abstract class SecurityPluginActivator implements BundleActivator
-{
- private static final Logger _logger = Logger.getLogger(SecurityPluginActivator.class);
-
- private SecurityPluginFactory _factory;
- private ConfigurationPluginFactory _config;
- private BundleContext _ctx;
- private String _bundleName;
-
- /** Implement this to return the factory this plugin activates. */
- public abstract SecurityPluginFactory getFactory();
-
- /** Implement this to return the factory this plugin activates. */
- public abstract ConfigurationPluginFactory getConfigurationFactory();
-
- /**
- * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
- */
- public void start(BundleContext ctx) throws Exception
- {
- _ctx = ctx;
- _factory = getFactory();
- _config = getConfigurationFactory();
- _bundleName = ctx.getBundle().getSymbolicName();
-
- // register the service
- _logger.info("Registering security plugin: " + _bundleName);
- _ctx.registerService(SecurityPluginFactory.class.getName(), _factory, null);
- _ctx.registerService(ConfigurationPluginFactory.class.getName(), _config, null);
- }
-
- /**
- * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
- */
- public void stop(BundleContext context) throws Exception
- {
- _logger.info("Stopping security plugin: " + _bundleName);
-
- // null object references
- _factory = null;
- _config = null;
- _ctx = null;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
new file mode 100644
index 0000000000..8138745486
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
@@ -0,0 +1,137 @@
+/*
+ *
+ * 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;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+
+/**
+ * Creates a {@link Subject} formed by the {@link Principal}'s returned from:
+ * <ol>
+ * <li>Authenticating using an {@link AuthenticationManager}</li>
+ * <li>A {@link GroupPrincipalAccessor}</li>
+ * </ol>
+ *
+ * <p>
+ * SubjectCreator is a facade to the {@link AuthenticationManager}, and is intended to be
+ * the single place that {@link Subject}'s are created in the broker.
+ * </p>
+ */
+public class SubjectCreator
+{
+ private AuthenticationManager _authenticationManager;
+ private GroupPrincipalAccessor _groupAccessor;
+
+ public SubjectCreator(AuthenticationManager authenticationManager, GroupPrincipalAccessor groupAccessor)
+ {
+ _authenticationManager = authenticationManager;
+ _groupAccessor = groupAccessor;
+ }
+
+ /**
+ * Gets the known SASL mechanisms
+ *
+ * @return SASL mechanism names, space separated.
+ */
+ public String getMechanisms()
+ {
+ return _authenticationManager.getMechanisms();
+ }
+
+ /**
+ * @see AuthenticationManager#createSaslServer(String, String, Principal)
+ */
+ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
+ {
+ return _authenticationManager.createSaslServer(mechanism, localFQDN, externalPrincipal);
+ }
+
+ /**
+ * Authenticates a user using SASL negotiation.
+ *
+ * @param server SASL server
+ * @param response SASL response to process
+ */
+ public SubjectAuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ AuthenticationResult authenticationResult = _authenticationManager.authenticate(server, response);
+ if(server.isComplete())
+ {
+ String username = server.getAuthorizationID();
+
+ return createResultWithGroups(username, authenticationResult);
+ }
+ else
+ {
+ return new SubjectAuthenticationResult(authenticationResult);
+ }
+ }
+
+ /**
+ * Authenticates a user using their username and password.
+ */
+ public SubjectAuthenticationResult authenticate(String username, String password)
+ {
+ final AuthenticationResult authenticationResult = _authenticationManager.authenticate(username, password);
+
+ return createResultWithGroups(username, authenticationResult);
+ }
+
+ private SubjectAuthenticationResult createResultWithGroups(String username, final AuthenticationResult authenticationResult)
+ {
+ if(authenticationResult.getStatus() == AuthenticationStatus.SUCCESS)
+ {
+ final Subject authenticationSubject = new Subject();
+
+ authenticationSubject.getPrincipals().addAll(authenticationResult.getPrincipals());
+ authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username));
+
+ authenticationSubject.setReadOnly();
+
+ return new SubjectAuthenticationResult(authenticationResult, authenticationSubject);
+ }
+ else
+ {
+ return new SubjectAuthenticationResult(authenticationResult);
+ }
+ }
+
+ public Subject createSubjectWithGroups(String username)
+ {
+ Subject authenticationSubject = new Subject();
+
+ authenticationSubject.getPrincipals().add(new AuthenticatedPrincipal(username));
+ authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username));
+ authenticationSubject.setReadOnly();
+
+ return authenticationSubject;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index a9ec4d1647..8e38681e68 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -18,33 +18,31 @@
*/
package org.apache.qpid.server.security.access;
-import org.apache.commons.lang.StringUtils;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
-
import java.util.ArrayList;
import java.util.EnumMap;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+
/**
* An set of properties for an access control v2 rule {@link ObjectType}.
- *
+ *
* The {@link #matches(ObjectProperties)} method is intended to be used when determining precedence of rules, and
* {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching
* described above.
*/
public class ObjectProperties
{
- /** serialVersionUID */
- private static final long serialVersionUID = -1356019341374170495L;
-
public static final String STAR= "*";
public static final ObjectProperties EMPTY = new ObjectProperties();
-
+
public enum Property
{
ROUTING_KEY,
@@ -65,81 +63,89 @@ public class ObjectProperties
AUTO_DELETE,
COMPONENT,
PACKAGE,
- CLASS;
-
- public static Property parse(String text)
+ CLASS,
+ FROM_NETWORK,
+ FROM_HOSTNAME;
+
+ private static final Map<String, Property> _canonicalNameToPropertyMap = new HashMap<String, ObjectProperties.Property>();
+
+ static
{
for (Property property : values())
{
- if (property.getName().equalsIgnoreCase(text))
- {
- return property;
- }
+ _canonicalNameToPropertyMap.put(getCanonicalName(property.name()), property);
+ }
+ }
+
+ /**
+ * Properties are parsed using their canonical name (see {@link #getCanonicalName(String)})
+ * so that, for the sake of user-friendliness, the ACL file parses is insensitive to
+ * case and underscores.
+ */
+ public static Property parse(String text)
+ {
+ String propertyName = getCanonicalName(text);
+ Property property = _canonicalNameToPropertyMap.get(propertyName);
+
+ if(property == null)
+ {
+ throw new IllegalArgumentException("Not a valid property: " + text
+ + " because " + propertyName
+ + " is not in " + _canonicalNameToPropertyMap.keySet());
+ }
+ else
+ {
+ return property;
}
- throw new IllegalArgumentException("Not a valid property: " + text);
}
-
- public String getName()
+
+ private static String getCanonicalName(String name)
{
- return StringUtils.remove(name(), '_').toLowerCase();
+ return StringUtils.remove(name, '_').toLowerCase();
}
-
- public static List<String> getPropertyNames()
- {
- List<String> properties = new ArrayList<String>();
- for (Property property : values())
- {
- properties.add(property.getName());
- }
- return properties;
- }
}
private final EnumMap<Property, String> _properties = new EnumMap<Property, String>(Property.class);
- public static List<String> getAllPropertyNames()
+ public static List<String> getAllPropertyNames()
{
- List<String> properties = new ArrayList<String>();
- for (Property property : Property.values())
- {
- properties.add(StringUtils.remove(property.name(), '_').toLowerCase());
- }
- return properties;
- }
-
+ List<String> properties = new ArrayList<String>();
+ for (Property property : Property.values())
+ {
+ properties.add(StringUtils.remove(property.name(), '_').toLowerCase());
+ }
+ return properties;
+ }
+
public ObjectProperties()
{
- super();
}
-
+
+ public ObjectProperties(Property property, String value)
+ {
+ _properties.put(property, value);
+ }
+
public ObjectProperties(ObjectProperties copy)
{
- super();
-
_properties.putAll(copy._properties);
}
-
+
public ObjectProperties(String name)
{
- super();
-
setName(name);
}
-
+
public ObjectProperties(AMQShortString name)
{
- super();
-
setName(name);
}
-
+
public ObjectProperties(AMQQueue queue)
{
- super();
-
setName(queue.getName());
-
+
put(Property.AUTO_DELETE, queue.isAutoDelete());
put(Property.TEMPORARY, queue.isAutoDelete());
put(Property.DURABLE, queue.isDurable());
@@ -157,45 +163,45 @@ public class ObjectProperties
put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName());
}
}
-
+
public ObjectProperties(Exchange exch, AMQQueue queue, AMQShortString routingKey)
{
this(queue);
-
- setName(exch.getName());
-
+
+ setName(exch.getName());
+
put(Property.QUEUE_NAME, queue.getName());
put(Property.ROUTING_KEY, routingKey);
}
-
+
public ObjectProperties(Exchange exch, AMQShortString routingKey)
{
this(exch.getName(), routingKey.asString());
}
-
+
public ObjectProperties(String exchangeName, String routingKey, Boolean immediate)
{
this(exchangeName, routingKey);
-
+
put(Property.IMMEDIATE, immediate);
}
-
+
public ObjectProperties(String exchangeName, String routingKey)
{
super();
-
+
setName(exchangeName);
-
+
put(Property.ROUTING_KEY, routingKey);
}
-
+
public ObjectProperties(Boolean autoDelete, Boolean durable, AMQShortString exchangeName,
Boolean internal, Boolean nowait, Boolean passive, AMQShortString exchangeType)
{
super();
-
+
setName(exchangeName);
-
+
put(Property.AUTO_DELETE, autoDelete);
put(Property.TEMPORARY, autoDelete);
put(Property.DURABLE, durable);
@@ -204,14 +210,14 @@ public class ObjectProperties
put(Property.PASSIVE, passive);
put(Property.TYPE, exchangeType);
}
-
+
public ObjectProperties(Boolean autoDelete, Boolean durable, Boolean exclusive, Boolean nowait, Boolean passive,
AMQShortString queueName, String owner)
{
super();
-
+
setName(queueName);
-
+
put(Property.AUTO_DELETE, autoDelete);
put(Property.TEMPORARY, autoDelete);
put(Property.DURABLE, durable);
@@ -220,7 +226,7 @@ public class ObjectProperties
put(Property.PASSIVE, passive);
put(Property.OWNER, owner);
}
-
+
public ObjectProperties(Boolean exclusive, Boolean noAck, Boolean noLocal, Boolean nowait, AMQQueue queue)
{
this(queue);
@@ -230,17 +236,7 @@ public class ObjectProperties
put(Property.EXCLUSIVE, exclusive);
put(Property.NO_WAIT, nowait);
}
-
- public List<String> getPropertyNames()
- {
- List<String> properties = new ArrayList<String>();
- for (Property property : _properties.keySet())
- {
- properties.add(property.getName());
- }
- return properties;
- }
-
+
public Boolean isSet(Property key)
{
return _properties.containsKey(key) && Boolean.valueOf(_properties.get(key));
@@ -255,17 +251,17 @@ public class ObjectProperties
{
return _properties.get(Property.NAME);
}
-
+
public void setName(String name)
{
_properties.put(Property.NAME, name);
}
-
+
public void setName(AMQShortString name)
{
put(Property.NAME, name);
}
-
+
public String put(Property key, AMQShortString value)
{
return put(key, value == null ? "" : value.asString());
@@ -275,7 +271,7 @@ public class ObjectProperties
{
return _properties.put(key, value == null ? "" : value.trim());
}
-
+
public void put(Property key, Boolean value)
{
if (value != null)
@@ -283,66 +279,64 @@ public class ObjectProperties
_properties.put(key, Boolean.toString(value));
}
}
-
+
public boolean matches(ObjectProperties properties)
{
if (properties._properties.keySet().isEmpty())
{
return true;
}
-
+
if (!_properties.keySet().containsAll(properties._properties.keySet()))
{
return false;
}
-
+
for (Map.Entry<Property,String> entry : properties._properties.entrySet())
{
Property key = entry.getKey();
String ruleValue = entry.getValue();
-
+
String thisValue = _properties.get(key);
- if (!valueMatches(thisValue, ruleValue))
+ if (!valueMatches(thisValue, ruleValue))
{
return false;
}
}
-
+
return true;
}
-
+
private boolean valueMatches(String thisValue, String ruleValue)
{
return (StringUtils.isEmpty(ruleValue)
|| StringUtils.equals(thisValue, ruleValue))
|| ruleValue.equals(STAR)
- || (ruleValue.endsWith(STAR)
+ || (ruleValue.endsWith(STAR)
&& thisValue != null
&& thisValue.length() >= ruleValue.length() - 1
&& thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1)));
}
@Override
- public boolean equals(Object o)
+ public boolean equals(Object obj)
{
- if (this == o)
+ if (obj == null)
{
- return true;
+ return false;
}
- if (o == null || getClass() != o.getClass())
+ if (obj == this)
{
- return false;
+ return true;
}
-
- ObjectProperties that = (ObjectProperties) o;
-
- if (_properties != null ? !_properties.equals(that._properties) : that._properties != null)
+ if (obj.getClass() != getClass())
{
return false;
}
-
- return true;
+ ObjectProperties rhs = (ObjectProperties) obj;
+ return new EqualsBuilder()
+ .append(_properties, rhs._properties).isEquals();
}
@Override
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
index 90ecd1dd17..8bc4b9d278 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
@@ -41,12 +41,15 @@ public enum ObjectType
{
ALL(Operation.ALL),
VIRTUALHOST(Operation.ALL, ACCESS),
+ MANAGEMENT(Operation.ALL, ACCESS),
QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME),
EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH),
LINK, // Not allowed in the Java broker
ROUTE, // Not allowed in the Java broker
- METHOD(Operation.ALL, ACCESS, UPDATE);
-
+ METHOD(Operation.ALL, ACCESS, UPDATE),
+ USER(Operation.ALL, CREATE, DELETE, UPDATE),
+ GROUP(Operation.ALL, CREATE, DELETE, UPDATE);
+
private EnumSet<Operation> _actions;
private ObjectType()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
deleted file mode 100644
index 4df135a4ca..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
+++ /dev/null
@@ -1,43 +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.access.plugins;
-
-import org.apache.qpid.server.security.AbstractPlugin;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-
-/**
- * This {@link org.apache.qpid.server.security.SecurityPlugin} simply abstains from all authorisation requests and ignores configuration.
- */
-public abstract class BasicPlugin extends AbstractPlugin
-{
- public Result access(ObjectType objectType, Object instance)
- {
- return getDefault();
- }
-
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- return getDefault();
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
deleted file mode 100644
index 4b7a2fb457..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
+++ /dev/null
@@ -1,86 +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.access.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * The <code>LegacyAccess</code> plugin is used internally and simply ignores legacy elements of the configuration file.
- */
-public class LegacyAccess extends BasicPlugin
-{
- public static class LegacyAccessConfiguration extends ConfigurationPlugin {
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.msg-auth", "virtualhosts.virtualhost.security.msg-auth");
- }
-
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new LegacyAccessConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
- }
-
- public static final SecurityPluginFactory<LegacyAccess> FACTORY = new SecurityPluginFactory<LegacyAccess>()
- {
- public LegacyAccess newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- LegacyAccessConfiguration configuration = config.getConfiguration(LegacyAccessConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- LegacyAccess plugin = new LegacyAccess();
- plugin.configure(configuration);
- return plugin;
- }
-
- public String getPluginName()
- {
- return LegacyAccess.class.getName();
- }
-
- public Class<LegacyAccess> getPluginClass()
- {
- return LegacyAccess.class;
- }
- };
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java
new file mode 100644
index 0000000000..fb31132514
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java
@@ -0,0 +1,127 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+
+/**
+ * A simple Principal wrapper. Exists to allow us to identify the "primary" principal
+ * by calling {@link Subject#getPrincipals(Class)}, passing in {@link AuthenticatedPrincipal}.class,
+ * e.g. when logging.
+ */
+public final class AuthenticatedPrincipal implements Principal, Serializable
+{
+ private final Principal _wrappedPrincipal;
+
+ /** convenience constructor for the common case where we're wrapping a {@link UsernamePrincipal} */
+ public AuthenticatedPrincipal(String userPrincipalName)
+ {
+ this(new UsernamePrincipal(userPrincipalName));
+ }
+
+ public AuthenticatedPrincipal(Principal wrappedPrincipal)
+ {
+ if(wrappedPrincipal == null)
+ {
+ throw new IllegalArgumentException("Wrapped principal is null");
+ }
+
+ _wrappedPrincipal = wrappedPrincipal;
+ }
+
+ @Override
+ public String getName()
+ {
+ return _wrappedPrincipal.getName();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return _wrappedPrincipal.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (!(obj instanceof AuthenticatedPrincipal))
+ {
+ return false;
+ }
+
+ AuthenticatedPrincipal other = (AuthenticatedPrincipal) obj;
+
+ return _wrappedPrincipal.equals(other._wrappedPrincipal);
+ }
+
+ public static AuthenticatedPrincipal getOptionalAuthenticatedPrincipalFromSubject(final Subject authSubject)
+ {
+ return getAuthenticatedPrincipalFromSubject(authSubject, true);
+ }
+
+ public static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject)
+ {
+ return getAuthenticatedPrincipalFromSubject(authSubject, false);
+ }
+
+ private static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject, boolean isPrincipalOptional)
+ {
+ if (authSubject == null)
+ {
+ throw new IllegalArgumentException("No authenticated subject.");
+ }
+
+ final Set<AuthenticatedPrincipal> principals = authSubject.getPrincipals(AuthenticatedPrincipal.class);
+ int numberOfAuthenticatedPrincipals = principals.size();
+
+ if(numberOfAuthenticatedPrincipals == 0 && isPrincipalOptional)
+ {
+ return null;
+ }
+ else
+ {
+ if (numberOfAuthenticatedPrincipals != 1)
+ {
+ throw new IllegalArgumentException(
+ "Can't find single AuthenticatedPrincipal in authenticated subject. There were "
+ + numberOfAuthenticatedPrincipals
+ + " authenticated principals out of a total number of principals of: " + authSubject.getPrincipals());
+ }
+ return principals.iterator().next();
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return getName();
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 949c0f2b89..09bf6cf3b1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.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,15 +20,20 @@
*/
package org.apache.qpid.server.security.auth;
-import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
/**
- * Encapsulates the result of an attempt to authenticate.
+ * Encapsulates the result of an attempt to authenticate using an {@link AuthenticationManager}.
* <p>
* The authentication status describes the overall outcome.
* <p>
* <ol>
- * <li>If authentication status is SUCCESS, the subject will be populated.
+ * <li>If authentication status is SUCCESS, at least one {@link Principal} will be populated.
* </li>
* <li>If authentication status is CONTINUE, the authentication has failed because the user
* supplied incorrect credentials (etc). If the authentication requires it, the next challenge
@@ -40,6 +45,8 @@ import javax.security.auth.Subject;
* </li>
* </ol>
*
+ * The main principal provided to the constructor is wrapped in an {@link AuthenticatedPrincipal}
+ * to make it easier for the rest of the application to identify it among the set of other principals.
*/
public class AuthenticationResult
{
@@ -56,37 +63,59 @@ public class AuthenticationResult
private final AuthenticationStatus _status;
private final byte[] _challenge;
private final Exception _cause;
- private final Subject _subject;
+ private final Set<Principal> _principals = new HashSet<Principal>();
+ private final Principal _mainPrincipal;
public AuthenticationResult(final AuthenticationStatus status)
{
this(null, status, null);
}
+ public AuthenticationResult(Principal mainPrincipal)
+ {
+ this(mainPrincipal, Collections.<Principal>emptySet());
+ }
+
+ public AuthenticationResult(Principal mainPrincipal, Set<Principal> otherPrincipals)
+ {
+ AuthenticatedPrincipal specialQpidAuthenticatedPrincipal = new AuthenticatedPrincipal(mainPrincipal);
+ _principals.addAll(otherPrincipals);
+ _principals.remove(mainPrincipal);
+ _principals.add(specialQpidAuthenticatedPrincipal);
+ _mainPrincipal = mainPrincipal;
+
+ _status = AuthenticationStatus.SUCCESS;
+ _challenge = null;
+ _cause = null;
+ }
+
public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status)
{
- this(challenge, status, null);
+ _challenge = challenge;
+ _status = status;
+ _cause = null;
+ _mainPrincipal = null;
}
public AuthenticationResult(final AuthenticationStatus error, final Exception cause)
{
- this(null, error, cause);
+ _status = error;
+ _challenge = null;
+ _cause = cause;
+ _mainPrincipal = null;
}
public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause)
{
- this._status = status;
- this._challenge = challenge;
- this._cause = cause;
- this._subject = null;
- }
+ if(status == AuthenticationStatus.SUCCESS)
+ {
+ throw new IllegalArgumentException("Successful authentication requires at least one principal");
+ }
- public AuthenticationResult(final Subject subject)
- {
- this._status = AuthenticationStatus.SUCCESS;
- this._challenge = null;
- this._cause = null;
- this._subject = subject;
+ _status = status;
+ _challenge = challenge;
+ _cause = cause;
+ _mainPrincipal = null;
}
public Exception getCause()
@@ -104,9 +133,13 @@ public class AuthenticationResult
return _challenge;
}
- public Subject getSubject()
+ public Set<Principal> getPrincipals()
{
- return _subject;
+ return _principals;
}
+ public Principal getMainPrincipal()
+ {
+ return _mainPrincipal;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java
new file mode 100644
index 0000000000..3be96b87eb
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.SubjectCreator;
+
+/**
+ * Encapsulates the result of an attempt to authenticate using a {@link SubjectCreator}.
+ *
+ * <p>
+ * iff authentication was successful, {@link #getSubject()} will return a non-null value and
+ * {@link #getStatus()} will return {@link AuthenticationResult.AuthenticationStatus#SUCCESS}.
+ *
+ * In this case, the {@link Subject} will contain the user {@link Principal} and zero or more other principals
+ * representing groups.
+ * </p>
+ * @see SubjectCreator
+ */
+public class SubjectAuthenticationResult
+{
+ private final AuthenticationResult _authenticationResult;
+ private final Subject _subject;
+
+ public SubjectAuthenticationResult(AuthenticationResult authenticationResult, Subject subject)
+ {
+ _authenticationResult = authenticationResult;
+ _subject = subject;
+ }
+
+ public SubjectAuthenticationResult(AuthenticationResult unsuccessfulAuthenticationResult)
+ {
+ this(unsuccessfulAuthenticationResult, null);
+ }
+
+ public Exception getCause()
+ {
+ return _authenticationResult.getCause();
+ }
+
+ public AuthenticationResult.AuthenticationStatus getStatus()
+ {
+ return _authenticationResult.getStatus();
+ }
+
+ public byte[] getChallenge()
+ {
+ return _authenticationResult.getChallenge();
+ }
+
+ public Subject getSubject()
+ {
+ return _subject;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java
index 9e7db94216..5b3c1d59cf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,14 +18,13 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.auth;
-import javax.security.auth.Subject;
+import java.io.Serializable;
import java.security.Principal;
-import java.util.Set;
/** A principal that is just a wrapper for a simple username. */
-public class UsernamePrincipal implements Principal
+public class UsernamePrincipal implements Principal, Serializable
{
private final String _name;
@@ -48,9 +47,6 @@ public class UsernamePrincipal implements Principal
return _name;
}
- /**
- * @see java.lang.Object#hashCode()
- */
@Override
public int hashCode()
{
@@ -58,9 +54,6 @@ public class UsernamePrincipal implements Principal
return prime * _name.hashCode();
}
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
@Override
public boolean equals(Object obj)
{
@@ -81,19 +74,4 @@ public class UsernamePrincipal implements Principal
}
}
}
-
- public static UsernamePrincipal getUsernamePrincipalFromSubject(final Subject authSubject)
- {
- if (authSubject == null)
- {
- throw new IllegalArgumentException("No authenticated subject.");
- }
-
- final Set<UsernamePrincipal> principals = authSubject.getPrincipals(UsernamePrincipal.class);
- if (principals.size() != 1)
- {
- throw new IllegalArgumentException("Can't find single UsernamePrincipal in authenticated subject");
- }
- return principals.iterator().next();
- }
}
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 cac60a5283..578bb96efa 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
@@ -21,9 +21,9 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
index 67f4b7344a..605d2d019d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
@@ -32,6 +32,8 @@ import java.util.Map;
/** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */
public interface PrincipalDatabase
{
+ void setPasswordFile(String passwordFile) throws IOException;
+
/**
* Set the password for a given principal in the specified callback. This is used for certain SASL providers. The
* user database implementation should look up the password in any way it chooses and set it in the callback by
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
new file mode 100644
index 0000000000..ff21d63c87
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
@@ -0,0 +1,71 @@
+/*
+ * 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.util.Map;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+/**
+ * Factory for {@link PrincipalDatabaseAuthenticationManager} objects configured
+ * with either the Plain or Base64MD5 digest {@link PrincipalDatabase}
+ * implementation.
+ */
+public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements AuthenticationManagerFactory
+{
+ public static final String ATTRIBUTE_PATH = "path";
+
+ private static final Logger LOGGER = Logger.getLogger(AbstractPrincipalDatabaseAuthManagerFactory.class);
+
+ @Override
+ public AuthenticationManager createInstance(Map<String, Object> attributes)
+ {
+ if (attributes == null || !getType().equals(attributes.get(ATTRIBUTE_TYPE)))
+ {
+ return null;
+ }
+
+ String passwordFile = (String) attributes.get(ATTRIBUTE_PATH);
+ if (passwordFile == null)
+ {
+ LOGGER.warn("Password file path must not be null");
+ return null;
+ }
+
+ PrincipalDatabase principalDatabase = createPrincipalDatabase();
+ try
+ {
+ principalDatabase.setPasswordFile(passwordFile);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ return new PrincipalDatabaseAuthenticationManager(principalDatabase);
+ }
+
+ abstract String getType();
+
+ abstract PrincipalDatabase createPrincipalDatabase();
+}
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
index 5676c43754..dd4c2e717a 100644
--- 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
@@ -21,31 +21,25 @@
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.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 String ANONYMOUS_USERNAME = "ANONYMOUS";
+
+ public static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal(ANONYMOUS_USERNAME);
public static final Subject ANONYMOUS_SUBJECT = new Subject();
static
@@ -53,76 +47,11 @@ public class AnonymousAuthenticationManager implements AuthenticationManager
ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL);
}
- private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_SUBJECT);
-
-
- private static CallbackHandler _callbackHandler = SASL_INITIALISER.getCallbackHandler();
+ private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_PRINCIPAL);
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()
+ AnonymousAuthenticationManager()
{
}
@@ -184,9 +113,4 @@ public class AnonymousAuthenticationManager implements AuthenticationManager
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/AnonymousAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..1b1995500c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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.util.Map;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+
+public class AnonymousAuthenticationManagerFactory implements AuthenticationManagerFactory
+{
+ public static final String PROVIDER_TYPE = AnonymousAuthenticationManager.class.getSimpleName();
+
+ @Override
+ public AuthenticationManager createInstance(Map<String, Object> attributes)
+ {
+ if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
+ {
+ return new AnonymousAuthenticationManager();
+ }
+ return null;
+ }
+
+}
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 ccddcb7669..c1a694f148 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
@@ -24,22 +24,22 @@ 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;
/**
* 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>
+ * If the authentication is successful, the manager is responsible for producing an
+ * {@link AuthenticationResult} containing the user's main {@link Principal} and zero or
+ * more other implementation-specific principals.
+ * </p>
* <p>
* The {@link #initialise()} method is responsible for registering SASL mechanisms required by
* the manager. The {@link #close()} method must reverse this registration.
- *
+ * </p>
*/
-public interface AuthenticationManager extends Closeable, Plugin
+public interface AuthenticationManager extends Closeable
{
/** The name for the required SASL Server mechanisms */
public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
@@ -88,5 +88,4 @@ public interface AuthenticationManager extends Closeable, Plugin
* @return authentication result
*/
AuthenticationResult authenticate(String username, String password);
-
}
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
deleted file mode 100644
index 89a4d8ae66..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java
+++ /dev/null
@@ -1,203 +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.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/Base64MD5PasswordFileAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..c61567ef77
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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 org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory
+{
+ public static final String PROVIDER_TYPE = "Base64MD5PasswordFileAuthenticationProvider";
+
+ @Override
+ String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ PrincipalDatabase createPrincipalDatabase()
+ {
+ return new Base64MD5PasswordFilePrincipalDatabase();
+ }
+
+}
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
index 2d6866b657..9ed8cf7fed 100644
--- 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
@@ -19,90 +19,19 @@
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.UsernamePrincipal;
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()
+ ExternalAuthenticationManager()
{
}
@@ -137,15 +66,13 @@ public class ExternalAuthenticationManager implements AuthenticationManager
// Process response from the client
try
{
- byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+ 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);
+ return new AuthenticationResult(principal);
}
else
{
@@ -162,16 +89,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager
@Override
public AuthenticationResult authenticate(String username, String password)
{
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ return new AuthenticationResult(new UsernamePrincipal(username));
}
@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/ExternalAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..3c3628e9db
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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.util.Map;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+
+public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory
+{
+ public static final String PROVIDER_TYPE = ExternalAuthenticationManager.class.getSimpleName();
+
+ @Override
+ public AuthenticationManager createInstance(Map<String, Object> attributes)
+ {
+ if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
+ {
+ return new ExternalAuthenticationManager();
+ }
+ return null;
+ }
+
+}
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
deleted file mode 100644
index 485ca2e1e9..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.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.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
index d735ecb1d4..3c1b709648 100644
--- 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
@@ -20,10 +20,7 @@ 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;
@@ -31,86 +28,15 @@ 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.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()
+ KerberosAuthenticationManager()
{
}
@@ -158,10 +84,7 @@ public class KerberosAuthenticationManager implements AuthenticationManager
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);
+ return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
}
else
{
@@ -186,11 +109,6 @@ public class KerberosAuthenticationManager implements AuthenticationManager
{
}
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
- {
- }
-
private static class GssApiCallbackHandler implements CallbackHandler
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..7af6727280
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util.Map;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+
+public class KerberosAuthenticationManagerFactory implements AuthenticationManagerFactory
+{
+ public static final String PROVIDER_TYPE = KerberosAuthenticationManager.class.getSimpleName();
+
+ @Override
+ public AuthenticationManager createInstance(Map<String, Object> attributes)
+ {
+ if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
+ {
+ return new KerberosAuthenticationManager();
+ }
+ return null;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..43b92735f1
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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 org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory
+{
+ public static final String PROVIDER_TYPE = "PlainPasswordFileAuthenticationProvider";
+
+ @Override
+ String getType()
+ {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ PrincipalDatabase createPrincipalDatabase()
+ {
+ return new PlainPasswordFilePrincipalDatabase();
+ }
+
+}
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 e6498919a1..f4c834810d 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
@@ -21,38 +21,25 @@
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;
-import org.apache.qpid.configuration.PropertyException;
-import org.apache.qpid.configuration.PropertyUtils;
-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.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
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;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
-import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+
import java.security.Security;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.TreeMap;
@@ -60,27 +47,10 @@ 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>
- * &lt;pd-auth-manager&gt;
- * &lt;principal-database&gt;
- * &lt;class&gt;org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase&lt;/class&gt;
- * &lt;attributes&gt;
- * &lt;attribute&gt;
- * &lt;name>passwordFile&lt;/name&gt;
- * &lt;value>${conf}/passwd&lt;/value&gt;
- * &lt;/attribute&gt;
- * &lt;/attributes&gt;
- * &lt;/principal-database&gt;
- * &lt;/pd-auth-manager&gt;
- * </pre>
*/
public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager
{
+
private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class);
/** The list of mechanisms, in the order in which they are configured (i.e. preferred order) */
@@ -95,95 +65,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
*/
private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
- private PrincipalDatabase _principalDatabase = null;
+ private final PrincipalDatabase _principalDatabase;
- public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>()
- {
- public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
- {
- 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)
- {
- _logger.info("No authentication-manager configuration found for PrincipalDatabaseAuthenticationManager");
- return null;
- }
-
- final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager();
- pdam.configure(configuration);
- pdam.initialise();
- return pdam;
- }
-
- public Class<PrincipalDatabaseAuthenticationManager> getPluginClass()
- {
- return PrincipalDatabaseAuthenticationManager.class;
- }
-
- public String getPluginName()
- {
- return PrincipalDatabaseAuthenticationManager.class.getName();
- }
- };
-
- public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin {
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.pd-auth-manager");
- }
-
- public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
- {
- final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration();
-
- instance.setConfiguration(path, config);
- return instance;
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] {"principal-database.class",
- "principal-database.attributes.attribute.name",
- "principal-database.attributes.attribute.value"};
- }
-
- 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 = (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++)
- {
- final String argName = argumentNames.get(i);
- final String argValue = argumentValues.get(i);
-
- attributes.put(argName, argValue);
- }
-
- return Collections.unmodifiableMap(attributes);
- }
- }
-
- protected PrincipalDatabaseAuthenticationManager()
+ public PrincipalDatabaseAuthenticationManager(PrincipalDatabase pd)
{
+ _principalDatabase = pd;
}
public void initialise()
@@ -246,21 +132,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
_logger.info("Initialised " + mechanism + " SASL provider successfully");
}
- /**
- * @see org.apache.qpid.server.plugins.Plugin#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin)
- */
- public void configure(final ConfigurationPlugin config) throws ConfigurationException
- {
- final PrincipalDatabaseAuthenticationManagerConfiguration pdamConfig = (PrincipalDatabaseAuthenticationManagerConfiguration) config;
- final String pdClazz = pdamConfig.getPrincipalDatabaseClass();
-
- _logger.info("PrincipalDatabase concrete implementation : " + pdClazz);
-
- _principalDatabase = createPrincipalDatabaseImpl(pdClazz);
-
- configPrincipalDatabase(_principalDatabase, pdamConfig);
- }
-
public String getMechanisms()
{
return _mechanisms;
@@ -268,8 +139,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
{
- return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
- _callbackHandlerMap.get(mechanism));
+ Map<String, ?> properties = _serverCreationProperties.get(mechanism);
+ CallbackHandler callbackHandler = _callbackHandlerMap.get(mechanism);
+
+ return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, properties,
+ callbackHandler);
}
/**
@@ -284,9 +158,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
if (server.isComplete())
{
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
- return new AuthenticationResult(subject);
+ final String userId = server.getAuthorizationID();
+ return new AuthenticationResult(new UsernamePrincipal(userId));
}
else
{
@@ -308,9 +181,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
if (_principalDatabase.verifyPassword(username, password.toCharArray()))
{
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(username));
- return new AuthenticationResult(subject);
+ return new AuthenticationResult(new UsernamePrincipal(username));
}
else
{
@@ -329,100 +200,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
Security.removeProvider(PROVIDER_NAME);
}
- private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException
- {
- try
- {
- return (PrincipalDatabase) Class.forName(pdClazz).newInstance();
- }
- catch (InstantiationException ie)
- {
- throw new ConfigurationException("Cannot instantiate " + pdClazz, ie);
- }
- catch (IllegalAccessException iae)
- {
- throw new ConfigurationException("Cannot access " + pdClazz, iae);
- }
- catch (ClassNotFoundException cnfe)
- {
- throw new ConfigurationException("Cannot load " + pdClazz + " implementation", cnfe);
- }
- catch (ClassCastException cce)
- {
- throw new ConfigurationException("Expecting a " + PrincipalDatabase.class + " implementation", cce);
- }
- }
-
- private void configPrincipalDatabase(final PrincipalDatabase principalDatabase, final PrincipalDatabaseAuthenticationManagerConfiguration config)
- throws ConfigurationException
- {
-
- final Map<String,String> attributes = config.getPdClassAttributeMap();
-
- for (Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator(); iterator.hasNext();)
- {
- final Entry<String, String> nameValuePair = iterator.next();
- final String methodName = generateSetterName(nameValuePair.getKey());
- final Method method;
- try
- {
- method = principalDatabase.getClass().getMethod(methodName, String.class);
- }
- catch (Exception e)
- {
- throw new ConfigurationException("No method " + methodName + " found in class "
- + principalDatabase.getClass()
- + " hence unable to configure principal database. The method must be public and "
- + "have a single String argument with a void return type", e);
- }
- try
- {
- method.invoke(principalDatabase, PropertyUtils.replaceProperties(nameValuePair.getValue()));
- }
- catch (IllegalArgumentException e)
- {
- throw new ConfigurationException(e.getMessage(), e);
- }
- catch (PropertyException e)
- {
- throw new ConfigurationException(e.getMessage(), e);
- }
- catch (IllegalAccessException e)
- {
- throw new ConfigurationException(e.getMessage(), e);
- }
- catch (InvocationTargetException e)
- {
- // QPID-1347.. InvocationTargetException wraps the checked exception thrown from the reflective
- // method call. Pull out the underlying message and cause to make these more apparent to the user.
- throw new ConfigurationException(e.getCause().getMessage(), e.getCause());
- }
- }
- }
-
public PrincipalDatabase getPrincipalDatabase()
{
return _principalDatabase;
}
-
- private String generateSetterName(String argName) throws ConfigurationException
- {
- if ((argName == null) || (argName.length() == 0))
- {
- throw new ConfigurationException("Argument names must have length >= 1 character");
- }
-
- if (Character.isLowerCase(argName.charAt(0)))
- {
- argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
- }
-
- final String methodName = "set" + argName;
- return methodName;
- }
-
- protected void setPrincipalDatabase(final PrincipalDatabase principalDatabase)
- {
- _principalDatabase = principalDatabase;
- }
}
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
index 64b24e28bc..7891ef8cf5 100644
--- 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
@@ -21,10 +21,10 @@ 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.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
@@ -32,7 +32,6 @@ 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;
@@ -41,13 +40,10 @@ 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.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
public class SimpleLDAPAuthenticationManager implements AuthenticationManager
@@ -55,123 +51,25 @@ 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 final String _providerSearchURL;
+ private final String _providerAuthURL;
+ private final String _searchContext;
+ private final String _searchFilter;
+ private final String _ldapContextFactory;
- private SimpleLDAPAuthenticationManager()
+ SimpleLDAPAuthenticationManager(String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory)
{
+ _providerSearchURL = providerSearchUrl;
+ _providerAuthURL = providerAuthUrl;
+ _searchContext = searchContext;
+ _searchFilter = searchFilter;
+ _ldapContextFactory = ldapContextFactory;
}
@Override
public void initialise()
{
-
+ validateInitialDirContext();
}
@Override
@@ -205,10 +103,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
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);
+ String authorizationID = server.getAuthorizationID();
+ _logger.debug("Authenticated as " + authorizationID);
+
+ return new AuthenticationResult(new UsernamePrincipal(authorizationID));
}
else
{
@@ -224,34 +122,74 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
@Override
public AuthenticationResult authenticate(String username, String password)
{
-
try
{
- return doLDAPNameAuthentication(getNameFromId(username), password);
+ AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password);
+ if(result.getStatus() == AuthenticationStatus.SUCCESS)
+ {
+ //Return a result based on the supplied username rather than the search name
+ return new AuthenticationResult(new UsernamePrincipal(username));
+ }
+ else
+ {
+ return result;
+ }
}
catch (NamingException e)
{
-
return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
-
}
}
- private AuthenticationResult doLDAPNameAuthentication(String username, String password) throws NamingException
+ private AuthenticationResult doLDAPNameAuthentication(String name, String password)
{
+ if(name == null)
+ {
+ //The search didn't return anything, class as not-authenticated before it NPEs below
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+
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_PRINCIPAL, name);
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);
+
+ DirContext ctx = null;
+ try
+ {
+ ctx = new InitialDirContext(env);
+
+ //Authentication succeeded
+ return new AuthenticationResult(new UsernamePrincipal(name));
+ }
+ catch(AuthenticationException ae)
+ {
+ //Authentication failed
+ return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ }
+ catch (NamingException e)
+ {
+ //Some other failure
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ }
+ finally
+ {
+ if(ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Exception closing InitialDirContext", e);
+ }
+ }
+ }
}
@Override
@@ -259,17 +197,8 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
{
}
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
+ private void validateInitialDirContext()
{
- 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);
@@ -277,11 +206,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
try
{
- new InitialDirContext(env);
+ new InitialDirContext(env).close();
}
catch (NamingException e)
{
- throw new ConfigurationException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e);
+ throw new RuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e);
}
}
@@ -305,19 +234,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
}
catch (NamingException e)
{
- _logger.info("SASL Authentication Error", e);
+ _logger.warn("SASL Authentication Exception", e);
}
if(password != null)
{
- try
- {
- authenticated = doLDAPNameAuthentication(name, password);
-
- }
- catch (NamingException e)
- {
- authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
- }
+ authenticated = doLDAPNameAuthentication(name, password);
}
}
else if (callback instanceof PlainPasswordCallback)
@@ -325,17 +246,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
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 = doLDAPNameAuthentication(name, password);
+ if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS)
{
- authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ ((PlainPasswordCallback)callback).setAuthenticated(true);
}
}
}
@@ -357,7 +271,6 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
env.put(Context.PROVIDER_URL, _providerSearchURL);
-
env.put(Context.SECURITY_AUTHENTICATION, "none");
DirContext ctx = null;
@@ -382,7 +295,14 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager
}
finally
{
- ctx.close();
+ try
+ {
+ ctx.close();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Exception closing InitialDirContext", e);
+ }
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
new file mode 100644
index 0000000000..05a692fb0e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
@@ -0,0 +1,69 @@
+/*
+ * 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.util.Map;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+
+public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationManagerFactory
+{
+ private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
+
+ public static final String PROVIDER_TYPE = SimpleLDAPAuthenticationManager.class.getSimpleName();
+
+ public static final String ATTRIBUTE_LDAP_CONTEXT_FACTORY = "ldapContextFactory";
+ public static final String ATTRIBUTE_SEARCH_FILTER = "searchFilter";
+ public static final String ATTRIBUTE_SEARCH_CONTEXT = "searchContext";
+ public static final String ATTRIBUTE_PROVIDER_AUTH_URL = "providerAuthUrl";
+ public static final String ATTRIBUTE_PROVIDER_SEARCH_URL = "providerSearchUrl";
+ public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl";
+
+ @Override
+ public AuthenticationManager createInstance(Map<String, Object> attributes)
+ {
+ if (attributes == null || !PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
+ {
+ return null;
+ }
+ String providerUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_URL);
+ String providerSearchUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_SEARCH_URL);
+ if (providerSearchUrl == null)
+ {
+ providerSearchUrl = providerUrl;
+ }
+ String providerAuthUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_AUTH_URL);
+ if (providerAuthUrl == null)
+ {
+ providerAuthUrl = providerUrl;
+ }
+ String searchContext = (String) attributes.get(ATTRIBUTE_SEARCH_CONTEXT);
+ String searchFilter = (String) attributes.get(ATTRIBUTE_SEARCH_FILTER);
+ String ldapContextFactory = (String) attributes.get(ATTRIBUTE_LDAP_CONTEXT_FACTORY);
+ if (ldapContextFactory == null)
+ {
+ ldapContextFactory = DEFAULT_LDAP_CONTEXT_FACTORY;
+ }
+
+ return new SimpleLDAPAuthenticationManager(providerSearchUrl, providerAuthUrl, searchContext, searchFilter,
+ ldapContextFactory);
+ }
+
+}
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 2e21cfbb07..abb8677e90 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
@@ -22,13 +22,13 @@ 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.model.Broker;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
public class RMIPasswordAuthenticator implements JMXAuthenticator
@@ -38,23 +38,33 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String SHOULD_HAVE_2_ELEMENTS = "User details should have 2 elements, username, password";
static final String SHOULD_BE_NON_NULL = "Supplied username and password should be non-null";
static final String INVALID_CREDENTIALS = "Invalid user details supplied";
+ static final String USER_NOT_AUTHORISED_FOR_MANAGEMENT = "User not authorised for management";
static final String CREDENTIALS_REQUIRED = "User details are required. " +
- "Please ensure you are using an up to date management console to connect.";
+ "Please ensure you are using an up to date management console to connect.";
- private AuthenticationManager _authenticationManager = null;
- private SocketAddress _socketAddress;
+ private final Broker _broker;
+ private final SocketAddress _address;
- public RMIPasswordAuthenticator(SocketAddress socketAddress)
+ public RMIPasswordAuthenticator(Broker broker, SocketAddress address)
{
- _socketAddress = socketAddress;
+ _broker = broker;
+ _address = address;
}
- public void setAuthenticationManager(final AuthenticationManager authenticationManager)
+ public Subject authenticate(Object credentials) throws SecurityException
{
- _authenticationManager = authenticationManager;
+ validateCredentials(credentials);
+
+ final String[] userCredentials = (String[]) credentials;
+ final String username = (String) userCredentials[0];
+ final String password = (String) userCredentials[1];
+
+ final Subject authenticatedSubject = doAuthentication(username, password);
+ doManagementAuthorisation(authenticatedSubject);
+ return authenticatedSubject;
}
- public Subject authenticate(Object credentials) throws SecurityException
+ private void validateCredentials(Object credentials)
{
// Verify that credential's are of type String[].
if (!(credentials instanceof String[]))
@@ -70,41 +80,27 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
// Verify that required number of credentials.
- final String[] userCredentials = (String[]) credentials;
- if (userCredentials.length != 2)
+ if (((String[])credentials).length != 2)
{
throw new SecurityException(SHOULD_HAVE_2_ELEMENTS);
}
+ }
- final String username = (String) userCredentials[0];
- final String password = (String) userCredentials[1];
-
+ private Subject doAuthentication(final String username, final String password)
+ {
// Verify that all required credentials are actually present.
if (username == null || password == null)
{
throw new SecurityException(SHOULD_BE_NON_NULL);
}
- // Verify that an AuthenticationManager has been set.
- if (_authenticationManager == null)
+ SubjectCreator subjectCreator = _broker.getSubjectCreator(_address);
+ if (subjectCreator == null)
{
- 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);
- }
+ throw new SecurityException("Can't get subject creator for " + _address);
}
- final AuthenticationResult result = _authenticationManager.authenticate(username, password);
+
+ final SubjectAuthenticationResult result = subjectCreator.authenticate(username, password);
if (AuthenticationStatus.ERROR.equals(result.getStatus()))
{
@@ -112,10 +108,7 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
else if (AuthenticationStatus.SUCCESS.equals(result.getStatus()))
{
- final Subject subject = result.getSubject();
- subject.getPrincipals().add(new JMXPrincipal(username));
- subject.setReadOnly();
- return subject;
+ return result.getSubject();
}
else
{
@@ -123,4 +116,21 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
}
+ private void doManagementAuthorisation(Subject authenticatedSubject)
+ {
+ SecurityManager.setThreadSubject(authenticatedSubject);
+ try
+ {
+ if (!_broker.getSecurityManager().accessManagement())
+ {
+ throw new SecurityException(USER_NOT_AUTHORISED_FOR_MANAGEMENT);
+ }
+ }
+ finally
+ {
+ SecurityManager.setThreadSubject(null);
+ }
+ }
+
+
} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
index f4e8f800c6..b70a987107 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.security.auth.sasl;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import javax.security.auth.callback.Callback;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
index 52d36023c2..d10193e743 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.security.auth.sasl.anonymous;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
+
public class AnonymousSaslServer implements SaslServer
{
@@ -52,7 +54,7 @@ public class AnonymousSaslServer implements SaslServer
public String getAuthorizationID()
{
- return null;
+ return AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL.getName();
}
public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
index 478f195530..4e12ac0750 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
@@ -139,6 +139,12 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser
{
_realPricipalDatabase.reload();
}
+
+ @Override
+ public void setPasswordFile(String passwordFile) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java
new file mode 100644
index 0000000000..c66e7fd4e4
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java
@@ -0,0 +1,287 @@
+/*
+ * 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.group;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+/**
+ * A group database that reads/writes the following file format:
+ *
+ * group1.users=user1,user2
+ * group2.users=user2,user3
+ */
+public class FileGroupDatabase implements GroupDatabase
+{
+ private static final Logger LOGGER = Logger.getLogger(FileGroupDatabase.class);
+
+ private Map<String, Set<String>> _groupToUserMap = new ConcurrentHashMap<String, Set<String>>();
+ private Map<String, Set<String>> _userToGroupMap = new ConcurrentHashMap<String, Set<String>>();
+ private String _groupFile;
+
+ @Override
+ public Set<String> getAllGroups()
+ {
+ return Collections.unmodifiableSet(_groupToUserMap.keySet());
+ }
+
+ public synchronized void setGroupFile(String groupFile) throws IOException
+ {
+ File file = new File(groupFile);
+
+ if (!file.canRead())
+ {
+ throw new FileNotFoundException(groupFile
+ + " cannot be found or is not readable");
+ }
+
+ readGroupFile(groupFile);
+ }
+
+ @Override
+ public Set<String> getUsersInGroup(String group)
+ {
+ if (group == null)
+ {
+ LOGGER.warn("Requested user set for null group. Returning empty set.");
+ return Collections.emptySet();
+ }
+
+ Set<String> set = _groupToUserMap.get(group);
+ if (set == null)
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ return Collections.unmodifiableSet(set);
+ }
+ }
+
+ @Override
+ public synchronized void addUserToGroup(String user, String group)
+ {
+ Set<String> users = _groupToUserMap.get(group);
+ if (users == null)
+ {
+ throw new IllegalArgumentException("Group " + group + " does not exist so could not add " + user + " to it");
+ }
+
+ users.add(user);
+
+ Set<String> groups = _userToGroupMap.get(user);
+ if (groups == null)
+ {
+ groups = new ConcurrentSkipListSet<String>();
+ _userToGroupMap.put(user, groups);
+ }
+ groups.add(group);
+
+ update();
+ }
+
+ @Override
+ public synchronized void removeUserFromGroup(String user, String group)
+ {
+ Set<String> users = _groupToUserMap.get(group);
+ if (users == null)
+ {
+ throw new IllegalArgumentException("Group " + group + " does not exist so could not remove " + user + " from it");
+ }
+
+ users.remove(user);
+
+ Set<String> groups = _userToGroupMap.get(user);
+ if (groups != null)
+ {
+ groups.remove(group);
+ }
+
+ update();
+ }
+
+ @Override
+ public Set<String> getGroupsForUser(String user)
+ {
+ if(user == null)
+ {
+ LOGGER.warn("Requested group set for null user. Returning empty set.");
+ return Collections.emptySet();
+ }
+
+ Set<String> groups = _userToGroupMap.get(user);
+ if (groups == null)
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ return Collections.unmodifiableSet(groups);
+ }
+ }
+
+ @Override
+ public synchronized void createGroup(String group)
+ {
+ Set<String> users = new ConcurrentSkipListSet<String>();
+ _groupToUserMap.put(group, users);
+
+ update();
+ }
+
+ @Override
+ public synchronized void removeGroup(String group)
+ {
+ _groupToUserMap.remove(group);
+ for (Set<String> groupsForUser : _userToGroupMap.values())
+ {
+ groupsForUser.remove(group);
+ }
+
+ update();
+ }
+
+ private synchronized void update()
+ {
+ if (_groupFile != null)
+ {
+ try
+ {
+ writeGroupFile(_groupFile);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Unable to persist change to file " + _groupFile);
+ }
+ }
+ }
+
+ private synchronized void readGroupFile(String groupFile) throws IOException
+ {
+ _groupFile = groupFile;
+ _groupToUserMap.clear();
+ _userToGroupMap.clear();
+ Properties propertiesFile = new Properties();
+ FileInputStream fileInputStream = new FileInputStream(groupFile);
+ try
+ {
+ propertiesFile.load(fileInputStream);
+ }
+ finally
+ {
+ if(fileInputStream != null)
+ {
+ fileInputStream.close();
+ }
+ }
+
+ for (String propertyName : propertiesFile.stringPropertyNames())
+ {
+ validatePropertyNameIsGroupName(propertyName);
+
+ String groupName = propertyName.replaceAll("\\.users$", "");
+ String userString = propertiesFile.getProperty(propertyName);
+
+ final Set<String> userSet = buildUserSetFromCommaSeparateValue(userString);
+
+ _groupToUserMap.put(groupName, userSet);
+
+ for (String userName : userSet)
+ {
+ Set<String> groupsForThisUser = _userToGroupMap.get(userName);
+
+ if (groupsForThisUser == null)
+ {
+ groupsForThisUser = new ConcurrentSkipListSet<String>();
+ _userToGroupMap.put(userName, groupsForThisUser);
+ }
+
+ groupsForThisUser.add(groupName);
+ }
+ }
+ }
+
+ private synchronized void writeGroupFile(String groupFile) throws IOException
+ {
+ Properties propertiesFile = new Properties();
+
+ for (String group : _groupToUserMap.keySet())
+ {
+ Set<String> users = _groupToUserMap.get(group);
+ String userList = StringUtils.join(users, ",");
+
+ propertiesFile.setProperty(group + ".users", userList);
+ }
+
+ String comment = "Written " + new Date();
+ FileOutputStream fileOutputStream = new FileOutputStream(groupFile);
+ try
+ {
+ propertiesFile.store(fileOutputStream, comment);
+ }
+ finally
+ {
+ if(fileOutputStream != null)
+ {
+ fileOutputStream.close();
+ }
+ }
+ }
+
+ private void validatePropertyNameIsGroupName(String propertyName)
+ {
+ if (!propertyName.endsWith(".users"))
+ {
+ throw new IllegalArgumentException(
+ "Invalid definition with name '"
+ + propertyName
+ + "'. Group definitions must end with suffix '.users'");
+ }
+ }
+
+ private ConcurrentSkipListSet<String> buildUserSetFromCommaSeparateValue(String userString)
+ {
+ String[] users = userString.split(",");
+ final ConcurrentSkipListSet<String> userSet = new ConcurrentSkipListSet<String>();
+ for (String user : users)
+ {
+ final String trimmed = user.trim();
+ if (!trimmed.isEmpty())
+ {
+ userSet.add(trimmed);
+ }
+ }
+ return userSet;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java
new file mode 100644
index 0000000000..8295f28f9e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java
@@ -0,0 +1,147 @@
+/*
+ * 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.group;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+
+/**
+ * Implementation of a group manager whose implementation is backed by a flat group file.
+ * <p>
+ * This plugin is configured in the following manner:
+ * </p>
+ * <pre>
+ * &lt;file-group-manager&gt;
+ * &lt;attributes&gt;
+ * &lt;attribute&gt;
+ * &lt;name>groupFile&lt;/name&gt;
+ * &lt;value>${conf}/groups&lt;/value&gt;
+ * &lt;/attribute&gt;
+ * &lt;/attributes&gt;
+ * &lt;/file-group-manager&gt;
+ * </pre>
+ */
+public class FileGroupManager implements GroupManager
+{
+ private final FileGroupDatabase _groupDatabase;
+
+
+ public FileGroupManager(String groupFile)
+ {
+ _groupDatabase = new FileGroupDatabase();
+ try
+ {
+ _groupDatabase.setGroupFile(groupFile);
+ }
+ catch (IOException e)
+ {
+ throw new IllegalConfigurationException("Unable to set group file " + groupFile, e);
+ }
+ }
+
+ @Override
+ public Set<Principal> getGroupPrincipalsForUser(String userId)
+ {
+ Set<String> groups = _groupDatabase.getGroupsForUser(userId);
+ if (groups.isEmpty())
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (String groupName : groups)
+ {
+ principals.add(new GroupPrincipal(groupName));
+ }
+ return principals;
+ }
+ }
+
+ @Override
+ public Set<Principal> getUserPrincipalsForGroup(String group)
+ {
+ Set<String> users = _groupDatabase.getUsersInGroup(group);
+ if (users.isEmpty())
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (String user : users)
+ {
+ principals.add(new UsernamePrincipal(user));
+ }
+ return principals;
+ }
+ }
+
+ @Override
+ public Set<Principal> getGroupPrincipals()
+ {
+ Set<String> groups = _groupDatabase.getAllGroups();
+ if (groups.isEmpty())
+ {
+ return Collections.emptySet();
+ }
+ else
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (String groupName : groups)
+ {
+ principals.add(new GroupPrincipal(groupName));
+ }
+ return principals;
+ }
+ }
+
+ @Override
+ public void createGroup(String group)
+ {
+ _groupDatabase.createGroup(group);
+ }
+
+ @Override
+ public void removeGroup(String group)
+ {
+ _groupDatabase.removeGroup(group);
+ }
+
+ @Override
+ public void addUserToGroup(String user, String group)
+ {
+ _groupDatabase.addUserToGroup(user, group);
+ }
+
+ @Override
+ public void removeUserFromGroup(String user, String group)
+ {
+ _groupDatabase.removeUserFromGroup(user, group);
+
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java
new file mode 100644
index 0000000000..5c4730a9c8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java
@@ -0,0 +1,51 @@
+/*
+ * 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.group;
+
+import static org.apache.qpid.server.util.MapValueConverter.getStringAttribute;
+
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.plugin.GroupManagerFactory;
+
+public class FileGroupManagerFactory implements GroupManagerFactory
+{
+ static final String FILE_GROUP_MANAGER_TYPE = "file-group-manager";
+ static final String FILE = "file";
+
+ @Override
+ public GroupManager createInstance(Map<String, Object> attributes)
+ {
+ if(!FILE_GROUP_MANAGER_TYPE.equals(getStringAttribute(GroupProvider.TYPE, attributes, null)))
+ {
+ return null;
+ }
+
+ String groupFile = getStringAttribute(FILE, attributes, null);
+ if (StringUtils.isBlank(groupFile))
+ {
+ throw new IllegalConfigurationException("Path to file containing groups is not specified!");
+ }
+ return new FileGroupManager(groupFile);
+ }
+
+}
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/security/group/GroupDatabase.java
index ff4e38d9f7..98c12782d8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -18,20 +17,18 @@
* under the License.
*
*/
+package org.apache.qpid.server.security.group;
-package org.apache.qpid.server.configuration;
-
-import java.util.UUID;
+import java.util.Set;
-public interface ConfiguredObject<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>>
+public interface GroupDatabase
{
- public UUID getQMFId();
-
- public T getConfigType();
-
- public ConfiguredObject<T,C> getParent();
-
- public boolean isDurable();
+ Set<String> getAllGroups();
+ Set<String> getUsersInGroup(String group);
- long getCreateTime();
+ void addUserToGroup(String user, String group);
+ void removeUserFromGroup(String user, String group);
+ Set<String> getGroupsForUser(String user);
+ void createGroup(String group);
+ void removeGroup(String group);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java
index 00ed5fd0dd..6d2df86919 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -18,31 +17,24 @@
* under the License.
*
*/
+package org.apache.qpid.server.security.group;
-package org.apache.qpid.server.configuration;
+import java.security.Principal;
+import java.util.Set;
-public interface BridgeConfig extends ConfiguredObject<BridgeConfigType, BridgeConfig>
+public interface GroupManager
{
+ Set<Principal> getGroupPrincipalsForUser(String user);
- boolean isDynamic();
-
- boolean isQueueBridge();
-
- boolean isLocalSource();
-
- String getSource();
-
- String getDestination();
-
- String getKey();
+ Set<Principal> getGroupPrincipals();
- String getTag();
+ Set<Principal> getUserPrincipalsForGroup(String group);
- String getExcludes();
+ void createGroup(String group);
- LinkConfig getLink();
+ void removeGroup(String group);
- Integer getChannelId();
+ void addUserToGroup(String user, String group);
- int getAckBatching();
-} \ No newline at end of file
+ void removeUserFromGroup(String user, String group);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java
index 30a503c769..a9590bb964 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,8 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.group;
+import java.io.Serializable;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Enumeration;
@@ -30,11 +31,11 @@ import java.util.Enumeration;
* methods etc throw {@link UnsupportedOperationException}.
*
*/
-public class GroupPrincipal implements Group
+public class GroupPrincipal implements Group, Serializable
{
/** Name of the group */
private final String _groupName;
-
+
public GroupPrincipal(final String groupName)
{
_groupName = groupName;
@@ -83,7 +84,7 @@ public class GroupPrincipal implements Group
{
return true;
}
- else
+ else
{
if (obj instanceof GroupPrincipal)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java
new file mode 100644
index 0000000000..d549b76aab
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.group;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.adapter.GroupProviderAdapter;
+
+
+public class GroupPrincipalAccessor
+{
+ private final Collection<GroupProvider> _groupProviders;
+
+ public GroupPrincipalAccessor(Collection<GroupProvider> groupProviders)
+ {
+ _groupProviders = groupProviders;
+ }
+
+ public Set<Principal> getGroupPrincipals(String username)
+ {
+ Set<Principal> principals = new HashSet<Principal>();
+ for (GroupProvider groupProvider : _groupProviders)
+ {
+ Set<Principal> groups = groupProvider.getGroupPrincipalsForUser(username);
+ if (groups != null)
+ {
+ principals.addAll(groups);
+ }
+ }
+
+ return Collections.unmodifiableSet(principals);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java b/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java
deleted file mode 100644
index bdcfd86f82..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java
+++ /dev/null
@@ -1,89 +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.signal;
-
-import org.apache.log4j.Logger;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-public abstract class SignalHandlerTask
-{
- private static final Logger LOGGER = Logger.getLogger(SignalHandlerTask.class);
-
- private static final String HANDLE_METHOD = "handle";
- private static final String SUN_MISC_SIGNAL_CLASS = "sun.misc.Signal";
- private static final String SUN_MISC_SIGNAL_HANDLER_CLASS = "sun.misc.SignalHandler";
-
- public boolean register(final String signalName)
- {
- try
- {
- //try to load the signal handling classes
- Class<?> signalClazz = Class.forName(SUN_MISC_SIGNAL_CLASS);
- Class<?> handlerClazz = Class.forName(SUN_MISC_SIGNAL_HANDLER_CLASS);
-
- //create an InvocationHandler that just executes the SignalHandlerTask
- InvocationHandler invoker = new InvocationHandler()
- {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- handle();
-
- return null;
- }
- };
-
- //create a dynamic proxy implementing SignalHandler
- Object handler = Proxy.newProxyInstance(handlerClazz.getClassLoader(), new Class[]{handlerClazz}, invoker);
-
- //create the Signal to handle
- Constructor<?> signalConstructor = signalClazz.getConstructor(String.class);
- Object signal = signalConstructor.newInstance(signalName);
-
- //invoke the Signal.handle(signal, handler) method
- Method handleMethod = signalClazz.getMethod(HANDLE_METHOD, signalClazz, handlerClazz);
- handleMethod.invoke(null, signal, handler);
- }
- catch (Exception e)
- {
- LOGGER.debug("Unable to register handler for Signal " + signalName + " due to exception: " + e, e);
- return false;
- }
-
- return true;
- }
-
- public abstract void handle();
-
- public static String getPlatformDescription()
- {
- String name = System.getProperty("os.name");
- String osVer = System.getProperty("os.version");
- String jvmVendor = System.getProperty("java.vm.vendor");
- String jvmName = System.getProperty("java.vm.name");
- String javaRuntimeVer = System.getProperty("java.runtime.version");
-
- return "OS: " + name + " " + osVer + ", JVM:" + jvmVendor + " " + jvmName + " " + javaRuntimeVer;
- }
-}
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 f352bbdd2c..ff41536a23 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
@@ -31,10 +31,10 @@ import org.apache.qpid.framing.MethodDispatcher;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
+import org.apache.qpid.server.model.Broker;
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.security.SubjectCreator;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -47,32 +47,29 @@ public class AMQStateManager implements AMQMethodListener
{
private static final Logger _logger = Logger.getLogger(AMQStateManager.class);
- private final VirtualHostRegistry _virtualHostRegistry;
+ private final Broker _broker;
private final AMQProtocolSession _protocolSession;
/** The current state */
private AMQState _currentState;
private CopyOnWriteArraySet<StateListener> _stateListeners = new CopyOnWriteArraySet<StateListener>();
- public AMQStateManager(VirtualHostRegistry virtualHostRegistry, AMQProtocolSession protocolSession)
+ public AMQStateManager(Broker broker, AMQProtocolSession protocolSession)
{
-
- _virtualHostRegistry = virtualHostRegistry;
+ _broker = broker;
_protocolSession = protocolSession;
_currentState = AMQState.CONNECTION_NOT_STARTED;
}
/**
- * Get the ApplicationRegistry associated with this AMQStateManager
- *
- * returns the application registry associated with the VirtualHostRegistry of the AMQStateManager
+ * Get the Broker instance
*
- * @return the ApplicationRegistry
+ * @return the Broker
*/
- public IApplicationRegistry getApplicationRegistry()
+ public Broker getBroker()
{
- return _virtualHostRegistry.getApplicationRegistry();
+ return _broker;
}
public AMQState getCurrentState()
@@ -148,7 +145,7 @@ public class AMQStateManager implements AMQMethodListener
public VirtualHostRegistry getVirtualHostRegistry()
{
- return _virtualHostRegistry;
+ return _broker.getVirtualHostRegistry();
}
public AMQProtocolSession getProtocolSession()
@@ -157,13 +154,9 @@ public class AMQStateManager implements AMQMethodListener
return _protocolSession;
}
- /**
- * Get the AuthenticationManager associated with the ProtocolSession of the AMQStateManager
- *
- * @return the AuthenticationManager
- */
- public AuthenticationManager getAuthenticationManager()
+
+ public SubjectCreator getSubjectCreator()
{
- return getApplicationRegistry().getAuthenticationManager(getProtocolSession().getLocalAddress());
+ return _broker.getSubjectCreator(getProtocolSession().getLocalAddress());
}
}
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 ede01d247e..ab7ef3f55b 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
@@ -46,19 +46,7 @@ public interface ConfigurationRecoveryHandler
public static interface BindingRecoveryHandler
{
void binding(UUID bindingId, UUID exchangeId, UUID queueId, String bindingName, ByteBuffer buf);
- BrokerLinkRecoveryHandler completeBindingRecovery();
- }
-
- public static interface BrokerLinkRecoveryHandler
- {
- BridgeRecoveryHandler brokerLink(UUID id, long createTime, Map<String,String> arguments);
- void completeBrokerLinkRecovery();
- }
-
- public static interface BridgeRecoveryHandler
- {
- void bridge(UUID id, long createTime, Map<String,String> arguments);
- void completeBridgeRecoveryForLink();
+ void completeBindingRecovery();
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
index 655887e5c2..4e7bbf04a6 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
@@ -26,8 +26,6 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.queue.AMQQueue;
public interface DurableConfigurationStore
@@ -122,12 +120,5 @@ public interface DurableConfigurationStore
* @throws AMQStoreException If the operation fails for any reason.
*/
void updateQueue(AMQQueue queue) throws AMQStoreException;
-
- void createBrokerLink(BrokerLink link) throws AMQStoreException;
-
- void deleteBrokerLink(BrokerLink link) throws AMQStoreException;
-
- void createBridge(Bridge bridge) throws AMQStoreException;
-
- void deleteBridge(Bridge bridge) throws AMQStoreException;
+
}
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 262d7d0213..3f1d1b9530 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
@@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicLong;
/** A simple message store that stores the messages in a thread-safe structure in memory. */
public class MemoryMessageStore extends NullMessageStore
{
+ public static final String TYPE = "Memory";
private final AtomicLong _messageId = new AtomicLong(1);
private final AtomicBoolean _closed = new AtomicBoolean(false);
@@ -138,6 +139,6 @@ public class MemoryMessageStore extends NullMessageStore
@Override
public String getStoreType()
{
- return "Memory";
+ return TYPE;
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java
index 706ab3974a..20b6b7a8a6 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java
@@ -18,19 +18,22 @@
* under the License.
*
*/
+package org.apache.qpid.server.store;
-package org.apache.qpid.qmf;
-public enum CompletionCode
+public class MemoryMessageStoreFactory implements MessageStoreFactory
{
- OK,
- UNKNOWN_OBJECT,
- UNKNOWN_METHOD,
- NOT_IMPLEMENTED,
- INVALID_PARAMETER,
- FEATURE_NOT_IMPLEMENTED,
- FORBIDDEN,
- EXCEPTION,
- UNKNOWN_PACKAGE,
- UNKNOWN_CLASS;
+
+ @Override
+ public String getType()
+ {
+ return MemoryMessageStore.TYPE;
+ }
+
+ @Override
+ public MessageStore createMessageStore()
+ {
+ return new MemoryMessageStore();
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java
new file mode 100644
index 0000000000..0d5a4850f6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+
+public class MessageStoreCreator
+{
+ private Map<String, MessageStoreFactory> _factories = new HashMap<String, MessageStoreFactory>();
+
+ public MessageStoreCreator()
+ {
+ QpidServiceLoader<MessageStoreFactory> qpidServiceLoader = new QpidServiceLoader<MessageStoreFactory>();
+ Iterable<MessageStoreFactory> factories = qpidServiceLoader.atLeastOneInstanceOf(MessageStoreFactory.class);
+ for (MessageStoreFactory messageStoreFactory : factories)
+ {
+ String type = messageStoreFactory.getType();
+ MessageStoreFactory factory = _factories.put(type.toLowerCase(), messageStoreFactory);
+ if (factory != null)
+ {
+ throw new IllegalStateException("MessageStoreFactory with type name '" + type
+ + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '"
+ + messageStoreFactory.getClass().getName() + "'");
+ }
+ }
+ }
+
+ public MessageStore createMessageStore(String storeType)
+ {
+ MessageStoreFactory factory = _factories.get(storeType.toLowerCase());
+ if (factory == null)
+ {
+ throw new IllegalConfigurationException("Unknown store type: " + storeType);
+ }
+ return factory.createMessageStore();
+ }
+
+ public Collection<MessageStoreFactory> getFactories()
+ {
+ return Collections.unmodifiableCollection(_factories.values());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java
index 9f9c832732..a1afd02f12 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java
@@ -18,16 +18,11 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.server.store;
-public enum QMFEventSeverity
+public interface MessageStoreFactory
{
- EMERGENCY,
- ALERT,
- CRITICAL,
- ERROR,
- WARN,
- NOTICE,
- INFORM,
- DEBUG
+ String getType();
+
+ MessageStore createMessageStore();
}
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 be08e309e6..c6bffbc1de 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
@@ -24,8 +24,6 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.queue.AMQQueue;
public abstract class NullMessageStore implements MessageStore
@@ -78,26 +76,6 @@ public abstract class NullMessageStore implements MessageStore
}
@Override
- public void createBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- }
-
- @Override
- public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- }
-
- @Override
- public void createBridge(final Bridge bridge) throws AMQStoreException
- {
- }
-
- @Override
- public void deleteBridge(final Bridge bridge) throws AMQStoreException
- {
- }
-
- @Override
public void configureMessageStore(String name,
MessageStoreRecoveryHandler recoveryHandler,
TransactionLogRecoveryHandler tlogRecoveryHandler, Configuration config) throws Exception
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 2783637b2a..1d0936cec4 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,8 +20,6 @@
*/
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. */
@@ -30,7 +28,7 @@ public enum State
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.
+ * If the store is persistent, it has not yet loaded configuration from disk.
*
* From the point of view of the user, the store is essentially stopped.
*/
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 154d7e6535..e9946d1860 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
@@ -23,7 +23,6 @@ package org.apache.qpid.server.store.derby;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
@@ -41,7 +40,6 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -55,12 +53,9 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-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;
@@ -236,7 +231,7 @@ public class DerbyMessageStore implements MessageStore
private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006";
- private static final String DERBY_STORE_TYPE = "DERBY";
+ public static final String TYPE = "DERBY";
private final StateManager _stateManager;
@@ -572,8 +567,7 @@ public class DerbyMessageStore implements MessageStore
BindingRecoveryHandler brh = qrh.completeQueueRecovery();
_configuredObjectHelper.recoverBindings(brh, configuredObjects);
- BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery();
- recoverBrokerLinks(lrh);
+ brh.completeBindingRecovery();
}
catch (SQLException e)
{
@@ -581,144 +575,6 @@ public class DerbyMessageStore implements MessageStore
}
}
- private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh)
- throws SQLException
- {
- _logger.info("Recovering broker links...");
-
- Connection conn = null;
- try
- {
- conn = newAutoCommitConnection();
-
- PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_LINKS);
-
- try
- {
- ResultSet rs = stmt.executeQuery();
-
- try
- {
-
- while(rs.next())
- {
- UUID id = new UUID(rs.getLong(2), rs.getLong(1));
- long createTime = rs.getLong(3);
- Blob argumentsAsBlob = rs.getBlob(4);
-
- byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length());
-
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes));
- int size = dis.readInt();
-
- Map<String,String> arguments = new HashMap<String, String>();
-
- for(int i = 0; i < size; i++)
- {
- arguments.put(dis.readUTF(), dis.readUTF());
- }
-
- ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments);
-
- recoverBridges(brh, id);
-
- }
- }
- catch (IOException e)
- {
- throw new SQLException(e.getMessage(), e);
- }
- finally
- {
- rs.close();
- }
- }
- finally
- {
- stmt.close();
- }
-
- }
- finally
- {
- if(conn != null)
- {
- conn.close();
- }
- }
-
- }
-
- private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId)
- throws SQLException
- {
- _logger.info("Recovering bridges for link " + linkId + "...");
-
- Connection conn = null;
- try
- {
- conn = newAutoCommitConnection();
-
- PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_BRIDGES);
-
- try
- {
- stmt.setLong(1, linkId.getLeastSignificantBits());
- stmt.setLong(2, linkId.getMostSignificantBits());
-
- ResultSet rs = stmt.executeQuery();
-
- try
- {
-
- while(rs.next())
- {
- UUID id = new UUID(rs.getLong(2), rs.getLong(1));
- long createTime = rs.getLong(3);
- Blob argumentsAsBlob = rs.getBlob(6);
-
- byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length());
-
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes));
- int size = dis.readInt();
-
- Map<String,String> arguments = new HashMap<String, String>();
-
- for(int i = 0; i < size; i++)
- {
- arguments.put(dis.readUTF(), dis.readUTF());
- }
-
- brh.bridge(id, createTime, arguments);
-
- }
- brh.completeBridgeRecoveryForLink();
- }
- catch (IOException e)
- {
- throw new SQLException(e.getMessage(), e);
- }
- finally
- {
- rs.close();
- }
- }
- finally
- {
- stmt.close();
- }
-
- }
- finally
- {
- if(conn != null)
- {
- conn.close();
- }
- }
-
- }
-
@Override
public void close() throws Exception
{
@@ -975,71 +831,6 @@ public class DerbyMessageStore implements MessageStore
}
}
- @Override
- public void createBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- _logger.debug("public void createBrokerLink(BrokerLink = " + link + "): called");
-
- if (_stateManager.isInState(State.ACTIVE))
- {
- try
- {
- Connection conn = newAutoCommitConnection();
-
- PreparedStatement stmt = conn.prepareStatement(FIND_LINK);
- try
- {
-
- stmt.setLong(1, link.getQMFId().getLeastSignificantBits());
- stmt.setLong(2, link.getQMFId().getMostSignificantBits());
- ResultSet rs = stmt.executeQuery();
- try
- {
-
- // If we don't have any data in the result set then we can add this queue
- if (!rs.next())
- {
- PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_LINKS);
-
- try
- {
-
- insertStmt.setLong(1, link.getQMFId().getLeastSignificantBits());
- insertStmt.setLong(2, link.getQMFId().getMostSignificantBits());
- insertStmt.setLong(3, link.getCreateTime());
-
- byte[] argumentBytes = convertStringMapToBytes(link.getArguments());
- ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes);
-
- insertStmt.setBinaryStream(4,bis,argumentBytes.length);
-
- insertStmt.execute();
- }
- finally
- {
- insertStmt.close();
- }
- }
- }
- finally
- {
- rs.close();
- }
- }
- finally
- {
- stmt.close();
- }
- conn.close();
-
- }
- catch (SQLException e)
- {
- throw new AMQStoreException("Error writing " + link + " to database: " + e.getMessage(), e);
- }
- }
- }
-
private byte[] convertStringMapToBytes(final Map<String, String> arguments) throws AMQStoreException
{
byte[] argumentBytes;
@@ -1072,139 +863,7 @@ public class DerbyMessageStore implements MessageStore
return argumentBytes;
}
- @Override
- public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- _logger.debug("public void deleteBrokerLink( " + link + "): called");
- Connection conn = null;
- PreparedStatement stmt = null;
- try
- {
- conn = newAutoCommitConnection();
- stmt = conn.prepareStatement(DELETE_FROM_LINKS);
- stmt.setLong(1, link.getQMFId().getLeastSignificantBits());
- stmt.setLong(2, link.getQMFId().getMostSignificantBits());
- int results = stmt.executeUpdate();
-
- if (results == 0)
- {
- throw new AMQStoreException("Link " + link + " not found");
- }
- }
- catch (SQLException e)
- {
- throw new AMQStoreException("Error deleting Link " + link + " from database: " + e.getMessage(), e);
- }
- finally
- {
- closePreparedStatement(stmt);
- closeConnection(conn);
- }
-
-
- }
-
- @Override
- public void createBridge(final Bridge bridge) throws AMQStoreException
- {
- _logger.debug("public void createBridge(BrokerLink = " + bridge + "): called");
- if (_stateManager.isInState(State.ACTIVE))
- {
- try
- {
- Connection conn = newAutoCommitConnection();
-
- PreparedStatement stmt = conn.prepareStatement(FIND_BRIDGE);
- try
- {
-
- UUID id = bridge.getQMFId();
- stmt.setLong(1, id.getLeastSignificantBits());
- stmt.setLong(2, id.getMostSignificantBits());
- ResultSet rs = stmt.executeQuery();
- try
- {
-
- // If we don't have any data in the result set then we can add this queue
- if (!rs.next())
- {
- PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_BRIDGES);
-
- try
- {
-
- insertStmt.setLong(1, id.getLeastSignificantBits());
- insertStmt.setLong(2, id.getMostSignificantBits());
-
- insertStmt.setLong(3, bridge.getCreateTime());
-
- UUID linkId = bridge.getLink().getQMFId();
- insertStmt.setLong(4, linkId.getLeastSignificantBits());
- insertStmt.setLong(5, linkId.getMostSignificantBits());
-
- byte[] argumentBytes = convertStringMapToBytes(bridge.getArguments());
- ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes);
-
- insertStmt.setBinaryStream(6,bis,argumentBytes.length);
-
- insertStmt.execute();
- }
- finally
- {
- insertStmt.close();
- }
- }
- }
- finally
- {
- rs.close();
- }
- }
- finally
- {
- stmt.close();
- }
- conn.close();
-
- }
- catch (SQLException e)
- {
- throw new AMQStoreException("Error writing " + bridge + " to database: " + e.getMessage(), e);
- }
- }
- }
-
- @Override
- public void deleteBridge(final Bridge bridge) throws AMQStoreException
- {
- _logger.debug("public void deleteBridge( " + bridge + "): called");
- Connection conn = null;
- PreparedStatement stmt = null;
- try
- {
- conn = newAutoCommitConnection();
- stmt = conn.prepareStatement(DELETE_FROM_BRIDGES);
- stmt.setLong(1, bridge.getQMFId().getLeastSignificantBits());
- stmt.setLong(2, bridge.getQMFId().getMostSignificantBits());
- int results = stmt.executeUpdate();
-
- if (results == 0)
- {
- throw new AMQStoreException("Bridge " + bridge + " not found");
- }
- }
- catch (SQLException e)
- {
- throw new AMQStoreException("Error deleting bridge " + bridge + " from database: " + e.getMessage(), e);
- }
- finally
- {
- closePreparedStatement(stmt);
- closeConnection(conn);
- }
-
- }
@Override
public Transaction newTransaction()
@@ -2134,8 +1793,9 @@ public class DerbyMessageStore implements MessageStore
public ByteBuffer getContent(int offsetInMessage, int size)
{
ByteBuffer buf = ByteBuffer.allocate(size);
- getContent(offsetInMessage, buf);
+ int length = getContent(offsetInMessage, buf);
buf.position(0);
+ buf.limit(length);
return buf;
}
@@ -2673,7 +2333,7 @@ public class DerbyMessageStore implements MessageStore
@Override
public String getStoreType()
{
- return DERBY_STORE_TYPE;
+ return TYPE;
}
} \ No newline at end of file
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/store/derby/DerbyMessageStoreFactory.java
new file mode 100644
index 0000000000..046b503d8a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.MessageStoreFactory;
+
+public class DerbyMessageStoreFactory implements MessageStoreFactory
+{
+
+ @Override
+ public String getType()
+ {
+ return DerbyMessageStore.TYPE;
+ }
+
+ @Override
+ public MessageStore createMessageStore()
+ {
+ return new DerbyMessageStore();
+ }
+
+}
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 c92853e400..6c5cb2e721 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
@@ -27,11 +27,6 @@ import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.configuration.SubscriptionConfig;
-import org.apache.qpid.server.configuration.SubscriptionConfigType;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.filter.FilterManagerFactory;
import org.apache.qpid.server.flow.FlowCreditManager;
@@ -61,8 +56,7 @@ import java.util.concurrent.locks.ReentrantLock;
* Encapsulation of a supscription to a queue. <p/> Ties together the protocol session of a subscriber, the consumer tag
* that was given out by the broker and the channel id. <p/>
*/
-public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener,
- SubscriptionConfig
+public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener
{
private StateListener _stateListener = new StateListener()
@@ -91,7 +85,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
private final long _subscriptionID;
private LogSubject _logSubject;
private LogActor _logActor;
- private UUID _qmfId;
private final AtomicLong _deliveredCount = new AtomicLong(0);
private final AtomicLong _deliveredBytes = new AtomicLong(0);
@@ -373,11 +366,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return _channel;
}
- public ConfigStore getConfigStore()
- {
- return getQueue().getConfigStore();
- }
-
public Long getDelivered()
{
return _deliveredCount.get();
@@ -391,9 +379,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
_queue = queue;
- _qmfId = getConfigStore().createId();
- getConfigStore().addConfiguredObject(this);
-
_logSubject = new SubscriptionLogSubject(this);
_logActor = new SubscriptionActor(CurrentActor.get().getRootMessageLogger(), this);
@@ -547,8 +532,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
{
_stateChangeLock.unlock();
}
- getConfigStore().removeConfiguredObject(this);
-
//Log Subscription closed
CurrentActor.get().message(_logSubject, SubscriptionMessages.CLOSE());
}
@@ -752,11 +735,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return "WINDOW";
}
- public SessionConfig getSessionConfig()
- {
- return getChannel();
- }
-
public boolean isBrowsing()
{
return isBrowser();
@@ -767,32 +745,16 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
return true;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
public boolean isDurable()
{
return false;
}
- public SubscriptionConfigType getConfigType()
- {
- return SubscriptionConfigType.getInstance();
- }
-
public boolean isExclusive()
{
return getQueue().hasExclusiveSubscriber();
}
- public ConfiguredObject getParent()
- {
- return getSessionConfig();
- }
-
public String getName()
{
return String.valueOf(_consumerTag);
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 dfd9315226..b9bba49fab 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
@@ -24,11 +24,6 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.configuration.SubscriptionConfig;
-import org.apache.qpid.server.configuration.SubscriptionConfigType;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.flow.CreditCreditManager;
@@ -86,7 +81,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, SubscriptionConfig, LogSubject
+public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, LogSubject
{
private final long _subscriptionID;
@@ -125,7 +120,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private LogActor _logActor;
private final Map<String, Object> _properties = new ConcurrentHashMap<String, Object>();
- private UUID _qmfId;
private String _traceExclude;
private String _trace;
private final long _createTime = System.currentTimeMillis();
@@ -192,8 +186,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
Map<String, Object> arguments = queue.getArguments();
_traceExclude = (String) arguments.get("qpid.trace.exclude");
_trace = (String) arguments.get("qpid.trace.id");
- _qmfId = getConfigStore().createId();
- getConfigStore().addConfiguredObject(this);
String filterLogString = null;
_logActor = GenericActor.getInstance(this);
@@ -283,7 +275,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
}
_creditManager.removeListener(this);
- getConfigStore().removeConfiguredObject(this);
CurrentActor.get().message(getLogSubject(), SubscriptionMessages.CLOSE());
}
finally
@@ -295,11 +286,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
}
- public ConfigStore getConfigStore()
- {
- return getQueue().getConfigStore();
- }
-
public Long getDelivered()
{
return _deliveredCount.get();
@@ -970,12 +956,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return _session;
}
-
- public SessionConfig getSessionConfig()
- {
- return getSessionModel();
- }
-
public boolean isBrowsing()
{
return _acquireMode == MessageAcquireMode.NOT_ACQUIRED;
@@ -986,20 +966,11 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return getQueue().hasExclusiveSubscriber();
}
- public ConfiguredObject getParent()
- {
- return getSessionConfig();
- }
-
public boolean isDurable()
{
return false;
}
- public SubscriptionConfigType getConfigType()
- {
- return SubscriptionConfigType.getInstance();
- }
public boolean isExplicitAcknowledge()
{
@@ -1011,12 +982,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
return _flowMode.toString();
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
public String getName()
{
return _destination;
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
deleted file mode 100644
index 7c4188bfcd..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.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.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
-{
- public enum Transport
- {
- 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 _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 f21026794f..58de6a0cdf 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,17 +20,16 @@
*/
package org.apache.qpid.server.transport;
+import java.net.SocketAddress;
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;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -39,6 +38,7 @@ import org.apache.qpid.server.logging.messages.ConnectionMessages;
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.AuthenticatedPrincipal;
import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Connection;
@@ -48,6 +48,7 @@ import org.apache.qpid.transport.ExecutionException;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.ProtocolEvent;
import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.network.NetworkConnection;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT;
@@ -55,7 +56,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORM
public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder
{
- private ConnectionConfig _config;
private Runnable _onOpenTask;
private AtomicBoolean _logClosed = new AtomicBoolean(false);
private LogActor _actor = GenericActor.getInstance(this);
@@ -69,6 +69,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
private AtomicLong _lastIoTime = new AtomicLong();
private boolean _blocking;
private Principal _peerPrincipal;
+ private NetworkConnection _networkConnection;
public ServerConnection(final long connectionId)
{
@@ -147,16 +148,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
initialiseStatistics();
}
- public void setConnectionConfig(final ConnectionConfig config)
- {
- _config = config;
- }
-
- public ConnectionConfig getConfig()
- {
- return _config;
- }
-
public void onOpen(final Runnable task)
{
_onOpenTask = task;
@@ -228,7 +219,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
MessageFormat.format(CONNECTION_FORMAT,
getConnectionId(),
getClientId(),
- getConfig().getAddress(),
+ getRemoteAddressString(),
getVirtualHost().getName())
+ "] ";
}
@@ -238,7 +229,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
MessageFormat.format(USER_FORMAT,
getConnectionId(),
getClientId(),
- getConfig().getAddress())
+ getRemoteAddressString())
+ "] ";
}
@@ -247,7 +238,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
return "[" +
MessageFormat.format(SOCKET_FORMAT,
getConnectionId(),
- getConfig().getAddress())
+ getRemoteAddressString())
+ "] ";
}
}
@@ -396,7 +387,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
else
{
_authorizedSubject = authorizedSubject;
- _authorizedPrincipal = authorizedSubject.getPrincipals().iterator().next();
+ _authorizedPrincipal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(authorizedSubject);
}
}
@@ -417,7 +408,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public String getRemoteAddressString()
{
- return getConfig().getAddress();
+ return String.valueOf(getRemoteAddress());
}
public String getUserName()
@@ -489,4 +480,32 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
{
_peerPrincipal = peerPrincipal;
}
+
+ @Override
+ public void setRemoteAddress(SocketAddress remoteAddress)
+ {
+ super.setRemoteAddress(remoteAddress);
+ }
+
+ @Override
+ public void setLocalAddress(SocketAddress localAddress)
+ {
+ super.setLocalAddress(localAddress);
+ }
+
+ public void setNetworkConnection(NetworkConnection network)
+ {
+ _networkConnection = network;
+ }
+
+ public NetworkConnection getNetworkConnection()
+ {
+ return _networkConnection;
+ }
+
+ public void doHeartbeat()
+ {
+ super.doHeartBeat();
+
+ }
}
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 c13f63b44d..f3153fde62 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
@@ -32,18 +32,19 @@ 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.configuration.BrokerProperties;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.AMQConnectionModel;
-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.SubjectCreator;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.subscription.Subscription_0_10;
import org.apache.qpid.server.virtualhost.State;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.network.NetworkConnection;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,36 +54,49 @@ public class ServerConnectionDelegate extends ServerDelegate
{
private static final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionDelegate.class);
+ private final Broker _broker;
private final String _localFQDN;
- private final IApplicationRegistry _appRegistry;
private int _maxNoOfChannels;
private Map<String,Object> _clientProperties;
- private final AuthenticationManager _authManager;
+ private final SubjectCreator _subjectCreator;
- public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager)
+ public ServerConnectionDelegate(Broker broker, String localFQDN, SubjectCreator subjectCreator)
{
- this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager);
+ this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, localFQDN, subjectCreator);
}
private ServerConnectionDelegate(Map<String, Object> properties,
List<Object> locales,
- IApplicationRegistry appRegistry,
+ Broker broker,
String localFQDN,
- AuthenticationManager authManager)
+ SubjectCreator subjectCreator)
{
- super(properties, parseToList(authManager.getMechanisms()), locales);
+ super(properties, parseToList(subjectCreator.getMechanisms()), locales);
- _appRegistry = appRegistry;
+ _broker = broker;
_localFQDN = localFQDN;
- _maxNoOfChannels = appRegistry.getConfiguration().getMaxChannelCount();
- _authManager = authManager;
+ _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT);
+ _subjectCreator = subjectCreator;
+ }
+
+ private static List<String> getFeatures(Broker broker)
+ {
+ String brokerDisabledFeatures = System.getProperty(BrokerProperties.PROPERTY_DISABLED_FEATURES);
+ final List<String> features = new ArrayList<String>();
+ if (brokerDisabledFeatures == null || !brokerDisabledFeatures.contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR))
+ {
+ features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR);
+ }
+
+ return Collections.unmodifiableList(features);
}
- private static Map<String, Object> createConnectionProperties(final BrokerConfig brokerConfig)
+ private static Map<String, Object> createConnectionProperties(final Broker broker)
{
final Map<String,Object> map = new HashMap<String,Object>(2);
- map.put(ServerPropertyNames.FEDERATION_TAG, brokerConfig.getFederationTag());
- final List<String> features = brokerConfig.getFeatures();
+ // Federation tag is used by the client to identify the broker instance
+ map.put(ServerPropertyNames.FEDERATION_TAG, broker.getId().toString());
+ final List<String> features = getFeatures(broker);
if (features != null && features.size() > 0)
{
map.put(ServerPropertyNames.QPID_FEATURES, features);
@@ -112,14 +126,14 @@ public class ServerConnectionDelegate extends ServerDelegate
protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException
{
- return _authManager.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
+ return _subjectCreator.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
}
protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
{
final ServerConnection sconn = (ServerConnection) conn;
- final AuthenticationResult authResult = _authManager.authenticate(ss, response);
+ final SubjectAuthenticationResult authResult = _subjectCreator.authenticate(ss, response);
if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
{
@@ -166,7 +180,7 @@ public class ServerConnectionDelegate extends ServerDelegate
{
vhostName = "";
}
- vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName);
+ vhost = _broker.getVirtualHostRegistry().getVirtualHost(vhostName);
SecurityManager.setThreadSubject(sconn.getAuthorizedSubject());
@@ -174,7 +188,7 @@ public class ServerConnectionDelegate extends ServerDelegate
{
sconn.setVirtualHost(vhost);
- if (!vhost.getSecurityManager().accessVirtualhost(vhostName, ((ProtocolEngine) sconn.getConfig()).getRemoteAddress()))
+ if (!vhost.getSecurityManager().accessVirtualhost(vhostName, sconn.getRemoteAddress()))
{
sconn.setState(Connection.State.CLOSING);
sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'"));
@@ -215,14 +229,18 @@ public class ServerConnectionDelegate extends ServerDelegate
return;
}
- setConnectionTuneOkChannelMax(sconn, okChannelMax);
- }
+ if(ok.hasHeartbeat())
+ {
+ final int heartbeat = ok.getHeartbeat();
+ if(heartbeat > 0)
+ {
+ final NetworkConnection networkConnection = sconn.getNetworkConnection();
+ networkConnection.setMaxReadIdle(2 * heartbeat);
+ networkConnection.setMaxWriteIdle(heartbeat);
+ }
+ }
- @Override
- protected int getHeartbeatMax()
- {
- //TODO: implement broker support for actually sending heartbeats
- return 0;
+ setConnectionTuneOkChannelMax(sconn, okChannelMax);
}
@Override
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 f82b25b3d6..6152ddd228 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
@@ -42,13 +42,8 @@ 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;
-import org.apache.qpid.server.configuration.SessionConfig;
-import org.apache.qpid.server.configuration.SessionConfigType;
+import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -91,7 +86,7 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F
import static org.apache.qpid.util.Serial.gt;
public class ServerSession extends Session
- implements AuthorizationHolder, SessionConfig,
+ implements AuthorizationHolder,
AMQSessionModel, LogSubject, AsyncAutoCommitTransaction.FutureRecorder
{
private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class);
@@ -100,8 +95,7 @@ public class ServerSession extends Session
private static final int PRODUCER_CREDIT_TOPUP_THRESHOLD = 1 << 30;
private static final int UNFINISHED_COMMAND_QUEUE_THRESHOLD = 500;
- private final UUID _id;
- private ConnectionConfig _connectionConfig;
+ private final UUID _id = UUID.randomUUID();
private long _createTime = System.currentTimeMillis();
private LogActor _actor = GenericActor.getInstance(this);
@@ -139,7 +133,6 @@ public class ServerSession extends Session
private final AtomicLong _txnCommits = new AtomicLong(0);
private final AtomicLong _txnRejects = new AtomicLong(0);
private final AtomicLong _txnCount = new AtomicLong(0);
- private final AtomicLong _txnUpdateTime = new AtomicLong(0);
private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>();
@@ -147,21 +140,21 @@ public class ServerSession extends Session
private final TransactionTimeoutHelper _transactionTimeoutHelper;
- ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
- {
- this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig());
- }
- public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry, ConnectionConfig connConfig)
+ public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry)
{
super(connection, delegate, name, expiry);
- _connectionConfig = connConfig;
_transaction = new AsyncAutoCommitTransaction(this.getMessageStore(),this);
_logSubject = new ChannelLogSubject(this);
- _id = getConfigStore().createId();
- getConfigStore().addConfiguredObject(this);
- _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction()
+ {
+ @Override
+ public void doTimeoutAction(String reason) throws AMQException
+ {
+ getConnectionModel().closeSession(ServerSession.this, AMQConstant.RESOURCE_ERROR, reason);
+ }
+ });
}
protected void setState(State state)
@@ -184,12 +177,6 @@ public class ServerSession extends Session
invoke(new MessageStop(""));
}
- private ConfigStore getConfigStore()
- {
- return getConnectionConfig().getConfigStore();
- }
-
-
@Override
protected boolean isFull(int id)
{
@@ -206,9 +193,8 @@ public class ServerSession extends Session
}
getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime());
PostEnqueueAction postTransactionAction = new PostEnqueueAction(queues, message, isTransactional()) ;
- _transaction.enqueue(queues,message, postTransactionAction, 0L);
+ _transaction.enqueue(queues,message, postTransactionAction);
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
}
@@ -389,8 +375,6 @@ public class ServerSession extends Session
}
_messageDispositionListenerMap.clear();
- getConfigStore().removeConfiguredObject(this);
-
for (Task task : _taskList)
{
task.doTask(this);
@@ -424,7 +408,6 @@ public class ServerSession extends Session
entry.release();
}
});
- updateTransactionalActivity();
}
public Collection<Subscription_0_10> getSubscriptions()
@@ -470,11 +453,6 @@ public class ServerSession extends Session
return _transaction.isTransactional();
}
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
-
public void selectTx()
{
_transaction = new LocalTransaction(this.getMessageStore());
@@ -609,22 +587,6 @@ public class ServerSession extends Session
}
}
- /**
- * Update last transaction activity timestamp
- */
- public void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(System.currentTimeMillis());
- }
- }
-
- public Long getTxnStarts()
- {
- return _txnStarts.get();
- }
-
public Long getTxnCommits()
{
return _txnCommits.get();
@@ -682,23 +644,7 @@ public class ServerSession extends Session
public VirtualHost getVirtualHost()
{
- return (VirtualHost) _connectionConfig.getVirtualHost();
- }
-
- @Override
- public UUID getQMFId()
- {
- return _id;
- }
-
- public SessionConfigType getConfigType()
- {
- return SessionConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getVirtualHost();
+ return getConnection().getVirtualHost();
}
public boolean isDurable()
@@ -706,44 +652,16 @@ public class ServerSession extends Session
return false;
}
- public boolean isAttached()
- {
- return true;
- }
-
- public long getDetachedLifespan()
- {
- return 0;
- }
-
- public Long getExpiryTime()
- {
- return null;
- }
-
- public Long getMaxClientRate()
- {
- return null;
- }
-
- public ConnectionConfig getConnectionConfig()
- {
- return _connectionConfig;
- }
-
- public String getSessionName()
- {
- return getName().toString();
- }
public long getCreateTime()
{
return _createTime;
}
- public void mgmtClose()
+ @Override
+ public UUID getId()
{
- close();
+ return _id;
}
public AMQConnectionModel getConnectionModel()
@@ -774,28 +692,7 @@ public class ServerSession extends Session
public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
{
- if (inTransaction())
- {
- long currentTime = System.currentTimeMillis();
- long openTime = currentTime - _transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
-
- _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;
- }
-
- _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;
- }
- }
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose);
}
public void block(AMQQueue queue)
@@ -878,9 +775,7 @@ public class ServerSession extends Session
? getConnection().getConnectionId()
: -1;
- String remoteAddress = _connectionConfig instanceof ProtocolEngine
- ? ((ProtocolEngine) _connectionConfig).getRemoteAddress().toString()
- : "";
+ String remoteAddress = String.valueOf(getConnection().getRemoteAddress());
return "[" +
MessageFormat.format(CHANNEL_FORMAT,
connectionId,
@@ -1065,14 +960,16 @@ public class ServerSession extends Session
super.setClose(close);
}
- public int compareTo(AMQSessionModel session)
+ @Override
+ public int getConsumerCount()
{
- return getQMFId().compareTo(session.getQMFId());
+ return _subscriptions.values().size();
}
@Override
- public int getConsumerCount()
+ public int compareTo(AMQSessionModel o)
{
- return _subscriptions.values().size();
+ return getId().compareTo(o.getId());
}
+
}
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 05963ee874..d83bd1c4dc 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
@@ -31,7 +31,6 @@ import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeInUseException;
import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.exchange.HeadersExchange;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.filter.FilterManagerFactory;
@@ -41,11 +40,11 @@ import org.apache.qpid.server.logging.messages.ExchangeMessages;
import org.apache.qpid.server.message.MessageMetaData_0_10;
import org.apache.qpid.server.message.MessageTransferMessage;
import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
@@ -1266,18 +1265,12 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
queueRegistry.registerQueue(queue);
- boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister();
- if (autoRegister)
- {
-
- ExchangeRegistry exchangeRegistry = getExchangeRegistry(session);
+ ExchangeRegistry exchangeRegistry = getExchangeRegistry(session);
- Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
+ Exchange defaultExchange = exchangeRegistry.getDefaultExchange();
- virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null);
-
- }
+ virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null);
if (method.hasAutoDelete()
&& method.getAutoDelete()
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 efd7850a49..43e60c8e13 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
@@ -66,11 +66,18 @@ public class AsyncAutoCommitTransaction implements ServerTransaction
_futureRecorder = recorder;
}
+ @Override
public long getTransactionStartTime()
{
return 0L;
}
+ @Override
+ public long getTransactionUpdateTime()
+ {
+ return 0L;
+ }
+
/**
* Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered
* by the caller are executed immediately.
@@ -241,7 +248,7 @@ public class AsyncAutoCommitTransaction implements ServerTransaction
}
- public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction)
{
Transaction txn = null;
try
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
index e5a7df6880..8a9479a2d4 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
@@ -52,11 +52,18 @@ public class AutoCommitTransaction implements ServerTransaction
_messageStore = transactionLog;
}
+ @Override
public long getTransactionStartTime()
{
return 0L;
}
+ @Override
+ public long getTransactionUpdateTime()
+ {
+ return 0L;
+ }
+
/**
* Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered
* by the caller are executed immediately.
@@ -178,7 +185,7 @@ public class AutoCommitTransaction implements ServerTransaction
}
- public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction)
{
Transaction txn = null;
try
@@ -270,4 +277,6 @@ public class AutoCommitTransaction implements ServerTransaction
}
}
+
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java
index 05d0110e9b..ab987f0fb9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java
@@ -26,7 +26,6 @@ import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.Transaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Xid;
@@ -39,10 +38,6 @@ public class DistributedTransaction implements ServerTransaction
private final AutoCommitTransaction _autoCommitTransaction;
- private volatile Transaction _transaction;
-
- private long _txnStartTime = 0L;
-
private DtxBranch _branch;
private AMQSessionModel _session;
private VirtualHost _vhost;
@@ -55,9 +50,16 @@ public class DistributedTransaction implements ServerTransaction
_autoCommitTransaction = new AutoCommitTransaction(vhost.getMessageStore());
}
+ @Override
public long getTransactionStartTime()
{
- return _txnStartTime;
+ return 0;
+ }
+
+ @Override
+ public long getTransactionUpdateTime()
+ {
+ return 0;
}
public void addPostTransactionAction(Action postTransactionAction)
@@ -107,7 +109,7 @@ public class DistributedTransaction implements ServerTransaction
{
_branch.enqueue(queue, message);
_branch.addPostTransactionAcion(postTransactionAction);
- enqueue(Collections.singletonList(queue), message, postTransactionAction, System.currentTimeMillis());
+ enqueue(Collections.singletonList(queue), message, postTransactionAction);
}
else
{
@@ -116,7 +118,7 @@ public class DistributedTransaction implements ServerTransaction
}
public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message,
- Action postTransactionAction, long currentTime)
+ Action postTransactionAction)
{
if(_branch != null)
{
@@ -128,7 +130,7 @@ public class DistributedTransaction implements ServerTransaction
}
else
{
- _autoCommitTransaction.enqueue(queues, message, postTransactionAction, currentTime);
+ _autoCommitTransaction.enqueue(queues, message, postTransactionAction);
}
}
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 3fbcff7e2c..afa7cb0fb4 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
@@ -49,25 +49,42 @@ public class LocalTransaction implements ServerTransaction
private final List<Action> _postTransactionActions = new ArrayList<Action>();
private volatile Transaction _transaction;
- private MessageStore _transactionLog;
- private long _txnStartTime = 0L;
+ private final ActivityTimeAccessor _activityTime;
+ private final MessageStore _transactionLog;
+ private volatile long _txnStartTime = 0L;
+ private volatile long _txnUpdateTime = 0l;
private StoreFuture _asyncTran;
public LocalTransaction(MessageStore transactionLog)
{
- _transactionLog = transactionLog;
+ this(transactionLog, new ActivityTimeAccessor()
+ {
+ @Override
+ public long getActivityTime()
+ {
+ return System.currentTimeMillis();
+ }
+ });
}
-
- public boolean inTransaction()
+
+ public LocalTransaction(MessageStore transactionLog, ActivityTimeAccessor activityTime)
{
- return _transaction != null;
+ _transactionLog = transactionLog;
+ _activityTime = activityTime;
}
+ @Override
public long getTransactionStartTime()
{
return _txnStartTime;
}
+ @Override
+ public long getTransactionUpdateTime()
+ {
+ return _txnUpdateTime;
+ }
+
public void addPostTransactionAction(Action postTransactionAction)
{
sync();
@@ -78,6 +95,7 @@ public class LocalTransaction implements ServerTransaction
{
sync();
_postTransactionActions.add(postTransactionAction);
+ initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime();
if(message.isPersistent() && queue.isDurable())
{
@@ -104,6 +122,7 @@ public class LocalTransaction implements ServerTransaction
{
sync();
_postTransactionActions.add(postTransactionAction);
+ initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime();
try
{
@@ -180,6 +199,7 @@ public class LocalTransaction implements ServerTransaction
{
sync();
_postTransactionActions.add(postTransactionAction);
+ initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime();
if(message.isPersistent() && queue.isDurable())
{
@@ -189,7 +209,7 @@ public class LocalTransaction implements ServerTransaction
{
_logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString());
}
-
+
beginTranIfNecessary();
_transaction.enqueueMessage(queue, message);
}
@@ -202,15 +222,11 @@ public class LocalTransaction implements ServerTransaction
}
}
- public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime)
+ public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction)
{
sync();
_postTransactionActions.add(postTransactionAction);
-
- if (_txnStartTime == 0L)
- {
- _txnStartTime = currentTime == 0L ? System.currentTimeMillis() : currentTime;
- }
+ initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime();
if(message.isPersistent())
{
@@ -224,8 +240,7 @@ public class LocalTransaction implements ServerTransaction
{
_logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString() );
}
-
-
+
beginTranIfNecessary();
_transaction.enqueueMessage(queue, message);
}
@@ -378,16 +393,24 @@ public class LocalTransaction implements ServerTransaction
}
throw new RuntimeException("Failed to commit transaction", e);
}
-
-
}
private void doPostTransactionActions()
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Beginning " + _postTransactionActions.size() + " post transaction actions");
+ }
+
for(int i = 0; i < _postTransactionActions.size(); i++)
{
_postTransactionActions.get(i).postCommit();
}
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Completed post transaction actions");
+ }
}
public void rollback()
@@ -427,16 +450,34 @@ public class LocalTransaction implements ServerTransaction
}
}
+ private void initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime()
+ {
+ long currentTime = _activityTime.getActivityTime();
+
+ if (_txnStartTime == 0)
+ {
+ _txnStartTime = currentTime;
+ }
+ _txnUpdateTime = currentTime;
+ }
+
private void resetDetails()
{
_asyncTran = null;
_transaction = null;
- _postTransactionActions.clear();
+ _postTransactionActions.clear();
_txnStartTime = 0L;
+ _txnUpdateTime = 0;
}
public boolean isTransactional()
{
return true;
}
+
+ public interface ActivityTimeAccessor
+ {
+ long getActivityTime();
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
index c568ae67aa..8acac00479 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
@@ -55,11 +55,18 @@ public interface ServerTransaction
/**
* Return the time the current transaction started.
- *
+ *
* @return the time this transaction started or 0 if not in a transaction
*/
long getTransactionStartTime();
+ /**
+ * Return the time of the last activity on the current transaction.
+ *
+ * @return the time of the last activity or 0 if not in a transaction
+ */
+ long getTransactionUpdateTime();
+
/**
* Register an Action for execution after transaction commit or rollback. Actions
* will be executed in the order in which they are registered.
@@ -92,7 +99,7 @@ public interface ServerTransaction
*
* Store operations will result only for a persistent messages on durable queues.
*/
- void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime);
+ void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction);
/**
* Commit the transaction represented by this object.
diff --git a/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java
new file mode 100644
index 0000000000..aa7b4afcae
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java
@@ -0,0 +1,361 @@
+/*
+ *
+ * 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.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class MapValueConverter
+{
+
+ public static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal)
+ {
+ final Object value = attributes.get(name);
+ return toString(value, defaultVal);
+ }
+
+ public static String toString(final Object value)
+ {
+ return toString(value, null);
+ }
+
+ public static String toString(final Object value, String defaultVal)
+ {
+ if (value == null)
+ {
+ return defaultVal;
+ }
+ else if (value instanceof String)
+ {
+ return (String)value;
+ }
+ return String.valueOf(value);
+ }
+
+ public static String getStringAttribute(String name, Map<String, Object> attributes)
+ {
+ assertMandatoryAttribute(name, attributes);
+ return getStringAttribute(name, attributes, null);
+ }
+
+ private static void assertMandatoryAttribute(String name, Map<String, Object> attributes)
+ {
+ if (!attributes.containsKey(name))
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not found");
+ }
+ }
+
+ public static Map<String,Object> getMapAttribute(String name, Map<String,Object> attributes, Map<String,Object> defaultVal)
+ {
+ final Object value = attributes.get(name);
+ if(value == null)
+ {
+ return defaultVal;
+ }
+ else if(value instanceof Map)
+ {
+ @SuppressWarnings("unchecked")
+ Map<String,Object> retVal = (Map<String,Object>) value;
+ return retVal;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map");
+ }
+ }
+
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public 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());
+ }
+ }
+
+ public static <E extends Enum<?>> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes)
+ {
+ assertMandatoryAttribute(name, attributes);
+ return getEnumAttribute(clazz, name, attributes, null);
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ public static <T extends Enum<T>> T toEnum(String name, Object rawValue, Class<T> enumType)
+ {
+ if (enumType.isInstance(rawValue))
+ {
+ return (T) rawValue;
+ }
+ else if (rawValue instanceof String)
+ {
+ return (T) Enum.valueOf(enumType, (String) rawValue);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type "
+ + enumType.getSimpleName());
+ }
+ }
+
+ public static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue)
+ {
+ Object obj = attributes.get(name);
+ return toBoolean(name, obj, defaultValue);
+ }
+
+ public static Boolean toBoolean(String name, Object obj)
+ {
+ return toBoolean(name, obj, null);
+ }
+
+ public static Boolean toBoolean(String name, Object obj, Boolean defaultValue)
+ {
+ 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");
+ }
+ }
+
+
+ public static boolean getBooleanAttribute(String name, Map<String, Object> attributes)
+ {
+ assertMandatoryAttribute(name, attributes);
+ return getBooleanAttribute(name, attributes, null);
+ }
+
+ public static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue)
+ {
+ Object obj = attributes.get(name);
+ return toInteger(name, obj, defaultValue);
+ }
+
+ public static Integer toInteger(String name, Object obj)
+ {
+ return toInteger(name, obj, null);
+ }
+
+ public static Integer toInteger(String name, Object obj, Integer defaultValue)
+ {
+ 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");
+ }
+ }
+
+ public static Integer getIntegerAttribute(String name, Map<String,Object> attributes)
+ {
+ assertMandatoryAttribute(name, attributes);
+ return getIntegerAttribute(name, attributes, null);
+ }
+
+ public static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue)
+ {
+ Object obj = attributes.get(name);
+ return toLong(name, obj, defaultValue);
+ }
+
+ public static Long toLong(String name, Object obj)
+ {
+ return toLong(name, obj, null);
+ }
+
+ public static Long toLong(String name, Object obj, Long defaultValue)
+ {
+ 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 static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes)
+ {
+ assertMandatoryAttribute(name, attributes);
+ return getSetAttribute(name, attributes, Collections.<T>emptySet());
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes, Set<T> defaultValue)
+ {
+ Object obj = attributes.get(name);
+ if(obj == null)
+ {
+ return defaultValue;
+ }
+ else if(obj instanceof Set)
+ {
+ return (Set<T>) obj;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Set");
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T extends Enum<T>> Set<T> getEnumSetAttribute(String name, Map<String, Object> attributes, Class<T> clazz)
+ {
+ Object obj = attributes.get(name);
+ Object[] items = null;
+ if (obj == null)
+ {
+ return null;
+ }
+ else if (obj instanceof Collection)
+ {
+ Collection<?> data = (Collection<?>) obj;
+ items = data.toArray(new Object[data.size()]);
+ }
+ else if (obj instanceof String[])
+ {
+ items = (String[]) obj;
+ }
+ else if (obj instanceof Object[])
+ {
+ items = (Object[]) obj;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Value for attribute " + name + "[" + obj
+ + "] cannot be converted into set of enum of " + clazz);
+ }
+ Set<T> set = new HashSet<T>();
+ for (int i = 0; i < items.length; i++)
+ {
+ T item = null;
+ Object value = items[i];
+ if (value instanceof String)
+ {
+ item = (T) Enum.valueOf(clazz, (String) value);
+ }
+ else if (clazz.isInstance(value))
+ {
+ item = (T) value;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Cannot convert " + value + " from [" + obj + "] into enum of " + clazz
+ + " for attribute " + name);
+ }
+ set.add(item);
+ }
+ return set;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, Object> convert(Map<String, Object> configurationAttributes, Map<String, Class<?>> attributeTypes)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ for (Map.Entry<String, Class<?>> attributeEntry : attributeTypes.entrySet())
+ {
+ String attributeName = attributeEntry.getKey();
+ if (configurationAttributes.containsKey(attributeName))
+ {
+ Class<?> classObject = attributeEntry.getValue();
+ Object rawValue = configurationAttributes.get(attributeName);
+ Object value = null;
+ if (classObject == Long.class || classObject == long.class)
+ {
+ value = toLong(attributeName, rawValue);
+ }
+ else if (classObject == Integer.class || classObject == int.class)
+ {
+ value = toInteger(attributeName, rawValue);
+ }
+ else if (classObject == Boolean.class || classObject == boolean.class)
+ {
+ value = toBoolean(attributeName, rawValue);
+ }
+ else if (classObject == String.class)
+ {
+ value = toString(rawValue);
+ }
+ else if (Enum.class.isAssignableFrom(classObject))
+ {
+ @SuppressWarnings("rawtypes")
+ Class<Enum> enumType = (Class<Enum>)classObject;
+ value = toEnum(attributeName, rawValue, enumType);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Cannot convert '" + rawValue + "' into " + classObject);
+ }
+ attributes.put(attributeName, value);
+ }
+ }
+ return attributes;
+ }
+
+}
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 f810360662..d24f79c56c 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
@@ -25,13 +25,10 @@ import java.util.UUID;
import java.util.concurrent.ScheduledFuture;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.server.binding.BindingFactory;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
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.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
@@ -41,7 +38,7 @@ import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.txn.DtxRegistry;
-public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer
+public interface VirtualHost extends DurableConfigurationStore.Source, Closeable, StatisticsGatherer
{
IConnectionRegistry getConnectionRegistry();
@@ -61,8 +58,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
void close();
- UUID getBrokerId();
-
UUID getId();
void scheduleHouseKeepingTask(long period, HouseKeepingTask task);
@@ -77,25 +72,12 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo
int getHouseKeepingActiveCount();
- IApplicationRegistry getApplicationRegistry();
+ VirtualHostRegistry getVirtualHostRegistry();
BindingFactory getBindingFactory();
- void createBrokerConnection(String transport,
- String host,
- int port,
- String vhost,
- boolean durable,
- String authMechanism, String username, String password);
-
- public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments);
-
- ConfigStore getConfigStore();
-
DtxRegistry getDtxRegistry();
- void removeBrokerConnection(BrokerLink brokerLink);
-
LinkRegistry getLinkRegistry(String remoteContainerId);
ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask);
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 ea2f0f15e4..ae88e3e9f7 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
@@ -35,15 +35,16 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.BindingFactory;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.TransactionLogMessages;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.AbstractServerMessageImpl;
import org.apache.qpid.server.message.EnqueableMessage;
+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.v1_0.Message_1_0;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.QueueEntry;
@@ -65,7 +66,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
ConfigurationRecoveryHandler.QueueRecoveryHandler,
ConfigurationRecoveryHandler.ExchangeRecoveryHandler,
ConfigurationRecoveryHandler.BindingRecoveryHandler,
- ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler,
MessageStoreRecoveryHandler,
MessageStoreRecoveryHandler.StoredMessageRecoveryHandler,
TransactionLogRecoveryHandler,
@@ -77,7 +77,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
private final VirtualHost _virtualHost;
private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>();
- private final Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>();
+ private final Map<Long, ServerMessage> _recoveredMessages = new HashMap<Long, ServerMessage>();
private final Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>();
private MessageStoreLogSubject _logSubject;
@@ -169,7 +169,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
public void message(StoredMessage message)
{
- AbstractServerMessageImpl serverMessage;
+ ServerMessage serverMessage;
switch(message.getMetaData().getType())
{
case META_DATA_0_8:
@@ -178,6 +178,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
case META_DATA_0_10:
serverMessage = new MessageTransferMessage(message, null);
break;
+ case META_DATA_1_0:
+ serverMessage = new Message_1_0(message);
+ break;
default:
throw new RuntimeException("Unknown message type retrieved from store " + message.getMetaData().getClass());
}
@@ -190,19 +193,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
{
}
- public BridgeRecoveryHandler brokerLink(final UUID id,
- final long createTime,
- final Map<String, String> arguments)
- {
- BrokerLink blink = _virtualHost.createBrokerConnection(id, createTime, arguments);
- return new BridgeRecoveryHandlerImpl(blink);
-
- }
-
- public void completeBrokerLinkRecovery()
- {
- }
-
public void dtxRecord(long format, byte[] globalId, byte[] branchId,
Transaction.Record[] enqueues,
Transaction.Record[] dequeues)
@@ -221,12 +211,13 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
if(queue != null)
{
final long messageId = record.getMessage().getMessageNumber();
- final AbstractServerMessageImpl message = _recoveredMessages.get(messageId);
+ final ServerMessage message = _recoveredMessages.get(messageId);
_unusedMessages.remove(messageId);
if(message != null)
{
- message.incrementReference();
+ final MessageReference ref = message.newReference();
+
branch.enqueue(queue,message);
@@ -239,7 +230,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
{
queue.enqueue(message, true, null);
- message.decrementReference();
+ ref.release();
}
catch (AMQException e)
{
@@ -251,7 +242,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
public void onRollback()
{
- message.decrementReference();
+ ref.release();
}
});
}
@@ -280,7 +271,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
if(queue != null)
{
final long messageId = record.getMessage().getMessageNumber();
- final AbstractServerMessageImpl message = _recoveredMessages.get(messageId);
+ final ServerMessage message = _recoveredMessages.get(messageId);
_unusedMessages.remove(messageId);
if(message != null)
@@ -412,9 +403,8 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
- public BrokerLinkRecoveryHandler completeBindingRecovery()
+ public void completeBindingRecovery()
{
- return this;
}
public void complete()
@@ -529,22 +519,4 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
}
}
- private class BridgeRecoveryHandlerImpl implements BridgeRecoveryHandler
- {
- private final BrokerLink _blink;
-
- public BridgeRecoveryHandlerImpl(final BrokerLink blink)
- {
- _blink = blink;
- }
-
- public void bridge(final UUID id, final long createTime, final Map<String, String> arguments)
- {
- _blink.createBridge(id, createTime, arguments);
- }
-
- public void completeBridgeRecoveryForLink()
- {
- }
- }
}
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 d9dc0aa64e..dd3610373f 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
@@ -25,7 +25,6 @@ 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;
@@ -35,12 +34,8 @@ import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.BindingFactory;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
import org.apache.qpid.server.configuration.ExchangeConfiguration;
import org.apache.qpid.server.configuration.QueueConfiguration;
-import org.apache.qpid.server.configuration.VirtualHostConfigType;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.connection.ConnectionRegistry;
import org.apache.qpid.server.connection.IConnectionRegistry;
@@ -49,7 +44,6 @@ import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
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.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;
@@ -61,17 +55,16 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.DefaultQueueRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.stats.StatisticsGatherer;
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.MessageStoreCreator;
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;
public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.RegistryChangeListener, EventListener
{
@@ -79,23 +72,19 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5;
- 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>();
-
private final ScheduledThreadPoolExecutor _houseKeepingTasks;
- private final IApplicationRegistry _appRegistry;
+ private final VirtualHostRegistry _virtualHostRegistry;
- private final SecurityManager _securityManager;
+ private final StatisticsGatherer _brokerStatisticsGatherer;
- private final BrokerConfig _brokerConfig;
+ private final SecurityManager _securityManager;
private final VirtualHostConfiguration _vhostConfig;
@@ -120,7 +109,7 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>();
private boolean _blocked;
- public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception
+ public VirtualHostImpl(VirtualHostRegistry virtualHostRegistry, StatisticsGatherer brokerStatisticsGatherer, SecurityManager parentSecurityManager, VirtualHostConfiguration hostConfig) throws Exception
{
if (hostConfig == null)
{
@@ -132,19 +121,17 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
throw new IllegalArgumentException("Illegal name (" + hostConfig.getName() + ") for virtualhost.");
}
- _appRegistry = appRegistry;
- _brokerConfig = _appRegistry.getBrokerConfig();
+ _virtualHostRegistry = virtualHostRegistry;
+ _brokerStatisticsGatherer = brokerStatisticsGatherer;
_vhostConfig = hostConfig;
_name = _vhostConfig.getName();
_dtxRegistry = new DtxRegistry();
- _qmfId = _appRegistry.getConfigStore().createId();
_id = UUIDGenerator.generateVhostUUID(_name);
CurrentActor.get().message(VirtualHostMessages.CREATED(_name));
- _securityManager = new SecurityManager(_appRegistry.getSecurityManager());
- _securityManager.configureHostPlugins(_vhostConfig);
+ _securityManager = new SecurityManager(parentSecurityManager, _vhostConfig.getConfig().getString("security.acl"));
_connectionRegistry = new ConnectionRegistry();
_connectionRegistry.addRegistryChangeListener(this);
@@ -154,13 +141,12 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
_queueRegistry = new DefaultQueueRegistry(this);
_exchangeFactory = new DefaultExchangeFactory(this);
- _exchangeFactory.initialise(_vhostConfig);
_exchangeRegistry = new DefaultExchangeRegistry(this);
_bindingFactory = new BindingFactory(this);
- _messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass());
+ _messageStore = initialiseMessageStore(hostConfig);
configureMessageStore(hostConfig);
@@ -187,22 +173,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
return _id;
}
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- public VirtualHostConfigType getConfigType()
- {
- return VirtualHostConfigType.getInstance();
- }
-
- public ConfiguredObject getParent()
- {
- return getBroker();
- }
-
public boolean isDurable()
{
return false;
@@ -216,38 +186,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
*/
private void initialiseHouseKeeping(long period)
{
-
if (period != 0L)
{
scheduleHouseKeepingTask(period, new VirtualHostHouseKeepingTask());
-
- Map<String, VirtualHostPluginFactory> plugins = _appRegistry.getPluginManager().getVirtualHostPlugins();
-
- if (plugins != null)
- {
- for (Map.Entry<String, VirtualHostPluginFactory> entry : plugins.entrySet())
- {
- String pluginName = entry.getKey();
- VirtualHostPluginFactory factory = entry.getValue();
- try
- {
- VirtualHostPlugin plugin = factory.newInstance(this);
-
- // If we had configuration for the plugin the schedule it.
- if (plugin != null)
- {
- _houseKeepingTasks.scheduleAtFixedRate(plugin, plugin.getDelay() / 2,
- plugin.getDelay(), plugin.getTimeUnit());
-
- _logger.info("Loaded VirtualHostPlugin:" + plugin);
- }
- }
- catch (RuntimeException e)
- {
- _logger.error("Unable to load VirtualHostPlugin:" + pluginName + " due to:" + e.getMessage(), e);
- }
- }
- }
}
}
@@ -329,19 +270,34 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
if (!(o instanceof MessageStore))
{
- throw new ClassCastException("Message store factory class must implement " + MessageStore.class +
+ throw new ClassCastException("Message store class must implement " + MessageStore.class +
". Class " + clazz + " does not.");
}
final MessageStore messageStore = (MessageStore) o;
- final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, clazz.getSimpleName());
+ return messageStore;
+ }
+
+ private MessageStore initialiseMessageStore(VirtualHostConfiguration hostConfig) throws Exception
+ {
+ String storeType = hostConfig.getConfig().getString("store.type");
+ MessageStore messageStore = null;
+ if (storeType == null)
+ {
+ messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass());
+ }
+ else
+ {
+ messageStore = new MessageStoreCreator().createMessageStore(storeType);
+ }
+
+ final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, messageStore.getClass().getSimpleName());
OperationalLoggingListener.listen(messageStore, storeLogSubject);
messageStore.addEventListener(new BeforeActivationListener(), Event.BEFORE_ACTIVATE);
messageStore.addEventListener(new AfterActivationListener(), Event.AFTER_ACTIVATE);
messageStore.addEventListener(new BeforeCloseListener(), Event.BEFORE_CLOSE);
messageStore.addEventListener(new BeforePassivationListener(), Event.BEFORE_PASSIVATE);
-
return messageStore;
}
@@ -468,16 +424,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
return _name;
}
- public BrokerConfig getBroker()
- {
- return _brokerConfig;
- }
-
- public String getFederationTag()
- {
- return _brokerConfig.getFederationTag();
- }
-
public long getCreateTime()
{
return _createTime;
@@ -534,14 +480,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
CurrentActor.get().message(VirtualHostMessages.CLOSED());
}
- public UUID getBrokerId()
- {
- return _appRegistry.getBrokerId();
- }
-
- public IApplicationRegistry getApplicationRegistry()
+ public VirtualHostRegistry getVirtualHostRegistry()
{
- return _appRegistry;
+ return _virtualHostRegistry;
}
public BindingFactory getBindingFactory()
@@ -553,14 +494,14 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
{
_messagesDelivered.registerEvent(1L);
_dataDelivered.registerEvent(messageSize);
- _appRegistry.registerMessageDelivered(messageSize);
+ _brokerStatisticsGatherer.registerMessageDelivered(messageSize);
}
public void registerMessageReceived(long messageSize, long timestamp)
{
_messagesReceived.registerEvent(1L, timestamp);
_dataReceived.registerEvent(messageSize, timestamp);
- _appRegistry.registerMessageReceived(messageSize, timestamp);
+ _brokerStatisticsGatherer.registerMessageReceived(messageSize, timestamp);
}
public StatisticsCounter getMessageReceiptStatistics()
@@ -604,51 +545,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
_dataReceived = new StatisticsCounter("bytes-received-" + getName());
}
- public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments)
- {
- BrokerLink blink = new BrokerLink(this, id, createTime, arguments);
- // TODO - cope with duplicate broker link creation requests
- _links.putIfAbsent(blink,blink);
- getConfigStore().addConfiguredObject(blink);
- return blink;
- }
-
- public void createBrokerConnection(final String transport,
- final String host,
- final int port,
- final String vhost,
- final boolean durable,
- final String authMechanism,
- final String username,
- final String password)
- {
- BrokerLink blink = new BrokerLink(this, transport, host, port, vhost, durable, authMechanism, username, password);
-
- // TODO - cope with duplicate broker link creation requests
- _links.putIfAbsent(blink,blink);
- getConfigStore().addConfiguredObject(blink);
-
- }
-
- public void removeBrokerConnection(final String transport,
- final String host,
- final int port,
- final String vhost)
- {
- removeBrokerConnection(new BrokerLink(this, transport, host, port, vhost, false, null,null,null));
-
- }
-
- public void removeBrokerConnection(BrokerLink blink)
- {
- blink = _links.get(blink);
- if(blink != null)
- {
- blink.close();
- getConfigStore().removeConfiguredObject(blink);
- }
- }
-
public synchronized LinkRegistry getLinkRegistry(String remoteContainerId)
{
LinkRegistry linkRegistry = _linkRegistry.get(remoteContainerId);
@@ -660,11 +556,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr
return linkRegistry;
}
- public ConfigStore getConfigStore()
- {
- return getApplicationRegistry().getConfigStore();
- }
-
public DtxRegistry getDtxRegistry()
{
return _dtxRegistry;
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 1be472844a..483e11942b 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
@@ -1,140 +1,95 @@
-/*
- *
- * 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.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;
-
-
-public class VirtualHostRegistry implements Closeable
-{
- private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>();
-
-
- private String _defaultVirtualHostName;
- private ApplicationRegistry _applicationRegistry;
- private final Collection<RegistryChangeListener> _listeners =
- Collections.synchronizedCollection(new ArrayList<RegistryChangeListener>());
-
- public VirtualHostRegistry(ApplicationRegistry applicationRegistry)
- {
- _applicationRegistry = applicationRegistry;
- }
-
- public synchronized void registerVirtualHost(VirtualHost host) throws Exception
- {
- if(_registry.containsKey(host.getName()))
- {
- throw new Exception("Virtual Host with name " + host.getName() + " already registered.");
- }
- _registry.put(host.getName(),host);
- synchronized (_listeners)
+/*
+ *
+ * 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.virtualhost;
+
+import org.apache.qpid.common.Closeable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public class VirtualHostRegistry implements Closeable
+{
+ private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>();
+ private String _defaultVirtualHostName;
+
+
+ public VirtualHostRegistry()
+ {
+ super();
+ }
+
+ public synchronized void registerVirtualHost(VirtualHost host)
+ {
+ if(_registry.containsKey(host.getName()))
{
- for(RegistryChangeListener listener : _listeners)
- {
- listener.virtualHostRegistered(host);
- }
+ throw new IllegalArgumentException("Virtual Host with name " + host.getName() + " already registered.");
}
- }
-
- public synchronized void unregisterVirtualHost(VirtualHost host)
- {
- _registry.remove(host.getName());
- synchronized (_listeners)
+ _registry.put(host.getName(),host);
+ }
+
+ public synchronized void unregisterVirtualHost(VirtualHost host)
+ {
+ _registry.remove(host.getName());
+ }
+
+ public VirtualHost getVirtualHost(String name)
+ {
+ if(name == null || name.trim().length() == 0 || "/".equals(name.trim()))
{
- for(RegistryChangeListener listener : _listeners)
- {
- listener.virtualHostUnregistered(host);
- }
+ name = getDefaultVirtualHostName();
}
- }
-
- public VirtualHost getVirtualHost(String name)
- {
- if(name == null || name.trim().length() == 0 || "/".equals(name.trim()))
- {
- name = getDefaultVirtualHostName();
- }
-
- return _registry.get(name);
- }
-
- public VirtualHost getDefaultVirtualHost()
- {
- return getVirtualHost(getDefaultVirtualHostName());
- }
-
- private String getDefaultVirtualHostName()
- {
- return _defaultVirtualHostName;
- }
-
- public void setDefaultVirtualHostName(String defaultVirtualHostName)
- {
- _defaultVirtualHostName = defaultVirtualHostName;
- }
-
-
- public Collection<VirtualHost> getVirtualHosts()
- {
- return new ArrayList<VirtualHost>(_registry.values());
- }
-
- public ApplicationRegistry getApplicationRegistry()
- {
- return _applicationRegistry;
- }
-
- public ConfigStore getConfigStore()
- {
- return _applicationRegistry.getConfigStore();
- }
-
- public void close()
- {
- for (VirtualHost virtualHost : getVirtualHosts())
- {
- virtualHost.close();
- }
-
- }
-
- public static interface RegistryChangeListener
+
+ return _registry.get(name);
+ }
+
+ public VirtualHost getDefaultVirtualHost()
{
- void virtualHostRegistered(VirtualHost virtualHost);
- void virtualHostUnregistered(VirtualHost virtualHost);
+ return getVirtualHost(getDefaultVirtualHostName());
+ }
+ private String getDefaultVirtualHostName()
+ {
+ return _defaultVirtualHostName;
}
- public void addRegistryChangeListener(RegistryChangeListener listener)
+ public void setDefaultVirtualHostName(String defaultVirtualHostName)
{
- _listeners.add(listener);
+ _defaultVirtualHostName = defaultVirtualHostName;
+ }
+
+
+ public Collection<VirtualHost> getVirtualHosts()
+ {
+ return new ArrayList<VirtualHost>(_registry.values());
+ }
+
+ public void close()
+ {
+ for (VirtualHost virtualHost : getVirtualHosts())
+ {
+ virtualHost.close();
+ }
}
-}
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java
deleted file mode 100644
index 12886f400a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.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.virtualhost.plugins;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.Exchange.BindingListener;
-import org.apache.qpid.server.queue.AMQQueue;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * This is a listener that caches queues that are configured for slow consumer disconnection.
- *
- * There should be one listener per virtual host, which can be added to all exchanges on
- * that host.
- *
- * TODO In future, it will be possible to configure the policy at runtime, so only the queue
- * itself is cached, and the configuration looked up by the housekeeping thread. This means
- * that there may be occasions where the copy of the cache contents retrieved by the thread
- * does not contain queues that are configured, or that configured queues are not present.
- *
- * @see BindingListener
- */
-public class ConfiguredQueueBindingListener implements BindingListener
-{
- private static final Logger _log = Logger.getLogger(ConfiguredQueueBindingListener.class);
-
- private String _vhostName;
- private Set<AMQQueue> _cache = Collections.synchronizedSet(new HashSet<AMQQueue>());
-
- public ConfiguredQueueBindingListener(String vhostName)
- {
- _vhostName = vhostName;
- }
-
- /**
- * @see BindingListener#bindingAdded(Exchange, Binding)
- */
- public void bindingAdded(Exchange exchange, Binding binding)
- {
- processBinding(binding);
- }
-
- /**
- * @see BindingListener#bindingRemoved(Exchange, Binding)
- */
- public void bindingRemoved(Exchange exchange, Binding binding)
- {
- processBinding(binding);
- }
-
- private void processBinding(Binding binding)
- {
- AMQQueue queue = binding.getQueue();
-
- SlowConsumerDetectionQueueConfiguration config =
- queue.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName());
- if (config != null)
- {
- _cache.add(queue);
- }
- else
- {
- _cache.remove(queue);
- }
- }
-
- /**
- * Lookup and return the cache of configured {@link AMQQueue}s.
- *
- * Note that when accessing the cached queues, the {@link java.util.Iterator} is not thread safe
- * (see the {@link Collections#synchronizedSet(Set)} documentation) so a copy of the
- * cache is returned.
- *
- * @return a copy of the cached {@link java.util.Set} of queues
- */
- public Set<AMQQueue> getQueueCache()
- {
- return new HashSet<AMQQueue>(_cache);
- }
-}
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
deleted file mode 100644
index bd2e30449a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java
+++ /dev/null
@@ -1,174 +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.virtualhost.plugins;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration;
-import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.plugins.logging.SlowConsumerDetectionMessages;
-import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin;
-
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin
-{
- private SlowConsumerDetectionConfiguration _config;
- private ConfiguredQueueBindingListener _listener;
-
- public static class SlowConsumerFactory implements VirtualHostPluginFactory
- {
- public SlowConsumerDetection newInstance(VirtualHost vhost)
- {
- SlowConsumerDetectionConfiguration config = vhost.getConfiguration().getConfiguration(SlowConsumerDetectionConfiguration.class.getName());
-
- if (config == null)
- {
- return null;
- }
-
- SlowConsumerDetection plugin = new SlowConsumerDetection(vhost);
- plugin.configure(config);
- return plugin;
- }
- }
-
- /**
- * Configures the slow consumer disconnect plugin by adding a listener to each exchange on this
- * virtual host to record all the configured queues in a cache for processing by the housekeeping
- * thread.
- *
- * @see org.apache.qpid.server.plugins.Plugin#configure(ConfigurationPlugin)
- */
- public void configure(ConfigurationPlugin config)
- {
- _config = (SlowConsumerDetectionConfiguration) config;
- _listener = new ConfiguredQueueBindingListener(getVirtualHost().getName());
- final ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry();
- for (AMQShortString exchangeName : exchangeRegistry.getExchangeNames())
- {
- exchangeRegistry.getExchange(exchangeName).addBindingListener(_listener);
- }
- }
-
- public SlowConsumerDetection(VirtualHost vhost)
- {
- super(vhost);
- }
-
- public void execute()
- {
- CurrentActor.get().message(SlowConsumerDetectionMessages.RUNNING());
-
- Set<AMQQueue> cache = _listener.getQueueCache();
- for (AMQQueue q : cache)
- {
- CurrentActor.get().message(SlowConsumerDetectionMessages.CHECKING_QUEUE(q.getName()));
-
- try
- {
- final SlowConsumerDetectionQueueConfiguration config =
- q.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName());
- if (checkQueueStatus(q, config))
- {
- final SlowConsumerPolicyPlugin policy = config.getPolicy();
- if (policy == null)
- {
- // We would only expect to see this during shutdown
- getLogger().warn("No slow consumer policy for queue " + q.getName());
- }
- else
- {
- policy.performPolicy(q);
- }
-
- }
- }
- catch (Exception e)
- {
- // Don't throw exceptions as this will stop the house keeping task from running.
- getLogger().error("Exception in SlowConsumersDetection for queue: " + q.getName(), e);
- }
- }
-
- CurrentActor.get().message(SlowConsumerDetectionMessages.COMPLETE());
- }
-
- public long getDelay()
- {
- return _config.getDelay();
- }
-
- public TimeUnit getTimeUnit()
- {
- return _config.getTimeUnit();
- }
-
- /**
- * Check the depth,messageSize,messageAge,messageCount values for this q
- *
- * @param q the queue to check
- * @param config the queue configuration to compare against the queue state
- *
- * @return true if the queue has reached a threshold.
- */
- private boolean checkQueueStatus(AMQQueue q, SlowConsumerDetectionQueueConfiguration config)
- {
- if (config != null)
- {
- if (getLogger().isInfoEnabled())
- {
- getLogger().info("Retrieved Queue(" + q.getName() + ") Config:" + config);
- }
-
- int count = q.getMessageCount();
-
- // First Check message counts
- if ((config.getMessageCount() != 0 && count >= config.getMessageCount()) ||
- // The check queue depth
- (config.getDepth() != 0 && q.getQueueDepth() >= config.getDepth()) ||
- // finally if we have messages on the queue check Arrival time.
- // We must check count as OldestArrival time is Long.MAX_LONG when
- // there are no messages.
- (config.getMessageAge() != 0 &&
- ((count > 0) && q.getOldestMessageArrivalTime() >= config.getMessageAge())))
- {
-
- if (getLogger().isDebugEnabled())
- {
- getLogger().debug("Detected Slow Consumer on Queue(" + q.getName() + ")");
- getLogger().debug("Queue Count:" + q.getMessageCount() + ":" + config.getMessageCount());
- getLogger().debug("Queue Depth:" + q.getQueueDepth() + ":" + config.getDepth());
- getLogger().debug("Queue Arrival:" + q.getOldestMessageArrivalTime() + ":" + config.getMessageAge());
- }
-
- return true;
- }
- }
- return false;
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java
deleted file mode 100644
index 35f6228ab9..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java
+++ /dev/null
@@ -1,42 +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.virtualhost.plugins;
-
-import org.apache.qpid.server.plugins.Plugin;
-
-import java.util.concurrent.TimeUnit;
-
-public interface VirtualHostPlugin extends Runnable, Plugin
-{
- /**
- * Long value representing the delay between repeats
- *
- * @return
- */
- public long getDelay();
-
- /**
- * Option to specify what the delay value represents
- * @see java.util.concurrent.TimeUnit for valid value.
- * @return
- */
- public TimeUnit getTimeUnit();
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java
deleted file mode 100644
index c8bea18444..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java
+++ /dev/null
@@ -1,28 +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.virtualhost.plugins;
-
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-public interface VirtualHostPluginFactory
-{
- public VirtualHostHouseKeepingPlugin newInstance(VirtualHost vhost);
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties
deleted file mode 100644
index 03c56910c2..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties
+++ /dev/null
@@ -1,23 +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.
-#
-# Default File used for all non-defined locales.
-
-RUNNING = SCD-1001 : Running
-COMPLETE = SCD-1002 : Complete
-CHECKING_QUEUE = SCD-1003 : Checking Status of Queue {0} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties
deleted file mode 100644
index ed4fb1d45a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties
+++ /dev/null
@@ -1,22 +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.
-#
-# Default File used for all non-defined locales.
-
-DELETING_QUEUE = TDP-1001 : Deleting Queue
-DISCONNECTING = TDP-1002 : Disconnecting Session \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java
deleted file mode 100644
index f2f61f204e..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java
+++ /dev/null
@@ -1,141 +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.virtualhost.plugins.policies;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.exchange.TopicExchange;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.protocol.AMQSessionModel;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.virtualhost.plugins.logging.TopicDeletePolicyMessages;
-import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin;
-import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory;
-
-public class TopicDeletePolicy implements SlowConsumerPolicyPlugin
-{
- private Logger _logger = Logger.getLogger(TopicDeletePolicy.class);
- private TopicDeletePolicyConfiguration _configuration;
-
- public static class TopicDeletePolicyFactory implements SlowConsumerPolicyPluginFactory
- {
- public TopicDeletePolicy newInstance(ConfigurationPlugin configuration) throws ConfigurationException
- {
- TopicDeletePolicyConfiguration config =
- configuration.getConfiguration(TopicDeletePolicyConfiguration.class.getName());
-
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(config);
- return policy;
- }
-
- public String getPluginName()
- {
- return "topicdelete";
- }
-
- public Class<TopicDeletePolicy> getPluginClass()
- {
- return TopicDeletePolicy.class;
- }
- }
-
- public void performPolicy(AMQQueue q)
- {
- if (q == null)
- {
- return;
- }
-
- AMQSessionModel owner = q.getExclusiveOwningSession();
-
- // Only process exclusive queues
- if (owner == null)
- {
- return;
- }
-
- //Only process Topics
- if (!validateQueueIsATopic(q))
- {
- return;
- }
-
- try
- {
- CurrentActor.get().message(owner.getLogSubject(),TopicDeletePolicyMessages.DISCONNECTING());
- // Close the consumer . this will cause autoDelete Queues to be purged
- owner.getConnectionModel().
- closeSession(owner, AMQConstant.RESOURCE_ERROR,
- "Consuming to slow.");
-
- // Actively delete non autoDelete queues if deletePersistent is set
- if (!q.isAutoDelete() && (_configuration != null && _configuration.deletePersistent()))
- {
- CurrentActor.get().message(q.getLogSubject(), TopicDeletePolicyMessages.DELETING_QUEUE());
- q.delete();
- }
-
- }
- catch (AMQException e)
- {
- _logger.warn("Unable to close consumer:" + owner + ", on queue:" + q.getName());
- }
-
- }
-
- /**
- * Check the queue bindings to validate the queue is bound to the
- * topic exchange.
- *
- * @param q the Queue
- *
- * @return true iff Q is bound to a TopicExchange
- */
- private boolean validateQueueIsATopic(AMQQueue q)
- {
- for (Binding binding : q.getBindings())
- {
- if (binding.getExchange() instanceof TopicExchange)
- {
- return true;
- }
- }
-
- return false;
- }
-
- public void configure(ConfigurationPlugin config)
- {
- _configuration = (TopicDeletePolicyConfiguration) config;
- }
-
- @Override
- public String toString()
- {
- return "TopicDelete" + (_configuration == null ? "" : "[" + _configuration + "]");
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java
deleted file mode 100644
index 48158b7dff..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java
+++ /dev/null
@@ -1,82 +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.virtualhost.plugins.policies;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class TopicDeletePolicyConfiguration extends ConfigurationPlugin
-{
-
- public static class TopicDeletePolicyConfigurationFactory
- implements ConfigurationPluginFactory
- {
- public ConfigurationPlugin newInstance(String path,
- Configuration config)
- throws ConfigurationException
- {
- TopicDeletePolicyConfiguration slowConsumerConfig =
- new TopicDeletePolicyConfiguration();
- slowConsumerConfig.setConfiguration(path, config);
- return slowConsumerConfig;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList(
- "virtualhosts.virtualhost.queues.slow-consumer-detection.policy.topicDelete",
- "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy.topicDelete",
- "virtualhosts.virtualhost.topics.slow-consumer-detection.policy.topicDelete",
- "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy.topicDelete");
- }
- }
-
- public String[] getElementsProcessed()
- {
- return new String[]{"delete-persistent"};
- }
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // No validation required.
- }
-
- public boolean deletePersistent()
- {
- // If we don't have configuration then we don't deletePersistent Queues
- return (hasConfiguration() && contains("delete-persistent"));
- }
-
- @Override
- public String formatToString()
- {
- return (deletePersistent()?"delete-durable":"");
- }
-
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java b/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java
deleted file mode 100644
index 7f600abdc9..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java
+++ /dev/null
@@ -1,29 +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.slowconsumerdetection.policies;
-
-import org.apache.qpid.server.plugins.Plugin;
-import org.apache.qpid.server.queue.AMQQueue;
-
-public interface SlowConsumerPolicyPlugin extends Plugin
-{
- public void performPolicy(AMQQueue Queue);
-}
diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory
new file mode 100644
index 0000000000..5f75a8c4c9
--- /dev/null
+++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory
@@ -0,0 +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.
+#
+org.apache.qpid.server.configuration.store.factory.JsonConfigurationStoreFactory
diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory
new file mode 100644
index 0000000000..8ff67030ef
--- /dev/null
+++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory
+org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory
+org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory
+org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManagerFactory
+org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory
+org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManagerFactory
diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType
new file mode 100644
index 0000000000..4ad646b7a0
--- /dev/null
+++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+org.apache.qpid.server.exchange.DirectExchangeType
+org.apache.qpid.server.exchange.TopicExchangeType
+org.apache.qpid.server.exchange.FanoutExchangeType
+org.apache.qpid.server.exchange.HeadersExchangeType
diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory
new file mode 100644
index 0000000000..6bfb55ff18
--- /dev/null
+++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory
@@ -0,0 +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.
+#
+org.apache.qpid.server.security.group.FileGroupManagerFactory
diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory
new file mode 100644
index 0000000000..1357f816b7
--- /dev/null
+++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+org.apache.qpid.server.store.derby.DerbyMessageStoreFactory
+org.apache.qpid.server.store.MemoryMessageStoreFactory \ No newline at end of file
diff --git a/java/broker/src/main/resources/initial-store.json b/java/broker/src/main/resources/initial-store.json
new file mode 100644
index 0000000000..a80ad95bd4
--- /dev/null
+++ b/java/broker/src/main/resources/initial-store.json
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.
+ *
+ */
+{
+ "name": "QpidBroker",
+ "defaultAuthenticationProvider" : "defaultAuthenticationProvider",
+ "defaultVirtualHost" : "default",
+ "authenticationproviders" : [ {
+ "name" : "defaultAuthenticationProvider",
+ "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider",
+ "path" : "${QPID_HOME}/etc/passwd"
+ } ],
+ "ports" : [ {
+ "name" : "5672-AMQP",
+ "port" : 5672
+ }, {
+ "name" : "8080-HTTP",
+ "port" : 8080,
+ "protocols" : [ "HTTP" ]
+ }, {
+ "name" : "8999-RMI",
+ "port" : 8999,
+ "protocols" : [ "RMI" ]
+ }, {
+ "name" : "9099-JMX_RMI",
+ "port" : 9099,
+ "protocols" : [ "JMX_RMI" ]
+ }],
+ "virtualhosts" : [ {
+ "name" : "default",
+ "storeType" : "DERBY",
+ "storePath" : "${QPID_WORK}/store"
+ } ],
+ "plugins" : [ {
+ "pluginType" : "MANAGEMENT-HTTP",
+ "name" : "httpManagement"
+ }, {
+ "pluginType" : "MANAGEMENT-JMX",
+ "name" : "jmxManagement"
+ } ]
+} \ No newline at end of file
diff --git a/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java b/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java
index fc6cbcb248..e10bdbbb35 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java
@@ -20,23 +20,69 @@
*/
package org.apache.qpid.server;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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.MessagePublishInfo;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class AMQChannelTest extends InternalBrokerBaseCase
+public class AMQChannelTest extends QpidTestCase
{
private VirtualHost _virtualHost;
private AMQProtocolSession _protocolSession;
+ private Map<Integer,String> _replies;
+ private Broker _broker;
@Override
public void setUp() throws Exception
{
super.setUp();
- _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next();
- _protocolSession = new InternalTestProtocolSession(_virtualHost);
+ BrokerTestHelper.setUp();
+ _virtualHost = BrokerTestHelper.createVirtualHost(getTestName());
+ _broker = BrokerTestHelper.createBrokerMock();
+ _protocolSession = new InternalTestProtocolSession(_virtualHost, _broker)
+ {
+ @Override
+ public void writeReturn(MessagePublishInfo messagePublishInfo,
+ ContentHeaderBody header,
+ MessageContentSource msgContent,
+ int channelId,
+ int replyCode,
+ AMQShortString replyText) throws AMQException
+ {
+ _replies.put(replyCode, replyText.asString());
+ }
+ };
+ _replies = new HashMap<Integer, String>();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ _virtualHost.close();
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
public void testCompareTo() throws Exception
@@ -44,9 +90,54 @@ public class AMQChannelTest extends InternalBrokerBaseCase
AMQChannel channel1 = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore());
// create a channel with the same channelId but on a different session
- AMQChannel channel2 = new AMQChannel(new InternalTestProtocolSession(_virtualHost), 1, _virtualHost.getMessageStore());
+ AMQChannel channel2 = new AMQChannel(new InternalTestProtocolSession(_virtualHost, _broker), 1, _virtualHost.getMessageStore());
assertFalse("Unexpected compare result", channel1.compareTo(channel2) == 0);
assertEquals("Unexpected compare result", 0, channel1.compareTo(channel1));
}
+ public void testPublishContentHeaderWhenMessageAuthorizationFails() throws Exception
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_MSG_AUTH, "true");
+ AMQChannel channel = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore());
+ channel.setLocalTransactional();
+
+ MessagePublishInfo info = mock(MessagePublishInfo.class);
+ Exchange e = mock(Exchange.class);
+ ContentHeaderBody contentHeaderBody= mock(ContentHeaderBody.class);
+ BasicContentHeaderProperties properties = mock(BasicContentHeaderProperties.class);
+
+ when(contentHeaderBody.getProperties()).thenReturn(properties);
+ when(info.getExchange()).thenReturn(new AMQShortString("test"));
+ when(properties.getUserId()).thenReturn(new AMQShortString(_protocolSession.getAuthorizedPrincipal().getName() + "_incorrect"));
+
+ channel.setPublishFrame(info, e);
+ channel.publishContentHeader(contentHeaderBody);
+ channel.commit();
+
+ assertEquals("Unexpected number of replies", 1, _replies.size());
+ assertEquals("Message authorization passed", "Access Refused", _replies.get(403));
+ }
+
+ public void testPublishContentHeaderWhenMessageAuthorizationPasses() throws Exception
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_MSG_AUTH, "true");
+ AMQChannel channel = new AMQChannel(_protocolSession, 1, _virtualHost.getMessageStore());
+ channel.setLocalTransactional();
+
+ MessagePublishInfo info = mock(MessagePublishInfo.class);
+ Exchange e = mock(Exchange.class);
+ ContentHeaderBody contentHeaderBody= mock(ContentHeaderBody.class);
+ BasicContentHeaderProperties properties = mock(BasicContentHeaderProperties.class);
+
+ when(contentHeaderBody.getProperties()).thenReturn(properties);
+ when(info.getExchange()).thenReturn(new AMQShortString("test"));
+ when(properties.getUserId()).thenReturn(new AMQShortString(_protocolSession.getAuthorizedPrincipal().getName()));
+
+ channel.setPublishFrame(info, e);
+ channel.publishContentHeader(contentHeaderBody);
+ channel.commit();
+
+ assertEquals("Unexpected number of replies", 0, _replies.size());
+ }
+
}
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 43824e713f..16b459b5d4 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
@@ -22,91 +22,36 @@ package org.apache.qpid.server;
import org.apache.qpid.test.utils.QpidTestCase;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-
public class BrokerOptionsTest extends QpidTestCase
{
private BrokerOptions _options;
-
- private static final int TEST_PORT1 = 6789;
- private static final int TEST_PORT2 = 6790;
-
protected void setUp()
{
_options = new BrokerOptions();
}
-
- public void testDefaultPort()
- {
- assertEquals(Collections.<Integer>emptySet(), _options.getPorts());
- }
- public void testOverriddenPort()
+ public void testDefaultConfigurationStoreType()
{
- _options.addPort(TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getPorts());
+ assertEquals("json", _options.getConfigurationStoreType());
}
- public void testManyOverriddenPorts()
+ public void testOverriddenConfigurationStoreType()
{
- _options.addPort(TEST_PORT1);
- _options.addPort(TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getPorts());
+ _options.setConfigurationStoreType("dby");
+ assertEquals("dby", _options.getConfigurationStoreType());
}
- public void testDuplicateOverriddenPortsAreSilentlyIgnored()
+ public void testDefaultConfigurationStoreLocation()
{
- _options.addPort(TEST_PORT1);
- _options.addPort(TEST_PORT2);
- _options.addPort(TEST_PORT1); // duplicate - should be silently ignored
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getPorts());
+ assertNull(_options.getConfigurationStoreLocation());
}
- public void testDefaultSSLPort()
- {
- assertEquals(Collections.<Integer>emptySet(), _options.getSSLPorts());
- }
-
- public void testOverriddenSSLPort()
- {
- _options.addSSLPort(TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getSSLPorts());
- }
-
- public void testManyOverriddenSSLPorts()
- {
- _options.addSSLPort(TEST_PORT1);
- _options.addSSLPort(TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getSSLPorts());
- }
-
- public void testDuplicateOverriddenSSLPortsAreSilentlyIgnored()
- {
- _options.addSSLPort(TEST_PORT1);
- _options.addSSLPort(TEST_PORT2);
- _options.addSSLPort(TEST_PORT1); // duplicate - should be silently ignored
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getSSLPorts());
- }
-
- public void testDefaultConfigFile()
- {
- assertNull(_options.getConfigFile());
- }
-
- public void testOverriddenConfigFile()
+ public void testOverriddenConfigurationStoreLocation()
{
final String testConfigFile = "etc/mytestconfig.xml";
- _options.setConfigFile(testConfigFile);
- assertEquals(testConfigFile, _options.getConfigFile());
+ _options.setConfigurationStoreLocation(testConfigFile);
+ assertEquals(testConfigFile, _options.getConfigurationStoreLocation());
}
public void testDefaultLogConfigFile()
@@ -121,109 +66,85 @@ public class BrokerOptionsTest extends QpidTestCase
assertEquals(testLogConfigFile, _options.getLogConfigFile());
}
- public void testDefaultJmxPortRegistryServer()
+ public void testDefaultLogWatchFrequency()
{
- assertNull(_options.getJmxPortRegistryServer());
+ assertEquals(0L, _options.getLogWatchFrequency());
}
- public void testJmxPortRegistryServer()
+ public void testOverridenLogWatchFrequency()
{
- _options.setJmxPortRegistryServer(TEST_PORT1);
- assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPortRegistryServer());
+ final int myFreq = 10 * 1000;
+
+ _options.setLogWatchFrequency(myFreq);
+ assertEquals(myFreq, _options.getLogWatchFrequency());
}
- public void testDefaultJmxPortConnectorServer()
- {
- assertNull(_options.getJmxPortConnectorServer());
- }
- public void testJmxPortConnectorServer()
+ public void testDefaultInitialConfigurationStoreType()
{
- _options.setJmxPortConnectorServer(TEST_PORT1);
- assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPortConnectorServer());
+ assertEquals("json", _options.getInitialConfigurationStoreType());
}
- public void testQpidHomeExposesSysProperty()
+ public void testOverriddenInitialConfigurationStoreType()
{
- assertEquals(System.getProperty("QPID_HOME"), _options.getQpidHome());
- }
-
- public void testDefaultExcludesPortFor0_10()
- {
- assertEquals(Collections.EMPTY_SET, _options.getExcludedPorts(ProtocolExclusion.v0_10));
- }
-
- public void testOverriddenExcludesPortFor0_10()
- {
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getExcludedPorts(ProtocolExclusion.v0_10));
+ _options.setInitialConfigurationStoreType("dby");
+ assertEquals("dby", _options.getInitialConfigurationStoreType());
}
- public void testManyOverriddenExcludedPortFor0_10()
+ public void testDefaultInitialConfigurationStoreLocation()
{
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10));
+ assertNull(_options.getInitialConfigurationStoreLocation());
}
- public void testDuplicatedOverriddenExcludedPortFor0_10AreSilentlyIgnored()
+ public void testOverriddenInitialConfigurationStoreLocation()
{
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10));
+ final String testConfigFile = "etc/mytestconfig.xml";
+ _options.setInitialConfigurationStoreLocation(testConfigFile);
+ assertEquals(testConfigFile, _options.getInitialConfigurationStoreLocation());
}
-
- public void testDefaultBind()
+
+ public void testDefaultManagementMode()
{
- assertNull(_options.getBind());
+ assertEquals(false, _options.isManagementMode());
}
-
- public void testOverriddenBind()
+
+ public void testOverriddenDefaultManagementMode()
{
- final String bind = "192.168.0.1";
- _options.setBind(bind);
- assertEquals(bind, _options.getBind());
+ _options.setManagementMode(true);
+ assertEquals(true, _options.isManagementMode());
}
- public void testDefaultLogWatchFrequency()
+ public void testDefaultManagementModeRmiPort()
{
- assertEquals(0L, _options.getLogWatchFrequency());
+ assertEquals(0, _options.getManagementModeRmiPort());
}
- public void testOverridenLogWatchFrequency()
+ public void testOverriddenDefaultManagementModeRmiPort()
{
- final int myFreq = 10 * 1000;
-
- _options.setLogWatchFrequency(myFreq);
- assertEquals(myFreq, _options.getLogWatchFrequency());
+ _options.setManagementModeRmiPort(5555);
+ assertEquals(5555, _options.getManagementModeRmiPort());
}
- public void testDefaultIncludesPortFor0_10()
+ public void testDefaultManagementModeConnectorPort()
{
- assertEquals(Collections.EMPTY_SET, _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ assertEquals(0, _options.getManagementModeConnectorPort());
}
- public void testOverriddenIncludesPortFor0_10()
+ public void testOverriddenDefaultManagementModeConnectorPort()
{
- _options.addIncludedPort(ProtocolInclusion.v0_10, TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getIncludedPorts(ProtocolInclusion.v0_10));
+ _options.setManagementModeConnectorPort(5555);
+ assertEquals(5555, _options.getManagementModeConnectorPort());
}
- public void testManyOverriddenIncludedPortFor0_10()
+ public void testDefaultManagementModeHttpPort()
{
- _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));
+ assertEquals(0, _options.getManagementModeHttpPort());
}
- public void testDuplicatedOverriddenIncludedPortFor0_10AreSilentlyIgnored()
+ public void testOverriddenDefaultManagementModeHttpPort()
{
- _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));
+ _options.setManagementModeHttpPort(5555);
+ assertEquals(5555, _options.getManagementModeHttpPort());
}
+
}
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 ffd607574e..cab54b1310 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
@@ -23,8 +23,6 @@ package org.apache.qpid.server;
import org.apache.commons.cli.CommandLine;
import org.apache.qpid.test.utils.QpidTestCase;
-import java.util.EnumSet;
-
/**
* Test to verify the command line parsing within the Main class, by
* providing it a series of command line arguments and verifying the
@@ -36,149 +34,135 @@ public class MainTest extends QpidTestCase
{
BrokerOptions options = startDummyMain("");
- assertTrue(options.getPorts().isEmpty());
- assertTrue(options.getSSLPorts().isEmpty());
- assertEquals(null, options.getJmxPortRegistryServer());
- assertEquals(null, options.getConfigFile());
+ assertEquals("json", options.getConfigurationStoreType());
+ assertEquals(null, options.getConfigurationStoreLocation());
assertEquals(null, options.getLogConfigFile());
- assertEquals(null, options.getBind());
-
- for(ProtocolExclusion pe : EnumSet.allOf(ProtocolExclusion.class))
- {
- assertEquals(0, options.getExcludedPorts(pe).size());
- }
+ assertEquals(0, options.getLogWatchFrequency());
+ assertEquals("json", options.getInitialConfigurationStoreType());
+ assertEquals(null, options.getInitialConfigurationStoreLocation());
- for(ProtocolInclusion pe : EnumSet.allOf(ProtocolInclusion.class))
- {
- assertEquals(0, options.getIncludedPorts(pe).size());
- }
+ assertFalse(options.isManagementMode());
+ assertEquals(0, options.getManagementModeConnectorPort());
+ assertEquals(0, options.getManagementModeRmiPort());
+ assertEquals(0, options.getManagementModeHttpPort());
}
- public void testPortOverriddenSingle()
+ public void testConfigurationStoreLocation()
{
- BrokerOptions options = startDummyMain("-p 1234");
+ BrokerOptions options = startDummyMain("-sp abcd/config.xml");
+ assertEquals("abcd/config.xml", options.getConfigurationStoreLocation());
- assertTrue(options.getPorts().contains(1234));
- assertEquals(1, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
+ options = startDummyMain("-store-path abcd/config2.xml");
+ assertEquals("abcd/config2.xml", options.getConfigurationStoreLocation());
}
- public void testPortOverriddenMultiple()
+ public void testConfigurationStoreType()
{
- BrokerOptions options = startDummyMain("-p 1234 -p 4321");
+ BrokerOptions options = startDummyMain("-st dby");
+ assertEquals("dby", options.getConfigurationStoreType());
- assertTrue(options.getPorts().contains(1234));
- assertTrue(options.getPorts().contains(4321));
- assertEquals(2, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
+ options = startDummyMain("-store-type bdb");
+ assertEquals("bdb", options.getConfigurationStoreType());
}
- public void testSSLPortOverriddenSingle()
+ public void testLogConfig()
{
- BrokerOptions options = startDummyMain("-s 5678");
+ BrokerOptions options = startDummyMain("-l wxyz/log4j.xml");
- assertTrue(options.getSSLPorts().contains(5678));
- assertEquals(1, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
+ assertEquals("wxyz/log4j.xml", options.getLogConfigFile());
}
- public void testSSLPortOverriddenMultiple()
+ public void testLogWatch()
{
- BrokerOptions options = startDummyMain("-s 5678 -s 8765");
+ BrokerOptions options = startDummyMain("-w 9");
- assertTrue(options.getSSLPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(2, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
+ assertEquals(9, options.getLogWatchFrequency());
}
- public void testNonSSLandSSLPortsOverridden()
+ public void testVersion()
{
- BrokerOptions options = startDummyMain("-p 5678 -s 8765");
+ final TestMain main = new TestMain("-v".split("\\s"));
- assertTrue(options.getPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(1, options.getPorts().size());
- assertEquals(1, options.getSSLPorts().size());
+ assertNotNull("Command line not parsed correctly", main.getCommandLine());
+ assertTrue("Parsed command line didnt pick up version option", main.getCommandLine().hasOption("v"));
}
- public void testJmxPortRegistryServerOverridden()
+ public void testHelp()
{
- BrokerOptions options = startDummyMain("--jmxregistryport 3456");
-
- assertEquals(Integer.valueOf(3456), options.getJmxPortRegistryServer());
+ final TestMain main = new TestMain("-h".split("\\s"));
- options = startDummyMain("-m 3457");
- assertEquals(Integer.valueOf(3457), options.getJmxPortRegistryServer());
+ assertNotNull("Command line not parsed correctly", main.getCommandLine());
+ assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h"));
}
- public void testJmxPortConnectorServerOverridden()
+ public void testInitailConfigurationStoreLocation()
{
- BrokerOptions options = startDummyMain("--jmxconnectorport 3456");
+ BrokerOptions options = startDummyMain("-isp abcd/config.xml");
+ assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation());
- assertEquals(Integer.valueOf(3456), options.getJmxPortConnectorServer());
+ options = startDummyMain("-initial-store-path abcd/config.xml");
+ assertEquals("abcd/config.xml", options.getInitialConfigurationStoreLocation());
}
- public void testExclude0_10()
+ public void testInitialConfigurationStoreType()
{
- BrokerOptions options = startDummyMain("-p 3456 --exclude-0-10 3456");
+ BrokerOptions options = startDummyMain("-ist dby");
+ assertEquals("dby", options.getInitialConfigurationStoreType());
- assertTrue(options.getPorts().contains(3456));
- assertEquals(1, options.getPorts().size());
- assertTrue(options.getExcludedPorts(ProtocolExclusion.v0_10).contains(3456));
- assertEquals(1, options.getExcludedPorts(ProtocolExclusion.v0_10).size());
- assertEquals(0, options.getExcludedPorts(ProtocolExclusion.v0_9_1).size());
- }
-
- public void testConfig()
- {
- BrokerOptions options = startDummyMain("-c abcd/config.xml");
+ options = startDummyMain("-initial-store-type bdb");
+ assertEquals("bdb", options.getInitialConfigurationStoreType());
- assertEquals("abcd/config.xml", options.getConfigFile());
}
- public void testLogConfig()
+ public void testManagementMode()
{
- BrokerOptions options = startDummyMain("-l wxyz/log4j.xml");
+ BrokerOptions options = startDummyMain("-mm");
+ assertTrue(options.isManagementMode());
- assertEquals("wxyz/log4j.xml", options.getLogConfigFile());
+ options = startDummyMain("--management-mode");
+ assertTrue(options.isManagementMode());
}
- public void testLogWatch()
+ public void testManagementModeRmiPort()
{
- BrokerOptions options = startDummyMain("-w 9");
+ BrokerOptions options = startDummyMain("-mm -rmi 7777");
+ assertTrue(options.isManagementMode());
+ assertEquals(7777, options.getManagementModeRmiPort());
- assertEquals(9, options.getLogWatchFrequency());
+ options = startDummyMain("-mm --jmxregistryport 7777");
+ assertTrue(options.isManagementMode());
+ assertEquals(7777, options.getManagementModeRmiPort());
+
+ options = startDummyMain("-rmi 7777");
+ assertEquals(0, options.getManagementModeRmiPort());
}
- public void testVersion()
+ public void testManagementModeConnectorPort()
{
- final TestMain main = new TestMain("-v".split("\\s"));
+ BrokerOptions options = startDummyMain("-mm -jmxrmi 8888");
+ assertTrue(options.isManagementMode());
+ assertEquals(8888, options.getManagementModeConnectorPort());
- assertNotNull("Command line not parsed correctly", main.getCommandLine());
- assertTrue("Parsed command line didnt pick up version option", main.getCommandLine().hasOption("v"));
+ options = startDummyMain("-mm --jmxconnectorport 8888");
+ assertTrue(options.isManagementMode());
+ assertEquals(8888, options.getManagementModeConnectorPort());
+
+ options = startDummyMain("-jmxrmi 8888");
+ assertEquals(0, options.getManagementModeConnectorPort());
}
- public void testHelp()
+ public void testManagementModeHttpPort()
{
- final TestMain main = new TestMain("-h".split("\\s"));
+ BrokerOptions options = startDummyMain("-mm -http 9999");
+ assertTrue(options.isManagementMode());
+ assertEquals(9999, options.getManagementModeHttpPort());
- assertNotNull("Command line not parsed correctly", main.getCommandLine());
- assertTrue("Parsed command line didnt pick up help option", main.getCommandLine().hasOption("h"));
- }
+ options = startDummyMain("-mm --httpport 9999");
+ assertTrue(options.isManagementMode());
+ assertEquals(9999, options.getManagementModeHttpPort());
- 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());
+ options = startDummyMain("-http 9999");
+ assertEquals(0, options.getManagementModeHttpPort());
}
private BrokerOptions startDummyMain(String commandLine)
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
index 9081dc49d6..96078d766c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/TransactionTimeoutHelperTest.java
@@ -18,67 +18,131 @@
*/
package org.apache.qpid.server;
-import static org.mockito.Matchers.any;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.qpid.server.logging.messages.ChannelMessages.IDLE_TXN_LOG_HIERARCHY;
+import static org.apache.qpid.server.logging.messages.ChannelMessages.OPEN_TXN_LOG_HIERARCHY;
+import static org.mockito.Matchers.argThat;
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.TransactionTimeoutHelper.CloseAction;
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.server.txn.ServerTransaction;
import org.apache.qpid.test.utils.QpidTestCase;
+import org.hamcrest.Description;
+import org.mockito.ArgumentMatcher;
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 final ServerTransaction _transaction = mock(ServerTransaction.class);
+ private final CloseAction _closeAction = mock(CloseAction.class);
private TransactionTimeoutHelper _transactionTimeoutHelper;
- private RootMessageLogger _rootMessageLogger;
+ private long _now;
- public void testLogIfNecessary()
+ public void testNotTransactional() throws Exception
{
- _transactionTimeoutHelper.logIfNecessary(99, 100, _logMessage, "");
- verifyZeroInteractions(_logActor, _logMessage);
+ when(_transaction.isTransactional()).thenReturn(false);
- _transactionTimeoutHelper.logIfNecessary(101, 100, _logMessage, "");
- verify(_logActor).message(_logSubject, _logMessage);
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 5, 10, 5, 10);
+
+ verifyZeroInteractions(_logActor, _closeAction);
+ }
+
+ public void testOpenTransactionProducesWarningOnly() throws Exception
+ {
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+
+ configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(30), 0, 0, 0);
+
+ verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
+ verifyZeroInteractions(_closeAction);
+ }
+
+ public void testOpenTransactionProducesTimeoutActionOnly() throws Exception
+ {
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+
+ configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, SECONDS.toMillis(30), 0, 0);
+
+ verify(_closeAction).doTimeoutAction("Open transaction timed out");
+ verifyZeroInteractions(_logActor);
}
- public void testLogIfNecessaryWhenOperationalLoggingDisabled()
+ public void testOpenTransactionProducesWarningAndTimeoutAction() throws Exception
{
- //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));
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+
+ configureMockTransaction(sixtyOneSecondsAgo, sixtyOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(15), SECONDS.toMillis(30), 0, 0);
+
+ verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
+ verify(_closeAction).doTimeoutAction("Open transaction timed out");
}
- public void testIsTimedOut()
+ public void testIdleTransactionProducesWarningOnly() throws Exception
{
- assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(199,200));
- assertTrue("Should have timed out", _transactionTimeoutHelper.isTimedOut(201,200));
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+ final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
+
+ configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(30), 0);
+
+ verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
+ verifyZeroInteractions(_closeAction);
}
- /**
- * If TransactionTimeout is disabled, the timeout will be 0. This test verifies
- * that the helper methods respond negatively in this scenario.
- */
- public void testTransactionTimeoutDisabled()
+ public void testIdleTransactionProducesTimeoutActionOnly() throws Exception
{
- assertFalse("Shouldn't have timed out", _transactionTimeoutHelper.isTimedOut(201,0));
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+ final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
+
+ configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
- _transactionTimeoutHelper.logIfNecessary(99, 0, _logMessage, "");
- verifyZeroInteractions(_logActor, _logMessage);
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, 0, SECONDS.toMillis(30));
+
+ verify(_closeAction).doTimeoutAction("Idle transaction timed out");
+ verifyZeroInteractions(_logActor);
+ }
+
+ public void testIdleTransactionProducesWarningAndTimeoutAction() throws Exception
+ {
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+ final long thrityOneSecondsAgo = _now - SECONDS.toMillis(31);
+
+ configureMockTransaction(sixtyOneSecondsAgo, thrityOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, 0, 0, SECONDS.toMillis(15), SECONDS.toMillis(30));
+
+ verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
+ verify(_closeAction).doTimeoutAction("Idle transaction timed out");
+ }
+
+ public void testIdleAndOpenWarnings() throws Exception
+ {
+ final long sixtyOneSecondsAgo = _now - SECONDS.toMillis(61);
+ final long thirtyOneSecondsAgo = _now - SECONDS.toMillis(31);
+
+ configureMockTransaction(sixtyOneSecondsAgo, thirtyOneSecondsAgo);
+
+ _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, SECONDS.toMillis(60), 0, SECONDS.toMillis(30), 0);
+
+ verify(_logActor).message(same(_logSubject), isLogMessage(IDLE_TXN_LOG_HIERARCHY, "CHN-1008 : Idle Transaction : 31,\\d{3} ms"));
+ verify(_logActor).message(same(_logSubject), isLogMessage(OPEN_TXN_LOG_HIERARCHY, "CHN-1007 : Open Transaction : 61,\\d{3} ms"));
+ verifyZeroInteractions(_closeAction);
}
@Override
@@ -88,14 +152,79 @@ public class TransactionTimeoutHelperTest extends QpidTestCase
CurrentActor.set(_logActor);
- _rootMessageLogger = mock(RootMessageLogger.class);
- when(_logActor.getRootMessageLogger()).thenReturn(_rootMessageLogger);
+ _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, _closeAction);
+ _now = System.currentTimeMillis();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ CurrentActor.remove();
+ }
+ }
- when(_rootMessageLogger.isMessageEnabled(
- same(_logActor), any(LogSubject.class), any(String.class)))
- .thenReturn(true);
+ private void configureMockTransaction(final long startTime, final long updateTime)
+ {
+ when(_transaction.isTransactional()).thenReturn(true);
+ when(_transaction.getTransactionStartTime()).thenReturn(startTime);
+ when(_transaction.getTransactionUpdateTime()).thenReturn(updateTime);
+ }
- _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject);
+ private LogMessage isLogMessage(String expectedlogHierarchy, String expectedText)
+ {
+ return argThat(new IsLogMessage(expectedlogHierarchy, expectedText));
}
+ class IsLogMessage extends ArgumentMatcher<LogMessage>
+ {
+ private final String _expectedLogHierarchy;
+ private final String _expectedLogMessageMatches;
+ private String _hierarchyMatchesFailure;
+ private String _logMessageMatchesFailure;
+
+ public IsLogMessage(String expectedlogHierarchy, String expectedLogMessageMatches)
+ {
+ _expectedLogHierarchy = expectedlogHierarchy;
+ _expectedLogMessageMatches = expectedLogMessageMatches;
+ }
+
+ public boolean matches(Object arg)
+ {
+ LogMessage logMessage = (LogMessage)arg;
+
+ boolean hierarchyMatches = logMessage.getLogHierarchy().equals(_expectedLogHierarchy);
+ boolean logMessageMatches = logMessage.toString().matches(_expectedLogMessageMatches);
+
+ if (!hierarchyMatches)
+ {
+ _hierarchyMatchesFailure = "LogHierarchy does not match. Expected " + _expectedLogHierarchy + " actual " + logMessage.getLogHierarchy();
+ }
+
+ if (!logMessageMatches)
+ {
+ _logMessageMatchesFailure = "LogMessage does not match. Expected " + _expectedLogMessageMatches + " actual " + logMessage.toString();
+ }
+
+ return hierarchyMatches && logMessageMatches;
+ }
+
+ @Override
+ public void describeTo(Description description)
+ {
+ if (_hierarchyMatchesFailure != null)
+ {
+ description.appendText(_hierarchyMatchesFailure);
+ }
+ if (_logMessageMatchesFailure != null)
+ {
+ description.appendText(_logMessageMatchesFailure);
+ }
+ }
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java b/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java
index b3223f16c4..4d6d60906d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/ack/AcknowledgeTest.java
@@ -22,14 +22,72 @@ package org.apache.qpid.server.ack;
import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.List;
-public class AcknowledgeTest extends InternalBrokerBaseCase
+public class AcknowledgeTest extends QpidTestCase
{
+ private AMQChannel _channel;
+ private SimpleAMQQueue _queue;
+ private MessageStore _messageStore;
+ private String _queueName;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _channel = BrokerTestHelper.createChannel();
+ VirtualHost virtualHost = _channel.getVirtualHost();
+ _queueName = getTestName();
+ _queue = BrokerTestHelper.createQueue(_queueName, virtualHost);
+ _messageStore = virtualHost.getMessageStore();
+ Exchange defaultExchange = virtualHost.getExchangeRegistry().getDefaultExchange();
+ virtualHost.getBindingFactory().addBinding(_queueName, _queue, defaultExchange, null);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_channel != null)
+ {
+ _channel.getVirtualHost().close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
+ private AMQChannel getChannel()
+ {
+ return _channel;
+ }
+
+ private InternalTestProtocolSession getSession()
+ {
+ return (InternalTestProtocolSession)_channel.getProtocolSession();
+ }
+
+ private SimpleAMQQueue getQueue()
+ {
+ return _queue;
+ }
public void testTransactionalSingleAck() throws AMQException
{
@@ -70,7 +128,7 @@ public class AcknowledgeTest extends InternalBrokerBaseCase
checkStoreContents(0);
//Send required messsages to the queue
- publishMessages(getSession(), getChannel(), sendMessageCount);
+ BrokerTestHelper.publishMessages(getChannel(), sendMessageCount, _queueName, ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString());
if (getChannel().isTransactional())
{
@@ -84,7 +142,7 @@ public class AcknowledgeTest extends InternalBrokerBaseCase
assertEquals("Channel should have no unacked msgs ", 0, getChannel().getUnacknowledgedMessageMap().size());
//Subscribe to the queue
- AMQShortString subscriber = subscribe(getSession(), getChannel(), getQueue());
+ AMQShortString subscriber = _channel.subscribeToQueue(null, _queue, true, null, false, true);
getQueue().deliverAsync();
@@ -117,4 +175,9 @@ public class AcknowledgeTest extends InternalBrokerBaseCase
checkStoreContents(remainingUnackedMessages);
}
+ private void checkStoreContents(int messageCount)
+ {
+ assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount());
+ }
+
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java
new file mode 100644
index 0000000000..fa1bd966a7
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreatorTest.java
@@ -0,0 +1,144 @@
+/*
+ *
+ * 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;
+
+import java.io.File;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+
+public class BrokerConfigurationStoreCreatorTest extends QpidTestCase
+{
+ private File _userStoreLocation;
+ private BrokerConfigurationStoreCreator _storeCreator;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ // check whether QPID_HOME JVM system property is set
+ if (QPID_HOME == null)
+ {
+ // set the properties in order to resolve the defaults store settings
+ setTestSystemProperty("QPID_HOME", TMP_FOLDER);
+ }
+ _storeCreator = new BrokerConfigurationStoreCreator();
+ _userStoreLocation = new File(TMP_FOLDER, "_store_" + System.currentTimeMillis() + "_" + getTestName());
+ }
+
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ if (_userStoreLocation != null)
+ {
+ FileUtils.delete(_userStoreLocation, true);
+ }
+ }
+ }
+
+ public void testCreateJsonStore()
+ {
+ ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", null, null);
+ assertNotNull("Store was not created", store);
+ assertTrue("File should exists", _userStoreLocation.exists());
+ assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0);
+ JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore();
+ jsonStore.open(_userStoreLocation.getAbsolutePath());
+ Set<UUID> childrenIds = jsonStore.getRootEntry().getChildrenIds();
+ assertFalse("Unexpected children: " + childrenIds, childrenIds.isEmpty());
+ }
+
+ public void testCreateJsonStoreFromInitialStore() throws Exception
+ {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+
+ Map<String, Object> brokerObjectMap = new HashMap<String, Object>();
+ UUID brokerId = UUID.randomUUID();
+ brokerObjectMap.put(Broker.ID, brokerId);
+ brokerObjectMap.put("name", "Test");
+
+ StringWriter sw = new StringWriter();
+ objectMapper.writeValue(sw, brokerObjectMap);
+
+ String brokerJson = sw.toString();
+
+ File _storeFile = TestFileUtils.createTempFile(this, ".json", brokerJson);
+
+ ConfigurationEntryStore store = _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "json", _storeFile.getAbsolutePath(), "json");
+ assertNotNull("Store was not created", store);
+ assertTrue("File should exists", _userStoreLocation.exists());
+ assertTrue("File size should be greater than 0", _userStoreLocation.length() > 0);
+ JsonConfigurationEntryStore jsonStore = new JsonConfigurationEntryStore();
+ jsonStore.open(_userStoreLocation.getAbsolutePath());
+ ConfigurationEntry entry = jsonStore.getRootEntry();
+ assertEquals("Unexpected root id", brokerId, entry.getId());
+ Map<String, Object> attributes = entry.getAttributes();
+ assertNotNull("Unexpected attributes: " + attributes, attributes);
+ assertEquals("Unexpected attributes size: " + attributes.size(), 1, attributes.size());
+ assertEquals("Unexpected attribute name: " + attributes.get("name"), "Test", attributes.get("name"));
+ Set<UUID> childrenIds = entry.getChildrenIds();
+ assertTrue("Unexpected children: " + childrenIds, childrenIds.isEmpty());
+ }
+
+ public void testCreateDerbyStore()
+ {
+ //TODO: Implement DERBY store
+ try
+ {
+ _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "derby", null, null);
+ fail("Store is not yet supported");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+ public void testCreateXmlStore() throws Exception
+ {
+ try
+ {
+ _storeCreator.createStore(_userStoreLocation.getAbsolutePath(), "xml", null, null);
+ fail("Store is not yet supported");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java
new file mode 100644
index 0000000000..5e9e19ffaf
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/BrokerPropertiesTest.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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;
+
+import java.util.Locale;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class BrokerPropertiesTest extends QpidTestCase
+{
+ public void testGetLocaleDefault()
+ {
+ Locale locale = BrokerProperties.getLocale();
+ assertEquals("Unexpected locale", Locale.US, locale);
+ }
+
+ public void testGetLocaleSetWithJVMProperty()
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_LOCALE, "en_GB");
+ Locale locale = BrokerProperties.getLocale();
+ assertEquals("Unexpected locale", Locale.UK, locale);
+ }
+
+ public void testGetLocaleSetWithJVMPropertyInUnexpectedFormat()
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_LOCALE, "penguins_ANTARCTIC_Moubray_Bay");
+ Locale locale = BrokerProperties.getLocale();
+ assertEquals("Unexpected locale language", "penguins", locale.getLanguage());
+ assertEquals("Unexpected locale country", "ANTARCTIC", locale.getCountry());
+ assertEquals("Unexpected locale country", "Moubray_Bay", locale.getVariant());
+ }
+
+}
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
deleted file mode 100644
index 00e5cd1222..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/MockConnectionConfig.java
+++ /dev/null
@@ -1,171 +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;
-
-import java.util.UUID;
-
-public class MockConnectionConfig implements ConnectionConfig
-{
-
- 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._qmfId = _qmfId;
- this._configType = _configType;
- this._parent = _parent;
- this._durable = _durable;
- this._createTime = _createTime;
- this._virtualHost = _virtualHost;
- this._address = _address;
- this._incoming = _incoming;
- this._systemConnection = _systemConnection;
- this._federationLink = _federationLink;
- this._authId = _authId;
- this._remoteProcessName = _remoteProcessName;
- this._remotePID = _remotePID;
- this._remoteParentPID = _remoteParentPID;
- this._configStore = _configStore;
- this._shadow = _shadow;
- }
-
- private UUID _qmfId;
- private ConnectionConfigType _configType;
- private ConfiguredObject<ConnectionConfigType, ConnectionConfig> _parent;
- private boolean _durable;
- private long _createTime;
- private VirtualHostConfig _virtualHost;
- private String _address;
- private Boolean _incoming;
- private Boolean _systemConnection;
- private Boolean _federationLink;
- private String _authId;
- private String _remoteProcessName;
- private Integer _remotePID;
- private Integer _remoteParentPID;
- private ConfigStore _configStore;
- private Boolean _shadow;
-
- @Override
- public UUID getQMFId()
- {
- return _qmfId;
- }
-
- @Override
- public ConnectionConfigType getConfigType()
- {
- return _configType;
- }
-
- @Override
- public ConfiguredObject<ConnectionConfigType, ConnectionConfig> getParent()
- {
- return _parent;
- }
-
- @Override
- public boolean isDurable()
- {
- return _durable;
- }
-
- @Override
- public long getCreateTime()
- {
- return _createTime;
- }
-
- @Override
- public VirtualHostConfig getVirtualHost()
- {
- return _virtualHost;
- }
-
- @Override
- public String getAddress()
- {
- return _address;
- }
-
- @Override
- public Boolean isIncoming()
- {
- return _incoming;
- }
-
- @Override
- public Boolean isSystemConnection()
- {
- return _systemConnection;
- }
-
- @Override
- public Boolean isFederationLink()
- {
- return _federationLink;
- }
-
- @Override
- public String getAuthId()
- {
- return _authId;
- }
-
- @Override
- public String getRemoteProcessName()
- {
- return _remoteProcessName;
- }
-
- @Override
- public Integer getRemotePID()
- {
- return _remotePID;
- }
-
- @Override
- public Integer getRemoteParentPID()
- {
- return _remoteParentPID;
- }
-
- @Override
- public ConfigStore getConfigStore()
- {
- return _configStore;
- }
-
- @Override
- public Boolean isShadow()
- {
- return _shadow;
- }
-
- @Override
- public void mgmtClose()
- {
- }
-
-}
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 3c5b85cd90..0bb65479ce 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
@@ -20,25 +20,31 @@
*/
package org.apache.qpid.server.configuration;
+import static org.mockito.Mockito.when;
+
import junit.framework.TestCase;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.TestApplicationRegistry;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.util.BrokerTestHelper;
public class QueueConfigurationTest extends TestCase
{
-
private VirtualHostConfiguration _emptyConf;
private PropertiesConfiguration _env;
private VirtualHostConfiguration _fullHostConf;
+ private Broker _broker;
+ @Override
public void setUp() throws Exception
{
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _broker = BrokerTestHelper.createBrokerMock();
_env = new PropertiesConfiguration();
- _emptyConf = new VirtualHostConfiguration("test", _env);
+ _emptyConf = new VirtualHostConfiguration("test", _env, _broker);
PropertiesConfiguration fullEnv = new PropertiesConfiguration();
fullEnv.setProperty("queues.maximumMessageAge", 1);
@@ -49,35 +55,41 @@ public class QueueConfigurationTest extends TestCase
fullEnv.setProperty("queues.deadLetterQueues", true);
fullEnv.setProperty("queues.maximumDeliveryCount", 5);
- _fullHostConf = new VirtualHostConfiguration("test", fullEnv);
+ _fullHostConf = new VirtualHostConfiguration("test", fullEnv, _broker);
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+
public void testMaxDeliveryCount() throws Exception
{
- try
- {
- ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env));
- ApplicationRegistry.initialise(registry);
-
- // Check default value
- QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
- assertEquals("Unexpected default server configuration for max delivery count ", 0, qConf.getMaxDeliveryCount());
-
- // Check explicit value
- VirtualHostConfiguration vhostConfig = overrideConfiguration("maximumDeliveryCount", 7);
- qConf = new QueueConfiguration("test", vhostConfig);
- assertEquals("Unexpected host configuration for max delivery count", 7, qConf.getMaxDeliveryCount());
-
- // Check inherited value
- qConf = new QueueConfiguration("test", _fullHostConf);
- assertEquals("Unexpected queue configuration for max delivery count", 5, qConf.getMaxDeliveryCount());
-
- }
- finally
- {
- ApplicationRegistry.remove();
- }
+ // broker MAXIMUM_DELIVERY_ATTEMPTS attribute is not set
+ when(_broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(null);
+
+ // Check default value
+ QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
+ assertEquals("Unexpected default server configuration for max delivery count ", 0, qConf.getMaxDeliveryCount());
+
+ // set broker MAXIMUM_DELIVERY_ATTEMPTS attribute to 2
+ when(_broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(2);
+
+ // Check that queue inherits the MAXIMUM_DELIVERY_ATTEMPTS value from broker
+ qConf = new QueueConfiguration("test", _emptyConf);
+ assertEquals("Unexpected default server configuration for max delivery count ", 2, qConf.getMaxDeliveryCount());
+
+ // Check explicit value
+ VirtualHostConfiguration vhostConfig = overrideConfiguration("maximumDeliveryCount", 7);
+ qConf = new QueueConfiguration("test", vhostConfig);
+ assertEquals("Unexpected host configuration for max delivery count", 7, qConf.getMaxDeliveryCount());
+
+ // Check inherited value
+ qConf = new QueueConfiguration("test", _fullHostConf);
+ assertEquals("Unexpected queue configuration for max delivery count", 5, qConf.getMaxDeliveryCount());
}
/**
@@ -87,28 +99,28 @@ public class QueueConfigurationTest extends TestCase
*/
public void testIsDeadLetterQueueEnabled() throws Exception
{
- try
- {
- ApplicationRegistry registry = new TestApplicationRegistry(new ServerConfiguration(_env));
- ApplicationRegistry.initialise(registry);
-
- // Check default value
- QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
- assertFalse("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
-
- // Check explicit value
- VirtualHostConfiguration vhostConfig = overrideConfiguration("deadLetterQueues", true);
- qConf = new QueueConfiguration("test", vhostConfig);
- assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
-
- // Check inherited value
- qConf = new QueueConfiguration("test", _fullHostConf);
- assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
- }
- finally
- {
- ApplicationRegistry.remove();
- }
+ // enable dead letter queues broker wide
+ when(_broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(true);
+
+ // Check that queue inherits the broker setting
+ QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
+ assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
+
+ // broker DEAD_LETTER_QUEUE_ENABLED is not set
+ when(_broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(null);
+
+ // Check that queue dead letter queue is not enabled
+ qConf = new QueueConfiguration("test", _emptyConf);
+ assertFalse("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
+
+ // Check explicit value
+ VirtualHostConfiguration vhostConfig = overrideConfiguration("deadLetterQueues", true);
+ qConf = new QueueConfiguration("test", vhostConfig);
+ assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
+
+ // Check inherited value
+ qConf = new QueueConfiguration("test", _fullHostConf);
+ assertTrue("Unexpected queue configuration for dead letter enabled attribute", qConf.isDeadLetterQueueEnabled());
}
public void testGetMaximumMessageAge() throws ConfigurationException
@@ -178,27 +190,28 @@ public class QueueConfigurationTest extends TestCase
public void testGetMinimumAlertRepeatGap() throws Exception
{
- 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 inherited value
- qConf = new QueueConfiguration("test", _fullHostConf);
- assertEquals(1, qConf.getMinimumAlertRepeatGap());
- }
- finally
- {
- ApplicationRegistry.remove();
- }
+ // set broker attribute ALERT_REPEAT_GAP to 10
+ when(_broker.getAttribute(Broker.ALERT_REPEAT_GAP)).thenReturn(10);
+
+ // check that broker level setting is available on queue configuration
+ QueueConfiguration qConf = new QueueConfiguration("test", _emptyConf);
+ assertEquals(10, qConf.getMinimumAlertRepeatGap());
+
+ // remove configuration for ALERT_REPEAT_GAP on broker level
+ when(_broker.getAttribute(Broker.ALERT_REPEAT_GAP)).thenReturn(null);
+
+ // Check default value
+ qConf = new QueueConfiguration("test", _emptyConf);
+ assertEquals(0, 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());
}
public void testSortQueueConfiguration() throws ConfigurationException
@@ -235,6 +248,6 @@ public class QueueConfigurationTest extends TestCase
config.addConfiguration(_fullHostConf.getConfig());
config.addConfiguration(queueConfig);
- return new VirtualHostConfiguration("test", config);
+ return new VirtualHostConfiguration("test", config, _broker);
}
}
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
deleted file mode 100644
index 660ff5e7d4..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ /dev/null
@@ -1,1766 +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;
-
-import org.apache.commons.configuration.ConfigurationException;
-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;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Locale;
-
-import javax.net.ssl.KeyManagerFactory;
-
-public class ServerConfigurationTest extends QpidTestCase
-{
- private XMLConfiguration _config = new XMLConfiguration();
- private ServerConfiguration _serverConfig = null;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- _serverConfig = new ServerConfiguration(_config);
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
- public void testSetJMXPortRegistryServer() throws ConfigurationException
- {
- _serverConfig.initialise();
- _serverConfig.setJMXPortRegistryServer(23);
- assertEquals(23, _serverConfig.getJMXPortRegistryServer());
- }
-
- public void testGetJMXPortRegistryServer() throws ConfigurationException
- {
- _config.setProperty(ServerConfiguration.MGMT_JMXPORT_REGISTRYSERVER, 42);
- _serverConfig.initialise();
- assertEquals(42, _serverConfig.getJMXPortRegistryServer());
- }
-
- public void testDefaultJMXPortRegistryServer() throws ConfigurationException
- {
- _serverConfig.initialise();
- assertEquals(8999, _serverConfig.getJMXPortRegistryServer());
- }
-
- public void testSetJMXPortConnectorServer() throws ConfigurationException
- {
- ServerConfiguration serverConfig = new ServerConfiguration(_config);
- serverConfig.setJMXPortConnectorServer(67);
- assertEquals(67, serverConfig.getJMXConnectorServerPort());
- }
-
- public void testGetJMXPortConnectorServer() throws ConfigurationException
- {
- _config.setProperty(ServerConfiguration.MGMT_JMXPORT_CONNECTORSERVER, 67);
- ServerConfiguration serverConfig = new ServerConfiguration(_config);
- assertEquals(67, serverConfig.getJMXConnectorServerPort());
- }
-
- public void testDefaultJMXPortConnectorServer() throws ConfigurationException
- {
- ServerConfiguration serverConfig = new ServerConfiguration(_config);
- assertEquals(ServerConfiguration.DEFAULT_JMXPORT_REGISTRYSERVER + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET,
- serverConfig.getJMXConnectorServerPort());
- }
-
- public void testGetPlatformMbeanserver() throws ConfigurationException
- {
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getPlatformMbeanserver());
-
- // Check value we set
- _config.setProperty("management.platform-mbeanserver", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getPlatformMbeanserver());
- }
-
- public void testGetPluginDirectory() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getPluginDirectory());
-
- // Check value we set
- _config.setProperty("plugin-directory", "/path/to/plugins");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("/path/to/plugins", _serverConfig.getPluginDirectory());
- }
-
- public void testGetCacheDirectory() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getCacheDirectory());
-
- // Check value we set
- _config.setProperty("cache-directory", "/path/to/cache");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("/path/to/cache", _serverConfig.getCacheDirectory());
- }
-
- public void testGetFrameSize() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(65536, _serverConfig.getFrameSize());
-
- // Check value we set
- _config.setProperty("advanced.framesize", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getFrameSize());
- }
-
- public void testGetStatusEnabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(ServerConfiguration.DEFAULT_STATUS_UPDATES.equalsIgnoreCase("on"),
- _serverConfig.getStatusUpdatesEnabled());
-
- // Check disabling we set
- _config.setProperty(ServerConfiguration.STATUS_UPDATES, "off");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getStatusUpdatesEnabled());
-
- // Check invalid values don't cause error but result in disabled
- _config.setProperty(ServerConfiguration.STATUS_UPDATES, "Yes Please");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getStatusUpdatesEnabled());
-
- }
- public void testGetSynchedClocks() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSynchedClocks());
-
- // Check value we set
- _config.setProperty("advanced.synced-clocks", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getSynchedClocks());
- }
-
- public void testGetLocale() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
-
- // The Default is what ever the VMs default is
- Locale defaultLocale = Locale.getDefault();
-
- assertEquals(defaultLocale, _serverConfig.getLocale());
-
-
- //Test Language only
- Locale update = new Locale("es");
- _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
-
- //Test Language and Country
- update = new Locale("es","ES");
- _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
-
- //Test Language and Country and Variant
- update = new Locale("es","ES", "Traditional_WIN");
- _config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES_Traditional_WIN");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
- }
-
-
- public void testGetMsgAuth() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getMsgAuth());
-
- // Check value we set
- _config.setProperty("security.msg-auth", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getMsgAuth());
- }
-
- public void testGetManagementKeyStorePath() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePath());
-
- // Check value we set
- _config.setProperty("management.ssl.keyStorePath", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getManagementKeyStorePath());
- }
-
- public void testGetManagementSSLEnabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementSSLEnabled());
-
- // Check value we set
- _config.setProperty("management.ssl.enabled", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementSSLEnabled());
- }
-
- public void testGetManagementKeystorePassword() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePassword());
-
- // Check value we set
- _config.setProperty("management.ssl.keyStorePassword", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getManagementKeyStorePassword());
- }
-
- public void testGetQueueAutoRegister() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getQueueAutoRegister());
-
- // Check value we set
- _config.setProperty("queue.auto_register", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getQueueAutoRegister());
- }
-
- public void testGetJMXManagementEnabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getJMXManagementEnabled());
-
- // Check value we set
- _config.setProperty("management.enabled", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getJMXManagementEnabled());
- }
-
- public void testGetManagementRightsInferAllAccess() throws Exception
- {
- _serverConfig.initialise();
-
- //check default
- assertTrue("default should be true", _serverConfig.getManagementRightsInferAllAccess());
-
- //update it
- _config.setProperty("management.managementRightsInferAllAccess", "false");
- assertFalse("New value should be false", _serverConfig.getManagementRightsInferAllAccess());
- }
-
- public void testGetHeartBeatDelay() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(5, _serverConfig.getHeartBeatDelay());
-
- // Check value we set
- _config.setProperty("heartbeat.delay", 23);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getHeartBeatDelay());
- }
-
- public void testGetHeartBeatTimeout() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(2.0, _serverConfig.getHeartBeatTimeout());
-
- // Check value we set
- _config.setProperty("heartbeat.timeoutFactor", 2.3);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(2.3, _serverConfig.getHeartBeatTimeout());
- }
-
- public void testGetMaximumMessageAge() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageAge());
-
- // Check value we set
- _config.setProperty("maximumMessageAge", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageAge());
- }
-
- public void testGetMaximumMessageCount() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageCount());
-
- // Check value we set
- _config.setProperty("maximumMessageCount", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageCount());
- }
-
- public void testGetMaximumQueueDepth() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumQueueDepth());
-
- // Check value we set
- _config.setProperty("maximumQueueDepth", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumQueueDepth());
- }
-
- public void testGetMaximumMessageSize() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageSize());
-
- // Check value we set
- _config.setProperty("maximumMessageSize", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageSize());
- }
-
- public void testGetMinimumAlertRepeatGap() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(30000l, _serverConfig.getMinimumAlertRepeatGap());
-
- // Check value we set
- _config.setProperty("minimumAlertRepeatGap", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMinimumAlertRepeatGap());
- }
-
- public void testGetProcessors() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(4, _serverConfig.getConnectorProcessors());
-
- // Check value we set
- _config.setProperty("connector.processors", 10);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getConnectorProcessors());
- }
-
- public void testGetPorts() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getPorts());
- assertEquals(1, _serverConfig.getPorts().size());
- assertEquals(5672, _serverConfig.getPorts().get(0));
-
-
- // Check value we set
- _config.setProperty("connector.port", "10");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getPorts());
- assertEquals(1, _serverConfig.getPorts().size());
- assertEquals("10", _serverConfig.getPorts().get(0));
- }
-
- public void testGetBind() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(WILDCARD_ADDRESS, _serverConfig.getBind());
-
- // Check value we set
- _config.setProperty("connector.bind", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getBind());
- }
-
- public void testGetReceiveBufferSize() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getReceiveBufferSize());
-
- // Check value we set
- _config.setProperty("connector.socketReceiveBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getReceiveBufferSize());
- }
-
- public void testGetWriteBufferSize() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getWriteBufferSize());
-
- // Check value we set
- _config.setProperty("connector.socketWriteBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getWriteBufferSize());
- }
-
- public void testGetTcpNoDelay() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getTcpNoDelay());
-
- // Check value we set
- _config.setProperty("connector.tcpNoDelay", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getTcpNoDelay());
- }
-
- public void testGetEnableSSL() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getEnableSSL());
-
- // Check value we set
- _config.setProperty("connector.ssl.enabled", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getEnableSSL());
- }
-
- public void testGetSSLOnly() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSSLOnly());
-
- // Check value we set
- _config.setProperty("connector.ssl.sslOnly", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getSSLOnly());
- }
-
- public void testGetSSLPorts() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getSSLPorts());
- assertEquals(1, _serverConfig.getSSLPorts().size());
- assertEquals(ServerConfiguration.DEFAULT_SSL_PORT, _serverConfig.getSSLPorts().get(0));
-
-
- // Check value we set
- _config.setProperty("connector.ssl.port", "10");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getSSLPorts());
- assertEquals(1, _serverConfig.getSSLPorts().size());
- assertEquals("10", _serverConfig.getSSLPorts().get(0));
- }
-
- public void testGetConnectorKeystorePath() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertNull(_serverConfig.getConnectorKeyStorePath());
-
- // Check value we set
- _config.setProperty("connector.ssl.keyStorePath", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getConnectorKeyStorePath());
-
- // Ensure we continue to support the old name keystorePath
- _config.clearProperty("connector.ssl.keyStorePath");
- _config.setProperty("connector.ssl.keystorePath", "b");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("b", _serverConfig.getConnectorKeyStorePath());
- }
-
- public void testGetConnectorKeystorePassword() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertNull(_serverConfig.getConnectorKeyStorePassword());
-
- // Check value we set
- _config.setProperty("connector.ssl.keyStorePassword", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getConnectorKeyStorePassword());
-
- // Ensure we continue to support the old name keystorePassword
- _config.clearProperty("connector.ssl.keyStorePassword");
- _config.setProperty("connector.ssl.keystorePassword", "b");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("b", _serverConfig.getConnectorKeyStorePassword());
- }
-
- public void testConnectorGetKeyManagerAlgorithm() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(KeyManagerFactory.getDefaultAlgorithm(), _serverConfig.getConnectorKeyManagerFactoryAlgorithm());
-
- // Check value we set
- _config.setProperty("connector.ssl.keyManagerFactoryAlgorithm", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getConnectorKeyManagerFactoryAlgorithm());
-
- // Ensure we continue to support the old name certType
- _config.clearProperty("connector.ssl.keyManagerFactoryAlgorithm");
- _config.setProperty("connector.ssl.certType", "b");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("b", _serverConfig.getConnectorKeyManagerFactoryAlgorithm());
- }
-
- public void testGetHousekeepingCheckPeriod() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(30000, _serverConfig.getHousekeepingCheckPeriod());
-
- // Check value we set
- _config.setProperty("housekeeping.checkPeriod", 23L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- _serverConfig.setHousekeepingCheckPeriod(42L);
- assertEquals(42, _serverConfig.getHousekeepingCheckPeriod());
- }
-
- public void testSingleConfiguration() throws IOException, ConfigurationException
- {
- File fileA = File.createTempFile(getClass().getName(), null);
- fileA.deleteOnExit();
- FileWriter out = new FileWriter(fileA);
- out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>");
- out.close();
- ServerConfiguration conf = new ServerConfiguration(fileA);
- conf.initialise();
- assertEquals("4235", conf.getSSLPorts().get(0));
- }
-
- public void testCombinedConfiguration() throws IOException, ConfigurationException
- {
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<broker><connector><ssl><port>2345</port></ssl></connector></broker>");
- out.close();
-
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
- assertEquals("4235", config.getSSLPorts().get(0)); // From first file, not
- // overriden by second
- assertNotNull(config.getPorts());
- assertEquals(1, config.getPorts().size());
- assertEquals("2342", config.getPorts().get(0)); // From the first file, not
- // present in the second
- }
-
- public void testVariableInterpolation() throws Exception
- {
- File mainFile = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<work>foo</work>\n");
- out.write("\t<management><ssl><keyStorePath>${work}</keyStorePath></ssl></management>\n");
- out.write("</broker>\n");
- out.close();
-
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
- assertEquals("Did not get correct interpolated value",
- "foo", config.getManagementKeyStorePath());
- }
-
- private void writeConfigFile(File mainFile, boolean allow) throws IOException {
- writeConfigFile(mainFile, allow, true, null, "test");
- }
-
- private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- if (includeVhosts)
- {
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<default>test</default>\n");
- out.write("\t\t<virtualhost>\n");
- out.write(String.format("\t\t\t<name>%s</name>\n", name));
- out.write(String.format("\t\t<%s> \n", name));
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>topic</type>\n");
- out.write(String.format("\t\t\t\t\t<name>%s.topic</name>\n", name));
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write(String.format("\t\t</%s> \n", name));
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- }
- if (vhostsFile != null)
- {
- out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n");
- }
- out.write("</broker>\n");
- out.close();
- }
-
- private void writeTestFishConfigFile(File mainFile) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t<test> \n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>topic</type>\n");
- out.write("\t\t\t\t\t<name>test.topic</name>\n");
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</test> \n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>fish</name>\n");
- out.write("\t\t<fish> \n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>topic</type>\n");
- out.write("\t\t\t\t\t<name>fish.topic</name>\n");
- out.write("\t\t\t\t\t<durable>false</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</fish> \n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
- }
-
- private void writeVirtualHostsFile(File vhostsFile, String name) throws IOException {
- FileWriter out = new FileWriter(vhostsFile);
- out.write("<virtualhosts>\n");
- out.write(String.format("\t\t<default>%s</default>\n", name));
- out.write("\t<virtualhost>\n");
- out.write(String.format("\t\t<name>%s</name>\n", name));
- out.write(String.format("\t\t<%s>\n", name));
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>topic</type>\n");
- out.write("\t\t\t\t\t<name>test.topic</name>\n");
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write(String.format("\t\t</%s>\n", name));
- out.write("\t</virtualhost>\n");
- out.write("</virtualhosts>\n");
- out.close();
- }
-
- private void writeMultiVirtualHostsFile(File vhostsFile) throws IOException {
- FileWriter out = new FileWriter(vhostsFile);
- out.write("<virtualhosts>\n");
- out.write("\t<virtualhost>\n");
- out.write("\t\t<name>topic</name>\n");
- out.write("\t\t<topic>\n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>topic</type>\n");
- out.write("\t\t\t\t\t<name>test.topic</name>\n");
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</topic>\n");
- out.write("\t</virtualhost>\n");
- out.write("\t<virtualhost>\n");
- out.write("\t\t<name>fanout</name>\n");
- out.write("\t\t<fanout>\n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<type>fanout</type>\n");
- out.write("\t\t\t\t\t<name>test.fanout</name>\n");
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</fanout>\n");
- out.write("\t</virtualhost>\n");
- out.write("</virtualhosts>\n");
- out.close();
- }
-
- private void writeMultipleVhostsConfigFile(File mainFile, File[] vhostsFileArray) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- for (File vhostsFile : vhostsFileArray)
- {
- out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n");
- }
- out.write("</broker>\n");
- out.close();
- }
-
- private void writeCombinedConfigFile(File mainFile, File fileA, File fileB) throws Exception
- {
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in the main
- * configuration file only.
- * <p>
- * Test for QPID-2361
- */
- public void testInternalVirtualhostConfigFile() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false, true, null, "test");
-
- // Load config
- ApplicationRegistry.remove();
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- String defaultVirtualHost = reg.getConfiguration().getDefaultVirtualHost();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic"));
-
- assertEquals("Incorrect default host", "test", defaultVirtualHost);
- assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size());
- assertEquals("Incorrect virtualhost name", "test", virtualHost.getName());
- assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString());
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file only.
- * <p>
- * Test for QPID-2361
- */
- public void testExternalVirtualhostXMLFile() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeConfigFile(mainFile, false, false, vhostsFile, null);
- writeVirtualHostsFile(vhostsFile, "test");
-
- // Load config
- ApplicationRegistry.remove();
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- String defaultVirtualHost = reg.getConfiguration().getDefaultVirtualHost();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
- Exchange exchange = virtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic"));
-
- assertEquals("Incorrect default host", "test", defaultVirtualHost);
- assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size());
- assertEquals("Incorrect virtualhost name", "test", virtualHost.getName());
- assertEquals("Incorrect exchange type", "topic", exchange.getType().getName().toString());
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file only, with two vhosts that have different properties.
- * <p>
- * Test for QPID-2361
- */
- public void testExternalMultiVirtualhostXMLFile() throws Exception
- {
- // Write out vhosts
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts-multi");
- vhostsFile.deleteOnExit();
- writeMultiVirtualHostsFile(vhostsFile);
-
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false, false, vhostsFile, null);
-
- // Load config
- ApplicationRegistry.remove();
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
-
- assertEquals("Incorrect virtualhost count", 2, virtualHostRegistry.getVirtualHosts().size());
-
- // test topic host
- VirtualHost topicVirtualHost = virtualHostRegistry.getVirtualHost("topic");
- Exchange topicExchange = topicVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.topic"));
-
- assertEquals("Incorrect topic virtualhost name", "topic", topicVirtualHost.getName());
- assertEquals("Incorrect topic exchange type", "topic", topicExchange.getType().getName().toString());
-
- // Test fanout host
- VirtualHost fanoutVirtualHost = virtualHostRegistry.getVirtualHost("fanout");
- Exchange fanoutExchange = fanoutVirtualHost.getExchangeRegistry().getExchange(new AMQShortString("test.fanout"));
-
- assertEquals("Incorrect fanout virtualhost name", "fanout", fanoutVirtualHost.getName());
- assertEquals("Incorrect fanout exchange type", "fanout", fanoutExchange.getType().getName().toString());
- }
-
- /**
- * Test that configuration does not load when virtual hosts are specified in both the main
- * configuration file and an external file. Should throw a {@link ConfigurationException}.
- * <p>
- * Test for QPID-2361
- */
- public void testInternalAndExternalVirtualhostXMLFile() throws Exception
- {
- // Write out vhosts
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeVirtualHostsFile(vhostsFile, "test");
-
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false, true, vhostsFile, "test");
-
- // Load config
- try
- {
- ApplicationRegistry.remove();
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
- fail("Different virtualhost XML configurations not allowed");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage());
- }
- }
-
- /**
- * Test that configuration does not load when virtual hosts are specified in multiple external
- * files. Should throw a {@link ConfigurationException}.
- * <p>
- * Test for QPID-2361
- */
- public void testMultipleInternalVirtualhostXMLFile() throws Exception
- {
- // Write out vhosts
- File vhostsFileOne = File.createTempFile(getClass().getName(), "vhosts-one");
- vhostsFileOne.deleteOnExit();
- writeVirtualHostsFile(vhostsFileOne, "one");
- File vhostsFileTwo = File.createTempFile(getClass().getName(), "vhosts-two");
- vhostsFileTwo.deleteOnExit();
- writeVirtualHostsFile(vhostsFileTwo, "two");
-
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- writeMultipleVhostsConfigFile(mainFile, new File[] { vhostsFileOne, vhostsFileTwo });
-
- // Load config
- try
- {
- ApplicationRegistry.remove();
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
- fail("Multiple virtualhost XML configurations not allowed");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Only one external virtualhosts configuration file allowed, multiple filenames found.",
- ce.getMessage());
- }
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file in the first of two configurations and embedded in the second. This
- * will throe a {@link ConfigurationException} since the configurations have different
- * types.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedDifferentVirtualhostConfig() throws Exception
- {
- // Write out vhosts config
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeVirtualHostsFile(vhostsFile, "external");
-
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File fileA = File.createTempFile(getClass().getName(), "a");
- File fileB = File.createTempFile(getClass().getName(), "b");
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeCombinedConfigFile(mainFile, fileA, fileB);
- writeConfigFile(fileA, false, false, vhostsFile, null);
- writeConfigFile(fileB, false);
-
- // Load config
- try
- {
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
- fail("Different virtualhost XML configurations not allowed");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message", "Only one of external or embedded virtualhosts configuration allowed.", ce.getMessage());
- }
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified two overriding configurations
- * each with an embedded virtualhost section. The first configuration section should be used.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedConfigEmbeddedVirtualhost() throws Exception
- {
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File fileA = File.createTempFile(getClass().getName(), "a");
- File fileB = File.createTempFile(getClass().getName(), "b");
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeCombinedConfigFile(mainFile, fileA, fileB);
- writeConfigFile(fileA, false, true, null, "a");
- writeConfigFile(fileB, false, true, null, "b");
-
- // Load config
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
-
- // Test config
- VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("a");
-
- assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length);
- assertEquals("Incorrect virtualhost name", "a", virtualHost.getName());
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified two overriding configurations
- * each with an external virtualhost XML file. The first configuration file should be used.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedConfigExternalVirtualhost() throws Exception
- {
- // Write out vhosts config
- File vhostsOne = File.createTempFile(getClass().getName(), "vhosts-one");
- vhostsOne.deleteOnExit();
- writeVirtualHostsFile(vhostsOne, "one");
- File vhostsTwo = File.createTempFile(getClass().getName(), "vhosts-two");
- vhostsTwo.deleteOnExit();
- writeVirtualHostsFile(vhostsTwo, "two");
-
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File fileA = File.createTempFile(getClass().getName(), "a");
- File fileB = File.createTempFile(getClass().getName(), "b");
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeCombinedConfigFile(mainFile, fileA, fileB);
- writeConfigFile(fileA, false, false, vhostsOne, null);
- writeConfigFile(fileB, false, false, vhostsTwo, null);
-
- // Load config
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
-
- // Test config
- VirtualHostConfiguration virtualHost = config.getVirtualHostConfig("one");
-
- assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length);
- assertEquals("Incorrect virtualhost name", "one", virtualHost.getName());
- }
-
- /**
- * Test that configuration loads correctly when an overriding virtualhost configuration resets
- * a property of an embedded virtualhost section. The overriding configuration property value
- * should be used.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedConfigEmbeddedVirtualhostOverride() throws Exception
- {
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File fileA = File.createTempFile(getClass().getName(), "override");
- File fileB = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeCombinedConfigFile(mainFile, fileA, fileB);
- writeTestFishConfigFile(fileB);
-
- // Write out overriding virtualhosts section
- FileWriter out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("<virtualhosts>\n");
- out.write("\t<virtualhost>\n");
- out.write("\t\t<test>\n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<durable>false</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</test>\n");
- out.write("\t\t<fish>\n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<durable>true</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</fish>\n");
- out.write("\t</virtualhost>\n");
- out.write("</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- // Load config
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
-
- // Test config
- VirtualHostConfiguration testHost = config.getVirtualHostConfig("test");
- ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic");
- VirtualHostConfiguration fishHost = config.getVirtualHostConfig("fish");
- ExchangeConfiguration fishExchange = fishHost.getExchangeConfiguration("fish.topic");
-
- assertEquals("Incorrect virtualhost count", 2, config.getVirtualHosts().length);
- assertEquals("Incorrect virtualhost name", "test", testHost.getName());
- assertFalse("Incorrect exchange durable property", testExchange.getDurable());
- assertEquals("Incorrect virtualhost name", "fish", fishHost.getName());
- assertTrue("Incorrect exchange durable property", fishExchange.getDurable());
- }
-
- /**
- * Test that configuration loads correctly when the virtualhost configuration is a set of overriding
- * configuration files that resets a property of a virtualhost. The opmost overriding configuration
- * property value should be used.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedVirtualhostOverride() throws Exception
- {
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- File fileA = File.createTempFile(getClass().getName(), "vhosts-override");
- File fileB = File.createTempFile(getClass().getName(), "vhosts-base");
- mainFile.deleteOnExit();
- vhostsFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeConfigFile(mainFile, true, false, vhostsFile, null);
- writeCombinedConfigFile(vhostsFile, fileA, fileB);
-
- // Write out overriding virtualhosts sections
- FileWriter out = new FileWriter(fileA);
- out.write("<virtualhosts>\n");
- out.write("\t<virtualhost>\n");
- out.write("\t\t<test>\n");
- out.write("\t\t\t<exchanges>\n");
- out.write("\t\t\t\t<exchange>\n");
- out.write("\t\t\t\t\t<durable>false</durable>\n");
- out.write("\t\t\t\t</exchange>\n");
- out.write("\t\tt</exchanges>\n");
- out.write("\t\t</test>\n");
- out.write("\t</virtualhost>\n");
- out.write("</virtualhosts>\n");
- out.close();
- writeVirtualHostsFile(fileB, "test");
-
- // Load config
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
-
- // Test config
- VirtualHostConfiguration testHost = config.getVirtualHostConfig("test");
- ExchangeConfiguration testExchange = testHost.getExchangeConfiguration("test.topic");
-
- assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length);
- assertEquals("Incorrect virtualhost name", "test", testHost.getName());
- assertFalse("Incorrect exchange durable property", testExchange.getDurable());
- }
-
- /**
- * Test that configuration loads correctly when the virtualhost configuration is a set of overriding
- * configuration files that define multiple virtualhosts, one per file. Only the virtualhosts defined in
- * the topmost file should be used.
- * <p>
- * Test for QPID-2361
- */
- public void testCombinedMultipleVirtualhosts() throws Exception
- {
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- File fileA = File.createTempFile(getClass().getName(), "vhosts-one");
- File fileB = File.createTempFile(getClass().getName(), "vhosts-two");
- mainFile.deleteOnExit();
- vhostsFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
- writeConfigFile(mainFile, true, false, vhostsFile, null);
- writeCombinedConfigFile(vhostsFile, fileA, fileB);
-
- // Write both virtualhosts definitions
- writeVirtualHostsFile(fileA, "test-one");
- writeVirtualHostsFile(fileB, "test-two");
-
- // Load config
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
-
- // Test config
- VirtualHostConfiguration oneHost = config.getVirtualHostConfig("test-one");
-
- assertEquals("Incorrect virtualhost count", 1, config.getVirtualHosts().length);
- assertEquals("Incorrect virtualhost name", "test-one", oneHost.getName());
- }
-
- /**
- * Test that a non-existent virtualhost file throws a {@link ConfigurationException}.
- * <p>
- * Test for QPID-2624
- */
- public void testNonExistantVirtualhosts() throws Exception
- {
- // Write out combined config file
- File mainFile = File.createTempFile(getClass().getName(), "main");
- File vhostsFile = new File("doesnotexist");
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, true, false, vhostsFile, null);
-
- // Load config
- try
- {
- ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
- config.initialise();
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Virtualhosts file does not exist", ce.getMessage());
- }
- catch (Exception e)
- {
- fail("Should throw a ConfigurationException");
- }
- }
-
- /**
- * Tests that element disabledFeatures allows features that would
- * otherwise be advertised by the broker to be turned off.
- */
- public void testDisabledFeatures() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- _serverConfig = new ServerConfiguration(_config);
- assertEquals("Unexpected size", 0, _serverConfig.getDisabledFeatures().size());
-
- // Check value we set
- _config.addProperty("disabledFeatures", "qpid.feature1");
- _config.addProperty("disabledFeatures", "qpid.feature2");
- _serverConfig = new ServerConfiguration(_config);
-
- assertEquals("Unexpected size",2, _serverConfig.getDisabledFeatures().size());
- assertTrue("Unexpected contents", _serverConfig.getDisabledFeatures().contains("qpid.feature1"));
- }
-
- /**
- * Tests that the old element security.jmx.access (that used to be used
- * to define JMX access rights) is rejected.
- */
- public void testManagementAccessRejected() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.jmx.access(0)", "jmxremote.access");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/jmx/access is no longer a supported element within the configuration xml.",
- ce.getMessage());
- }
- }
-
- /**
- * Tests that the old element security.jmx.principal-database (that used to define the
- * principal database used for JMX authentication) is rejected.
- */
- public void testManagementPrincipalDatabaseRejected() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.jmx.principal-database(0)", "mydb");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml.",
- ce.getMessage());
- }
- }
-
- /**
- * Tests that the old element security.principal-databases. ... (that used to define
- * principal databases) is rejected.
- */
- public void testPrincipalDatabasesRejected() throws ConfigurationException
- {
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.principal-databases.principal-database.class", "myclass");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/principal-databases is no longer supported within the configuration xml.",
- ce.getMessage());
- }
- }
-
- /**
- * Tests that the old element housekeeping.expiredMessageCheckPeriod. ... (that was
- * replaced by housekeeping.checkPeriod) is rejected.
- */
- public void testExpiredMessageCheckPeriodRejected() throws ConfigurationException
- {
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L);
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : housekeeping/expiredMessageCheckPeriod must be replaced by housekeeping/checkPeriod.",
- ce.getMessage());
- }
- }
-
- public void testMaxDeliveryCountDefault() throws Exception
- {
- final ServerConfiguration serverConfig = new ServerConfiguration(_config);
- assertEquals(0, serverConfig.getMaxDeliveryCount());
- }
-
- public void testMaxDeliveryCount() throws Exception
- {
- _config.setProperty("maximumDeliveryCount", 5);
- final ServerConfiguration serverConfig = new ServerConfiguration(_config);
- assertEquals(5, serverConfig.getMaxDeliveryCount());
- }
-
- /**
- * Test XML configuration file correctly enables dead letter queues
- */
- public void testDeadLetterQueueConfigurationFile() throws Exception
- {
- // Write config
- File xml = File.createTempFile(getClass().getName(), "xml");
- xml.deleteOnExit();
- FileWriter config = new FileWriter(xml);
- config.write("<broker>\n");
- writeSecurity(config);
- config.write("<deadLetterQueues>true</deadLetterQueues>\n");
- config.write("<virtualhosts>\n");
- config.write("<virtualhost>\n");
- config.write("<name>test</name>\n");
- config.write("<test>\n");
- config.write("<queues>\n");
- config.write("<deadLetterQueues>false</deadLetterQueues>\n");
- config.write("<queue>\n");
- config.write("<name>biggles</name>\n");
- config.write("<biggles>\n");
- config.write("<deadLetterQueues>true</deadLetterQueues>\n");
- config.write("</biggles>\n");
- config.write("</queue>\n");
- config.write("<queue>\n");
- config.write("<name>beetle</name>\n");
- config.write("<beetle />\n");
- config.write("</queue>\n");
- config.write("</queues>\n");
- config.write("</test>\n");
- config.write("</virtualhost>\n");
- config.write("<virtualhost>\n");
- config.write("<name>extra</name>\n");
- config.write("<extra>\n");
- config.write("<queues>\n");
- config.write("<queue>\n");
- config.write("<name>r2d2</name>\n");
- config.write("<r2d2>\n");
- config.write("<deadLetterQueues>false</deadLetterQueues>\n");
- config.write("</r2d2>\n");
- config.write("</queue>\n");
- config.write("<queue>\n");
- config.write("<name>c3p0</name>\n");
- config.write("<c3p0 />\n");
- config.write("</queue>\n");
- config.write("</queues>\n");
- config.write("</extra>\n");
- config.write("</virtualhost>\n");
- config.write("</virtualhosts>\n");
- config.write("</broker>\n");
- config.close();
-
- // Load config
- ApplicationRegistry.remove();
- ApplicationRegistry registry = new ConfigurationFileApplicationRegistry(xml);
- ApplicationRegistry.initialise(registry);
- ServerConfiguration serverConfiguration = ApplicationRegistry.getInstance().getConfiguration();
-
- VirtualHostConfiguration test = serverConfiguration.getVirtualHostConfig("test");
- assertNotNull("Host 'test' is not found", test);
- VirtualHostConfiguration extra = serverConfiguration.getVirtualHostConfig("extra");
- assertNotNull("Host 'extra' is not found", test);
-
- QueueConfiguration biggles = test.getQueueConfiguration("biggles");
- QueueConfiguration beetle = test.getQueueConfiguration("beetle");
- QueueConfiguration r2d2 = extra.getQueueConfiguration("r2d2");
- QueueConfiguration c3p0 = extra.getQueueConfiguration("c3p0");
-
- // Validate config
- assertTrue("Broker DLQ should be configured as enabled", serverConfiguration.isDeadLetterQueueEnabled());
- assertFalse("Test vhost DLQ should be configured as disabled", test.isDeadLetterQueueEnabled());
- assertTrue("Extra vhost DLQ should be enabled, using broker default", extra.isDeadLetterQueueEnabled());
- assertTrue("Biggles queue DLQ should be configured as enabled", biggles.isDeadLetterQueueEnabled());
- assertFalse("Beetle queue DLQ should be disabled, using test vhost default", beetle.isDeadLetterQueueEnabled());
- assertFalse("R2D2 queue DLQ should be configured as disabled", r2d2.isDeadLetterQueueEnabled());
- assertTrue("C3P0 queue DLQ should be enabled, using broker default", c3p0.isDeadLetterQueueEnabled());
- }
-
- public void testIsAmqp010enabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.isAmqp010enabled());
-
- // Check value we set
- _config.setProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.isAmqp010enabled());
- }
-
- public void testIsAmqp091enabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.isAmqp091enabled());
-
- // Check value we set
- _config.setProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.isAmqp091enabled());
- }
-
- public void testIsAmqp09enabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.isAmqp09enabled());
-
- // Check value we set
- _config.setProperty(ServerConfiguration.CONNECTOR_AMQP09ENABLED, false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.isAmqp09enabled());
- }
-
- public void testIsAmqp08enabled() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.isAmqp08enabled());
-
- // Check value we set
- _config.setProperty(ServerConfiguration.CONNECTOR_AMQP08ENABLED, false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- 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
- */
- private void writeSecurity(Writer out) throws Exception
- {
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- 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</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
deleted file mode 100644
index caf74a89ec..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/TopicConfigurationTest.java
+++ /dev/null
@@ -1,131 +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;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-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.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;
-
-/**
- * Test of the new Topic configuration processing
- */
-public class TopicConfigurationTest extends InternalBrokerBaseCase
-{
-
- @Override
- public void configure()
- {
- getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic.name", "stocks.nyse.appl");
-
- getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(1).subscriptionName", getName()+":stockSubscription");
-
- getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(2).name", "stocks.nyse.orcl");
- getConfigXml().addProperty("virtualhosts.virtualhost.test.topics.topic(2).subscriptionName", getName()+":stockSubscription");
- }
-
- /**
- * Test that a TopicConfig object is created and attached to the queue when it is bound to the topic exchange.
- *
-
- * @throws ConfigurationException
- * @throws AMQSecurityException
- */
- public void testTopicCreation() throws ConfigurationException, AMQSecurityException, AMQInternalException
- {
- Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME);
- getVirtualHost().getBindingFactory().addBinding("stocks.nyse.appl", getQueue(), topicExchange, null);
-
- TopicConfig config = getQueue().getConfiguration().getConfiguration(TopicConfig.class.getName());
-
- assertNotNull("Queue should have topic configuration bound to it.", config);
- assertEquals("Configuration name not correct", "stocks.nyse.appl", config.getName());
- }
-
- /**
- * Test that a queue created for a subscription correctly has topic
- * configuration selected based on the subscription and topic name.
- *
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testSubscriptionWithTopicCreation() throws ConfigurationException, AMQException
- {
-
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName()+":stockSubscription", false, "testowner",
- false, false, getVirtualHost(), null);
-
- getVirtualHost().getQueueRegistry().registerQueue(queue);
- Exchange defaultExchange = getVirtualHost().getExchangeRegistry().getDefaultExchange();
- getVirtualHost().getBindingFactory().addBinding(getName(), queue, defaultExchange, null);
-
-
- Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME);
- getVirtualHost().getBindingFactory().addBinding("stocks.nyse.orcl", queue, topicExchange, null);
-
- TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName());
-
- assertNotNull("Queue should have topic configuration bound to it.", config);
- assertEquals("Configuration subscription name not correct", getName() + ":stockSubscription", config.getSubscriptionName());
- assertEquals("Configuration name not correct", "stocks.nyse.orcl", config.getName());
-
- }
-
- /**
- * Test that a queue created for a subscription correctly has topic
- * configuration attached here this should be the generic topic section
- * with just the subscriptionName
- *
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testSubscriptionCreation() throws ConfigurationException, AMQException
- {
-
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID() ,getName()+":stockSubscription", false, "testowner",
- false, false, getVirtualHost(), null);
-
- getVirtualHost().getQueueRegistry().registerQueue(queue);
- Exchange defaultExchange = getVirtualHost().getExchangeRegistry().getDefaultExchange();
- getVirtualHost().getBindingFactory().addBinding(getName(), queue, defaultExchange, null);
-
-
- Exchange topicExchange = getVirtualHost().getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME);
- getVirtualHost().getBindingFactory().addBinding("stocks.nyse.ibm", queue, topicExchange, null);
-
- TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName());
-
- assertNotNull("Queue should have topic configuration bound to it.", config);
- assertEquals("Configuration subscription name not correct", getName() + ":stockSubscription", config.getSubscriptionName());
- assertEquals("Configuration name not correct", "#", config.getName());
-
- }
-
-
-
-}
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 50e7f0588b..570bd004c5 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
@@ -19,24 +19,69 @@
*/
package org.apache.qpid.server.configuration;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.model.Broker;
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.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
+public class VirtualHostConfigurationTest extends QpidTestCase
{
+ private VirtualHostRegistry _virtualHostRegistry;
+ private XMLConfiguration _configXml;
+ private Broker _broker;
@Override
- public void createBroker()
+ public void setUp() throws Exception
{
- // Prevent auto broker startup
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _configXml = new XMLConfiguration();
+ _configXml.addProperty("virtualhosts.virtualhost(-1).name", getName());
+ _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName());
+ _virtualHostRegistry = new VirtualHostRegistry();
+ _broker = mock(Broker.class);
+ when(_broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(30000l);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_virtualHostRegistry != null)
+ {
+ _virtualHostRegistry.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
+ private XMLConfiguration getConfigXml()
+ {
+ return _configXml;
+ }
+
+ private VirtualHost createVirtualHost(String hostName) throws Exception
+ {
+ Configuration config = getConfigXml().subset("virtualhosts.virtualhost." + XmlConfigurationUtilities.escapeTagName(hostName));
+ VirtualHostConfiguration virtualHostConfiguration = new VirtualHostConfiguration(hostName, config, _broker);
+ return BrokerTestHelper.createVirtualHost(virtualHostConfiguration, _virtualHostRegistry);
}
public void testQueuePriority() throws Exception
@@ -65,11 +110,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost.testQueuePriority.queues.queue.ntest.priority",
"false");
- // Start the broker now.
- super.createBroker();
-
- VirtualHost vhost =
- ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
+ VirtualHost vhost = createVirtualHost(getName());
// Check that atest was a priority queue with 5 priorities
AMQQueue atest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
@@ -102,11 +143,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost.testQueueAlerts.queues(-1).queue(-1).name(-1)", "btest");
- // Start the broker now.
- super.createBroker();
-
- VirtualHost vhost =
- ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
+ VirtualHost vhost = createVirtualHost(getName());
// Check specifically configured values
AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
@@ -129,11 +166,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues.queue.biggles.maximumDeliveryCount", 4);
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues(-1).queue(-1).name", "beetle");
- // Start the broker now.
- super.createBroker();
-
- // Get vhosts
- VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
+ VirtualHost test = createVirtualHost(getName());
// Enabled specifically
assertEquals("Test vhost MDC was configured as enabled", 5 ,test.getConfiguration().getMaxDeliveryCount());
@@ -163,12 +196,8 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.queues(-1).queue(-1).name", "c3p0");
getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + "Extra.store.class", TestableMemoryMessageStore.class.getName());
- // Start the broker now.
- super.createBroker();
-
- // Get vhosts
- VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
- VirtualHost extra = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName() + "Extra");
+ VirtualHost test = createVirtualHost(getName());
+ VirtualHost extra = createVirtualHost(getName() + "Extra");
// Enabled specifically
assertTrue("Test vhost DLQ was configured as enabled", test.getConfiguration().isDeadLetterQueueEnabled());
@@ -215,38 +244,13 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost.testHouseKeepingThreadCount.housekeeping.poolSize",
initialPoolSize);
- // Start the broker now.
- super.createBroker();
-
- VirtualHost vhost =
- ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
+ VirtualHost vhost = createVirtualHost(getName());
assertEquals("HouseKeeping PoolSize not set correctly.",
initialPoolSize, vhost.getHouseKeepingPoolSize());
}
/**
- * Test default house keeping tasks
- *
- * @throws Exception
- */
- public void testDefaultHouseKeepingTasks() throws Exception
- {
- // Start the broker now.
- super.createBroker();
-
- VirtualHost vhost =
- ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
-
- assertEquals("Default houseKeeping task count incorrect.", 2,
- vhost.getHouseKeepingTaskCount());
-
- // Currently the two are tasks:
- // ExpiredMessageTask from VirtualHost
- // UpdateTask from the QMF ManagementExchange
- }
-
- /**
* Test that we can dynamically change the thread pool size
*
* @throws Exception
@@ -258,11 +262,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
getConfigXml().addProperty("virtualhosts.virtualhost.testDynamicHouseKeepingPoolSizeChange.housekeeping.poolSize",
initialPoolSize);
- // Start the broker now.
- super.createBroker();
-
- VirtualHost vhost =
- ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(getName());
+ VirtualHost vhost = createVirtualHost(getName());
assertEquals("HouseKeeping PoolSize not set correctly.",
initialPoolSize, vhost.getHouseKeepingPoolSize());
@@ -286,7 +286,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
try
{
- super.createBroker();
+ createVirtualHost(getName());
fail("Exception not thrown");
}
catch(ConfigurationException ce)
@@ -309,7 +309,7 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
try
{
- super.createBroker();
+ createVirtualHost(getName());
fail("Exception not thrown");
}
catch (ConfigurationException ce)
@@ -320,4 +320,41 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
ce.getMessage());
}
}
+
+ /*
+ * Tests that the queues with dots in the names are fully supported. The XML configuration
+ * had problems with handling the tags containing dots due to the design of the Apache Commons
+ * Configuration library. The dots need to be escaped when accessing the XML configuration.
+ */
+ public void testDotsInQueueName() throws Exception
+ {
+ // Set up vhosts and queue
+ getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues(-1).queue(-1).name", "dot.in.a.name");
+ // Add a single property which is inside the <dot.in.a.name> queue tag - the maximum delivery count
+ getConfigXml().addProperty("virtualhosts.virtualhost." + getName() + ".queues.queue.dot..in..a..name.maximumDeliveryCount", 5);
+
+ VirtualHost test = createVirtualHost(getName());
+
+ // Check, that the property stored within the <dot.in.a.name> tag has been properly loaded
+ assertEquals("queue with dots in its name has been properly loaded", 5, test.getConfiguration().getQueueConfiguration("dot.in.a.name").getMaxDeliveryCount());
+ }
+
+ /*
+ * Tests that the virtual hosts with dots in the names are fully supported. The XML
+ * configuration had problems with handling the tags containing dots due to the design
+ * of the Apache Commons Configuration library. The dots need to be escaped when
+ * accessing the XML configuration.
+ */
+ public void testDotsInVirtualHostName() throws Exception
+ {
+ // Set up vhosts
+ getConfigXml().addProperty("virtualhosts.virtualhost.name", "dot.in.a.name");
+ // Add a single property which is inside the <dot.in.a.name> virtual host tag - the message store
+ getConfigXml().addProperty("virtualhosts.virtualhost.dot..in..a..name.store.class", TestableMemoryMessageStore.class.getName());
+
+ VirtualHost test = createVirtualHost("dot.in.a.name");
+
+ // Check, that the property stored within the <dot.in.a.name> tag has been properly loaded
+ assertEquals("virtual host with dots in the name has been properly loaded", TestableMemoryMessageStore.class.getName(), test.getMessageStore().getClass().getName());
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/AbstractConfigurationTest.java
index 14c7b8cb20..674abbfeb7 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/plugins/AbstractConfigurationTest.java
@@ -24,7 +24,7 @@ import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.List;
@@ -32,14 +32,14 @@ import java.util.List;
* Test that verifies that given a Configuration a ConfigurationPlugin can
* process and validate that data.
*/
-public class ConfigurationPluginTest extends InternalBrokerBaseCase
+public class AbstractConfigurationTest extends QpidTestCase
{
private static final double DOUBLE = 3.14;
private static final long POSITIVE_LONG = 1000;
private static final long NEGATIVE_LONG = -1000;
private static final int LIST_SIZE = 3;
- class ConfigPlugin extends ConfigurationPlugin
+ class TestConfigPlugin extends AbstractConfiguration
{
@Override
public String[] getElementsProcessed()
@@ -68,7 +68,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase
}
- private ConfigPlugin _plugin;
+ private TestConfigPlugin _plugin;
@Override
public void setUp() throws Exception
@@ -93,7 +93,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase
CompositeConfiguration composite = new CompositeConfiguration();
composite.addConfiguration(xmlconfig);
- _plugin = new ConfigPlugin();
+ _plugin = new TestConfigPlugin();
try
{
@@ -110,7 +110,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase
public void testHasConfiguration()
{
assertTrue("Plugin has no configuration ", _plugin.hasConfiguration());
- _plugin = new ConfigPlugin();
+ _plugin = new TestConfigPlugin();
assertFalse("Plugins has configuration", _plugin.hasConfiguration());
}
@@ -142,7 +142,7 @@ public class ConfigurationPluginTest extends InternalBrokerBaseCase
catch (ConfigurationException e)
{
assertEquals("negativeLong should not be reported as positive",
- "ConfigPlugin: unable to configure invalid negativeLong:" + NEGATIVE_LONG, e.getMessage());
+ "TestConfigPlugin: unable to configure invalid negativeLong:" + NEGATIVE_LONG, e.getMessage());
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
new file mode 100644
index 0000000000..c1ebe26f52
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java
@@ -0,0 +1,405 @@
+/*
+ *
+ * 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.startup;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+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.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory;
+import org.apache.qpid.server.model.adapter.PortFactory;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class BrokerRecovererTest extends TestCase
+{
+ private BrokerRecoverer _brokerRecoverer;
+ private ConfigurationEntry _brokerEntry = mock(ConfigurationEntry.class);
+
+ private UUID _brokerId = UUID.randomUUID();
+ private Map<String, Collection<ConfigurationEntry>> _brokerEntryChildren = new HashMap<String, Collection<ConfigurationEntry>>();
+ private ConfigurationEntry _authenticationProviderEntry1;
+ private AuthenticationProvider _authenticationProvider1;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ _brokerRecoverer = new BrokerRecoverer(mock(AuthenticationProviderFactory.class), mock(PortFactory.class), mock(StatisticsGatherer.class),
+ mock(VirtualHostRegistry.class), mock(LogRecorder.class), mock(RootMessageLogger.class), mock(TaskExecutor.class));
+ when(_brokerEntry.getId()).thenReturn(_brokerId);
+ when(_brokerEntry.getChildren()).thenReturn(_brokerEntryChildren);
+
+ //Add a base AuthenticationProvider for all tests
+ _authenticationProvider1 = mock(AuthenticationProvider.class);
+ when(_authenticationProvider1.getName()).thenReturn("authenticationProvider1");
+ _authenticationProviderEntry1 = mock(ConfigurationEntry.class);
+ _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1));
+ }
+
+ public void testCreateBrokerAttributes()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test");
+ attributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1");
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 9l);
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 8l);
+ attributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 7l);
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 6l);
+ attributes.put(Broker.ALERT_REPEAT_GAP, 5l);
+ attributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 5l);
+ attributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 3l);
+ attributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 2);
+ attributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, true);
+ attributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 1l);
+ attributes.put(Broker.ACL_FILE, "/path/to/acl");
+ attributes.put(Broker.SESSION_COUNT_LIMIT, 1000);
+ attributes.put(Broker.HEART_BEAT_DELAY, 2000);
+ attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000);
+ attributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, true);
+
+ Map<String, Object> entryAttributes = new HashMap<String, Object>();
+ for (Map.Entry<String, Object> attribute : attributes.entrySet())
+ {
+ String value = convertToString(attribute.getValue());
+ entryAttributes.put(attribute.getKey(), value);
+ }
+
+ when(_brokerEntry.getAttributes()).thenReturn(entryAttributes);
+
+ final ConfigurationEntry virtualHostEntry = mock(ConfigurationEntry.class);
+ String typeName = VirtualHost.class.getSimpleName();
+ when(virtualHostEntry.getType()).thenReturn(typeName);
+ _brokerEntryChildren.put(typeName, Arrays.asList(virtualHostEntry));
+ final VirtualHost virtualHost = mock(VirtualHost.class);
+ when(virtualHost.getName()).thenReturn("test");
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[] { virtualHostEntry, _authenticationProviderEntry1 },
+ new ConfiguredObject[] { virtualHost, _authenticationProvider1 });
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+
+ for (Map.Entry<String, Object> attribute : attributes.entrySet())
+ {
+ Object attributeValue = broker.getAttribute(attribute.getKey());
+ assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue);
+ }
+ }
+
+ public void testCreateBrokerWithVirtualHost()
+ {
+ final ConfigurationEntry virtualHostEntry = mock(ConfigurationEntry.class);
+
+ String typeName = VirtualHost.class.getSimpleName();
+ when(virtualHostEntry.getType()).thenReturn(typeName);
+ _brokerEntryChildren.put(typeName, Arrays.asList(virtualHostEntry));
+
+ final VirtualHost virtualHost = mock(VirtualHost.class);
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{virtualHostEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{virtualHost, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(1, broker.getVirtualHosts().size());
+ assertEquals(virtualHost, broker.getVirtualHosts().iterator().next());
+ }
+
+ public void testCreateBrokerWithPorts()
+ {
+ ConfigurationEntry portEntry = mock(ConfigurationEntry.class);
+ Port port = mock(Port.class);
+ _brokerEntryChildren.put(Port.class.getSimpleName(), Arrays.asList(portEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{portEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{port, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singletonList(port), broker.getPorts());
+ }
+
+ public void testCreateBrokerWithoutAuthenticationProviderThrowsException()
+ {
+ assertNotNull("expected to remove the base entry", _brokerEntryChildren.remove(AuthenticationProvider.class.getSimpleName()));
+ assertTrue("should be empty", _brokerEntryChildren.isEmpty());
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[0], new ConfiguredObject[0]);
+
+ try
+ {
+ _brokerRecoverer.create(recovererProvider, _brokerEntry);
+ fail("should have thrown an exception due to missing authentication provider configuration");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ //expected
+ }
+ }
+
+ public void testCreateBrokerWithOneAuthenticationProvider()
+ {
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{_authenticationProviderEntry1},
+ new ConfiguredObject[]{_authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singletonList(_authenticationProvider1), broker.getAuthenticationProviders());
+ }
+
+ public void testCreateBrokerWithMultipleAuthenticationProvidersAndNoDefaultThrowsException()
+ {
+ AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class);
+ when(authenticationProvider2.getName()).thenReturn("authenticationProvider2");
+ ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class);
+ _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2));
+
+ Map<String,Object> emptyBrokerAttributes = new HashMap<String,Object>();
+ when(_brokerEntry.getAttributes()).thenReturn(emptyBrokerAttributes);
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{authenticationProviderEntry2, _authenticationProviderEntry1},
+ new ConfiguredObject[]{authenticationProvider2, _authenticationProvider1});
+ try
+ {
+ _brokerRecoverer.create(recovererProvider, _brokerEntry);
+ fail("should have thrown an exception due to missing authentication provider default");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ //expected
+ }
+ }
+
+ public void testCreateBrokerWithMultipleAuthenticationProvidersAndPorts()
+ {
+ //Create a second authentication provider
+ AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class);
+ when(authenticationProvider2.getName()).thenReturn("authenticationProvider2");
+ ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class);
+ _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2));
+
+ //Set the default authentication provider
+ Map<String,Object> brokerAtttributes = new HashMap<String,Object>();
+ when(_brokerEntry.getAttributes()).thenReturn(brokerAtttributes);
+ brokerAtttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider2");
+
+ //Add a couple ports, one with a defined authentication provider and
+ //one without (which should then use the default)
+ ConfigurationEntry portEntry1 = mock(ConfigurationEntry.class);
+ Port port1 = mock(Port.class);
+ when(port1.getName()).thenReturn("port1");
+ when(port1.getPort()).thenReturn(5671);
+ when(port1.getAttribute(Port.AUTHENTICATION_MANAGER)).thenReturn("authenticationProvider1");
+ ConfigurationEntry portEntry2 = mock(ConfigurationEntry.class);
+ Port port2 = mock(Port.class);
+ when(port2.getName()).thenReturn("port2");
+ when(port2.getPort()).thenReturn(5672);
+ _brokerEntryChildren.put(Port.class.getSimpleName(), Arrays.asList(portEntry1, portEntry2));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(
+ new ConfigurationEntry[]{portEntry1, portEntry2, authenticationProviderEntry2, _authenticationProviderEntry1},
+ new ConfiguredObject[]{port1, port2, authenticationProvider2, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals("Unexpected number of authentication providers", 2,broker.getAuthenticationProviders().size());
+
+ Collection<Port> ports = broker.getPorts();
+ assertEquals("Unexpected number of ports", 2, ports.size());
+ assertTrue(ports.contains(port1));
+ assertTrue(ports.contains(port2));
+
+ verify(port1).setAuthenticationProvider(any(AuthenticationProvider.class));
+ verify(port1).setAuthenticationProvider(_authenticationProvider1);
+
+ verify(port2).setAuthenticationProvider(any(AuthenticationProvider.class));
+ verify(port2).setAuthenticationProvider(authenticationProvider2);
+ }
+
+ public void testCreateBrokerAssignsGroupAccessorToAuthenticationProviders()
+ {
+ //Create a second authentication provider
+ AuthenticationProvider authenticationProvider2 = mock(AuthenticationProvider.class);
+ when(authenticationProvider2.getName()).thenReturn("authenticationProvider2");
+ ConfigurationEntry authenticationProviderEntry2 = mock(ConfigurationEntry.class);
+ _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1, authenticationProviderEntry2));
+
+ //Set the default authentication provider
+ Map<String,Object> brokerAtttributes = new HashMap<String,Object>();
+ when(_brokerEntry.getAttributes()).thenReturn(brokerAtttributes);
+ brokerAtttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider2");
+
+ //Create a group provider
+ ConfigurationEntry groupProviderEntry = mock(ConfigurationEntry.class);
+ GroupProvider groupProvider = mock(GroupProvider.class);
+ _brokerEntryChildren.put(GroupProvider.class.getSimpleName(), Arrays.asList(groupProviderEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(
+ new ConfigurationEntry[]{groupProviderEntry, authenticationProviderEntry2, _authenticationProviderEntry1},
+ new ConfiguredObject[]{groupProvider, authenticationProvider2, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals("Unexpected number of authentication providers", 2, broker.getAuthenticationProviders().size());
+
+ //verify that a GroupAcessor was added to the AuthenticationProviders
+ verify(_authenticationProvider1).setGroupAccessor(any(GroupPrincipalAccessor.class));
+ verify(authenticationProvider2).setGroupAccessor(any(GroupPrincipalAccessor.class));
+ }
+
+ public void testCreateBrokerWithGroupProvider()
+ {
+ ConfigurationEntry groupProviderEntry = mock(ConfigurationEntry.class);
+ GroupProvider groupProvider = mock(GroupProvider.class);
+ _brokerEntryChildren.put(GroupProvider.class.getSimpleName(), Arrays.asList(groupProviderEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{groupProviderEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{groupProvider, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singletonList(groupProvider), broker.getGroupProviders());
+ }
+
+ public void testCreateBrokerWithPlugins()
+ {
+ ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class);
+ Plugin plugin = mock(Plugin.class);
+ _brokerEntryChildren.put(Plugin.class.getSimpleName(), Arrays.asList(pluginEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{plugin, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singleton(plugin), new HashSet<ConfiguredObject>(broker.getChildren(Plugin.class)));
+ }
+
+ public void testCreateBrokerWithKeyStores()
+ {
+ ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class);
+ KeyStore keyStore = mock(KeyStore.class);
+ _brokerEntryChildren.put(KeyStore.class.getSimpleName(), Arrays.asList(pluginEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{keyStore, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singleton(keyStore), new HashSet<ConfiguredObject>(broker.getChildren(KeyStore.class)));
+ }
+
+ public void testCreateBrokerWithTrustStores()
+ {
+ ConfigurationEntry pluginEntry = mock(ConfigurationEntry.class);
+ TrustStore trustStore = mock(TrustStore.class);
+ _brokerEntryChildren.put(TrustStore.class.getSimpleName(), Arrays.asList(pluginEntry));
+
+ RecovererProvider recovererProvider = createRecoveryProvider(new ConfigurationEntry[]{pluginEntry, _authenticationProviderEntry1},
+ new ConfiguredObject[]{trustStore, _authenticationProvider1});
+
+ Broker broker = _brokerRecoverer.create(recovererProvider, _brokerEntry);
+
+ assertNotNull(broker);
+ assertEquals(_brokerId, broker.getId());
+ assertEquals(Collections.singleton(trustStore), new HashSet<ConfiguredObject>(broker.getChildren(TrustStore.class)));
+ }
+
+ private String convertToString(Object attributeValue)
+ {
+ return String.valueOf(attributeValue);
+ }
+
+ private RecovererProvider createRecoveryProvider(final ConfigurationEntry[] entries, final ConfiguredObject[] objectsToRecoverer)
+ {
+ RecovererProvider recovererProvider = new RecovererProvider()
+ {
+ @Override
+ public ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type)
+ {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final ConfiguredObjectRecoverer<? extends ConfiguredObject> recovever = new ConfiguredObjectRecoverer()
+ {
+ @Override
+ public ConfiguredObject create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
+ {
+ for (int i = 0; i < entries.length; i++)
+ {
+ ConfigurationEntry e = entries[i];
+ if (entry == e)
+ {
+ return objectsToRecoverer[i];
+ }
+ }
+ return null;
+ }
+ };
+
+ return recovever;
+ }
+ };
+ return recovererProvider;
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.java
new file mode 100644
index 0000000000..c95f67beb9
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProviderTest.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.configuration.startup;
+
+import static org.mockito.Mockito.mock;
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class DefaultRecovererProviderTest extends TestCase
+{
+ public void testGetRecoverer()
+ {
+ String[] supportedTypes = {Broker.class.getSimpleName(),
+ VirtualHost.class.getSimpleName(), AuthenticationProvider.class.getSimpleName(),
+ GroupProvider.class.getSimpleName(), Plugin.class.getSimpleName(), Port.class.getSimpleName()};
+
+ // mocking the required object
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ VirtualHostRegistry virtualHostRegistry = mock(VirtualHostRegistry.class);
+ LogRecorder logRecorder = mock(LogRecorder.class);
+ RootMessageLogger rootMessageLogger = mock(RootMessageLogger.class);
+ TaskExecutor taskExecutor = mock(TaskExecutor.class);
+
+ DefaultRecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, logRecorder, rootMessageLogger, taskExecutor);
+ for (String configuredObjectType : supportedTypes)
+ {
+ ConfiguredObjectRecoverer<?> recovever = provider.getRecoverer(configuredObjectType);
+ assertNotNull("Null recoverer for type: " + configuredObjectType, recovever);
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.java
new file mode 100644
index 0000000000..6713574e4b
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/GroupProviderRecovererTest.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.configuration.startup;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.plugin.GroupManagerFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.security.group.GroupManager;
+
+import junit.framework.TestCase;
+
+public class GroupProviderRecovererTest extends TestCase
+{
+
+ private UUID _id;
+ private Map<String, Object> _attributes;
+
+ private GroupManagerFactory _factory;
+ private QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader;
+ private Broker _broker;
+ private ConfigurationEntry _configurationEntry;
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _id = UUID.randomUUID();
+ _attributes = new HashMap<String, Object>();
+
+ _factory = mock(GroupManagerFactory.class);
+
+ _groupManagerServiceLoader = mock(QpidServiceLoader.class);
+ when(_groupManagerServiceLoader.instancesOf(GroupManagerFactory.class)).thenReturn(Collections.singletonList(_factory ));
+
+ _broker = mock(Broker.class);
+
+ _configurationEntry = mock(ConfigurationEntry.class);
+ when(_configurationEntry.getId()).thenReturn(_id);
+ when(_configurationEntry.getAttributes()).thenReturn(_attributes);
+ }
+
+ public void testCreate()
+ {
+ GroupManager groupManager = mock(GroupManager.class);
+ String name = groupManager.getClass().getSimpleName();
+ when(_factory.createInstance(_attributes)).thenReturn(groupManager);
+ GroupProviderRecoverer groupProviderRecoverer = new GroupProviderRecoverer(_groupManagerServiceLoader);
+ GroupProvider groupProvider = groupProviderRecoverer.create(null, _configurationEntry, _broker);
+ assertNotNull("Null group provider", groupProvider);
+ assertEquals("Unexpected name", name, groupProvider.getName());
+ assertEquals("Unexpected ID", _id, groupProvider.getId());
+ }
+
+ public void testCreateThrowsExceptionWhenNoGroupManagerIsCreated()
+ {
+ when(_factory.createInstance(_attributes)).thenReturn(null);
+
+ GroupProviderRecoverer groupProviderRecoverer = new GroupProviderRecoverer(_groupManagerServiceLoader);
+ try
+ {
+ groupProviderRecoverer.create(null, _configurationEntry, _broker);
+ fail("Configuration exception should be thrown when group manager is not created");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java
new file mode 100644
index 0000000000..0d7dc1bb06
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/KeyStoreRecovererTest.java
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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.startup;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.TrustStore;
+
+import junit.framework.TestCase;
+
+public class KeyStoreRecovererTest extends TestCase
+{
+
+ public void testCreateWithAllAttributesProvided()
+ {
+ Map<String, Object> attributes = getKeyStoreAttributes();
+
+ UUID id = UUID.randomUUID();
+ Broker broker = mock(Broker.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ when(entry.getAttributes()).thenReturn(attributes);
+ when(entry.getId()).thenReturn(id);
+
+ KeyStoreRecoverer recovever = new KeyStoreRecoverer();
+
+ KeyStore KeyStore = recovever.create(null, entry, broker);
+ assertNotNull("Key store configured object is not created", KeyStore);
+ assertEquals(id, KeyStore.getId());
+ assertEquals("my-secret-password", KeyStore.getPassword());
+
+ assertNull("Password was unexpectedly returned from configured object", KeyStore.getAttribute(TrustStore.PASSWORD));
+
+ // password attribute should not be exposed by a key store configured object
+ // so, we should set password value to null in the map being used to create the key store configured object
+ attributes.put(KeyStore.PASSWORD, null);
+ for (Map.Entry<String, Object> attribute : attributes.entrySet())
+ {
+ Object attributeValue = KeyStore.getAttribute(attribute.getKey());
+ assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue);
+ }
+ }
+
+ private Map<String, Object> getKeyStoreAttributes()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(KeyStore.NAME, getName());
+ attributes.put(KeyStore.PATH, "/path/to/KeyStore");
+ attributes.put(KeyStore.PASSWORD, "my-secret-password");
+ attributes.put(KeyStore.TYPE, "NON-JKS");
+ attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD");
+ attributes.put(KeyStore.CERTIFICATE_ALIAS, "my-cert-alias");
+ attributes.put(KeyStore.DESCRIPTION, "description");
+ return attributes;
+ }
+
+ public void testCreateWithMissedRequiredAttributes()
+ {
+ Map<String, Object> attributes = getKeyStoreAttributes();
+
+ UUID id = UUID.randomUUID();
+ Broker broker = mock(Broker.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ when(entry.getId()).thenReturn(id);
+
+ KeyStoreRecoverer recovever = new KeyStoreRecoverer();
+
+ String[] mandatoryProperties = {KeyStore.NAME, KeyStore.PATH, KeyStore.PASSWORD};
+ for (int i = 0; i < mandatoryProperties.length; i++)
+ {
+ Map<String, Object> properties = new HashMap<String, Object>(attributes);
+ properties.remove(mandatoryProperties[i]);
+ when(entry.getAttributes()).thenReturn(properties);
+ try
+ {
+ recovever.create(null, entry, broker);
+ fail("Cannot create key store without a " + mandatoryProperties[i]);
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java
new file mode 100644
index 0000000000..42fd742407
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/PluginRecovererTest.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.startup;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+
+public class PluginRecovererTest extends TestCase
+{
+ private UUID _id;
+ private Map<String, Object> _attributes;
+
+ private PluginFactory _factory;
+ private QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader;
+ private Broker _broker;
+ private ConfigurationEntry _configurationEntry;
+
+ @SuppressWarnings("unchecked")
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _id = UUID.randomUUID();
+ _attributes = new HashMap<String, Object>();
+
+ _factory = mock(PluginFactory.class);
+
+ _pluginFactoryServiceLoader = mock(QpidServiceLoader.class);
+ when(_pluginFactoryServiceLoader.instancesOf(PluginFactory.class)).thenReturn(Collections.singletonList(_factory ));
+
+ _broker = mock(Broker.class);
+
+ _configurationEntry = mock(ConfigurationEntry.class);
+ when(_configurationEntry.getId()).thenReturn(_id);
+ when(_configurationEntry.getAttributes()).thenReturn(_attributes);
+ }
+
+ public void testCreate()
+ {
+ Plugin pluginFromFactory = mock(Plugin.class);
+ when(pluginFromFactory.getId()).thenReturn(_id);
+ when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(pluginFromFactory);
+
+ PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader);
+ ConfiguredObject pluginFromRecoverer = pluginRecoverer.create(null, _configurationEntry, _broker);
+ assertNotNull("Null group provider", pluginFromRecoverer);
+ assertSame("Unexpected plugin", pluginFromFactory, pluginFromRecoverer);
+ assertEquals("Unexpected ID", _id, pluginFromRecoverer.getId());
+ }
+
+ public void testCreateThrowsExceptionForUnexpectedId()
+ {
+ Plugin pluginFromFactory = mock(Plugin.class);
+ when(pluginFromFactory.getId()).thenReturn(UUID.randomUUID());
+ when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(pluginFromFactory);
+
+ PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader);
+ try
+ {
+ pluginRecoverer.create(null, _configurationEntry, _broker);
+ fail("An exception should be thrown for incorrect id");
+ }
+ catch(IllegalStateException e)
+ {
+ //pass
+ }
+ }
+
+ public void testCreateThrowsExceptionWhenNoPluginIsCreated()
+ {
+ when(_factory.createInstance(_id, _attributes, _broker)).thenReturn(null);
+
+ PluginRecoverer pluginRecoverer = new PluginRecoverer(_pluginFactoryServiceLoader);
+ try
+ {
+ pluginRecoverer.create(null, _configurationEntry, _broker);
+ fail("Configuration exception should be thrown when plugin is not created");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java
new file mode 100644
index 0000000000..3b64f45c80
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/TrustStoreRecovererTest.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.startup;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class TrustStoreRecovererTest extends QpidTestCase
+{
+ public void testCreateWithAllAttributesProvided()
+ {
+ Map<String, Object> attributes = getTrustStoreAttributes();
+
+ UUID id = UUID.randomUUID();
+ Broker broker = mock(Broker.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ when(entry.getAttributes()).thenReturn(attributes);
+ when(entry.getId()).thenReturn(id);
+
+ TrustStoreRecoverer recovever = new TrustStoreRecoverer();
+
+ TrustStore trustStore = recovever.create(null, entry, broker);
+ assertNotNull("Trust store configured object is not created", trustStore);
+ assertEquals(id, trustStore.getId());
+ assertEquals("my-secret-password", trustStore.getPassword());
+
+ assertNull("Password was unexpectedly returned from configured object", trustStore.getAttribute(TrustStore.PASSWORD));
+
+ // password attribute should not be exposed by a trust store configured object
+ // so, we should set password value to null in the map being used to create the trust store configured object
+ attributes.put(TrustStore.PASSWORD, null);
+ for (Map.Entry<String, Object> attribute : attributes.entrySet())
+ {
+ Object attributeValue = trustStore.getAttribute(attribute.getKey());
+ assertEquals("Unexpected value of attribute '" + attribute.getKey() + "'", attribute.getValue(), attributeValue);
+ }
+ }
+
+ private Map<String, Object> getTrustStoreAttributes()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(TrustStore.NAME, getName());
+ attributes.put(TrustStore.PATH, "/path/to/truststore");
+ attributes.put(TrustStore.PASSWORD, "my-secret-password");
+ attributes.put(TrustStore.TYPE, "NON-JKS");
+ attributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD");
+ attributes.put(TrustStore.DESCRIPTION, "Description");
+ return attributes;
+ }
+
+ public void testCreateWithMissedRequiredAttributes()
+ {
+ Map<String, Object> attributes = getTrustStoreAttributes();
+
+ UUID id = UUID.randomUUID();
+ Broker broker = mock(Broker.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ when(entry.getAttributes()).thenReturn(attributes);
+ when(entry.getId()).thenReturn(id);
+
+ TrustStoreRecoverer recovever = new TrustStoreRecoverer();
+
+ String[] mandatoryProperties = {TrustStore.NAME, TrustStore.PATH, TrustStore.PASSWORD};
+ for (int i = 0; i < mandatoryProperties.length; i++)
+ {
+ Map<String, Object> properties = new HashMap<String, Object>(attributes);
+ properties.remove(mandatoryProperties[i]);
+ when(entry.getAttributes()).thenReturn(properties);
+ try
+ {
+ recovever.create(null, entry, broker);
+ fail("Cannot create key store without a " + mandatoryProperties[i]);
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
new file mode 100644
index 0000000000..57d219f85f
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostRecovererTest.java
@@ -0,0 +1,124 @@
+/*
+ *
+ * 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.startup;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+
+public class VirtualHostRecovererTest extends TestCase
+{
+ public void testCreate()
+ {
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ SecurityManager securityManager = mock(SecurityManager.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ Broker parent = mock(Broker.class);
+ when(parent.getSecurityManager()).thenReturn(securityManager);
+
+ VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer);
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.NAME, getName());
+ attributes.put(VirtualHost.CONFIG_PATH, "/path/to/virtualhost.xml");
+ when(entry.getAttributes()).thenReturn(attributes);
+
+ VirtualHost host = recoverer.create(null, entry, parent);
+
+ assertNotNull("Null is returned", host);
+ assertEquals("Unexpected name", getName(), host.getName());
+ }
+
+ public void testCreateVirtualHostFromStoreConfigAtrributes()
+ {
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ SecurityManager securityManager = mock(SecurityManager.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ Broker parent = mock(Broker.class);
+ when(parent.getSecurityManager()).thenReturn(securityManager);
+
+ VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer);
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.NAME, getName());
+ attributes.put(VirtualHost.STORE_PATH, "/path/to/virtualhost/store");
+ attributes.put(VirtualHost.STORE_TYPE, "DERBY");
+ when(entry.getAttributes()).thenReturn(attributes);
+
+ VirtualHost host = recoverer.create(null, entry, parent);
+
+ assertNotNull("Null is returned", host);
+ assertEquals("Unexpected name", getName(), host.getName());
+ }
+
+ public void testCreateWithoutMandatoryAttributesResultsInException()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.NAME, getName());
+ attributes.put(VirtualHost.CONFIG_PATH, "/path/to/virtualhost.xml");
+ String[] mandatoryAttributes = {VirtualHost.NAME, VirtualHost.CONFIG_PATH};
+
+ checkMandatoryAttributesAreValidated(mandatoryAttributes, attributes);
+
+ attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.NAME, getName());
+ attributes.put(VirtualHost.STORE_PATH, "/path/to/store");
+ attributes.put(VirtualHost.STORE_TYPE, "DERBY");
+ mandatoryAttributes = new String[]{VirtualHost.NAME, VirtualHost.STORE_PATH, VirtualHost.STORE_TYPE};
+
+ checkMandatoryAttributesAreValidated(mandatoryAttributes, attributes);
+ }
+
+ public void checkMandatoryAttributesAreValidated(String[] mandatoryAttributes, Map<String, Object> attributes)
+ {
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ SecurityManager securityManager = mock(SecurityManager.class);
+ ConfigurationEntry entry = mock(ConfigurationEntry.class);
+ Broker parent = mock(Broker.class);
+ when(parent.getSecurityManager()).thenReturn(securityManager);
+ VirtualHostRecoverer recoverer = new VirtualHostRecoverer(statisticsGatherer);
+
+ for (String name : mandatoryAttributes)
+ {
+ Map<String, Object> copy = new HashMap<String, Object>(attributes);
+ copy.remove(name);
+ when(entry.getAttributes()).thenReturn(copy);
+ try
+ {
+ recoverer.create(null, entry, parent);
+ fail("Cannot create a virtual host without a manadatory attribute " + name);
+ }
+ catch(IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java
new file mode 100644
index 0000000000..b357c0b8e9
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java
@@ -0,0 +1,392 @@
+/*
+ *
+ * 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.store;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase
+{
+ private ConfigurationEntryStore _store;
+
+ private UUID _brokerId;
+ private UUID _virtualHostId;
+ private UUID _authenticationProviderId;
+
+ private Map<String, Object> _brokerAttributes;
+ private Map<String, Object> _virtualHostAttributes;
+ private Map<String, Object> _authenticationProviderAttributes;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ _brokerId = UUID.randomUUID();
+ _brokerAttributes = new HashMap<String, Object>();
+ _brokerAttributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test");
+ _brokerAttributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1");
+ _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 9);
+ _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 8);
+ _brokerAttributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 7);
+ _brokerAttributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 6);
+ _brokerAttributes.put(Broker.ALERT_REPEAT_GAP, 5);
+ _brokerAttributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 5);
+ _brokerAttributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 3);
+ _brokerAttributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 2);
+ _brokerAttributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, true);
+ _brokerAttributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 1);
+ _brokerAttributes.put(Broker.ACL_FILE, "/path/to/acl");
+ _brokerAttributes.put(Broker.SESSION_COUNT_LIMIT, 1000);
+ _brokerAttributes.put(Broker.HEART_BEAT_DELAY, 2000);
+ _brokerAttributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000);
+ _brokerAttributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, true);
+
+ _virtualHostId = UUID.randomUUID();
+ _virtualHostAttributes = new HashMap<String, Object>();
+ _virtualHostAttributes.put(VirtualHost.NAME, "test");
+ _virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/test");
+
+ _authenticationProviderId = UUID.randomUUID();
+ _authenticationProviderAttributes = new HashMap<String, Object>();
+ _authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1");
+ _authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, AnonymousAuthenticationManager.class.getSimpleName());
+
+ _store = createStore(_brokerId, _brokerAttributes);
+ addConfiguration(_virtualHostId, VirtualHost.class.getSimpleName(), _virtualHostAttributes);
+ addConfiguration(_authenticationProviderId, AuthenticationProvider.class.getSimpleName(), _authenticationProviderAttributes);
+ }
+
+ // ??? perhaps it should not be abstract
+ protected abstract ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception;
+
+ protected abstract void addConfiguration(UUID id, String type, Map<String, Object> attributes);
+
+ protected ConfigurationEntryStore getStore()
+ {
+ return _store;
+ }
+
+ public void testGetRootEntry()
+ {
+ ConfigurationEntry brokerConfigEntry = _store.getRootEntry();
+ assertNotNull("Root entry does not exist", brokerConfigEntry);
+ assertEquals("Unexpected id", _brokerId, brokerConfigEntry.getId());
+ assertEquals("Unexpected type ", Broker.class.getSimpleName(), brokerConfigEntry.getType());
+ Map<String, Object> attributes = brokerConfigEntry.getAttributes();
+ assertNotNull("Attributes cannot be null", attributes);
+ assertEquals("Unexpected attributes", _brokerAttributes, attributes);
+ }
+
+ public void testGetEntry()
+ {
+ ConfigurationEntry authenticationProviderConfigEntry = _store.getEntry(_authenticationProviderId);
+ assertNotNull("Provider with id " + _authenticationProviderId + " should exist", authenticationProviderConfigEntry);
+ assertEquals("Unexpected id", _authenticationProviderId, authenticationProviderConfigEntry.getId());
+ assertEquals("Unexpected type ", AuthenticationProvider.class.getSimpleName(), authenticationProviderConfigEntry.getType());
+ Map<String, Object> attributes = authenticationProviderConfigEntry.getAttributes();
+ assertNotNull("Attributes cannot be null", attributes);
+ assertEquals("Unexpected attributes", _authenticationProviderAttributes, attributes);
+ }
+
+ public void testRemove()
+ {
+ Map<String, Object> virtualHostAttributes = new HashMap<String, Object>();
+ virtualHostAttributes.put(VirtualHost.NAME, getName());
+ virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config");
+ UUID virtualHostId = UUID.randomUUID();
+ addConfiguration(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes);
+
+ assertNotNull("Virtual host with id " + virtualHostId + " should exist", _store.getEntry(virtualHostId));
+
+ _store.remove(virtualHostId);
+ assertNull("Authentication provider configuration should be removed", _store.getEntry(virtualHostId));
+ }
+
+ public void testRemoveMultipleEntries()
+ {
+ Map<String, Object> virtualHost1Attributes = new HashMap<String, Object>();
+ virtualHost1Attributes.put(VirtualHost.NAME, "test1");
+ virtualHost1Attributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1");
+ UUID virtualHost1Id = UUID.randomUUID();
+ addConfiguration(virtualHost1Id, VirtualHost.class.getSimpleName(), virtualHost1Attributes);
+
+ Map<String, Object> virtualHost2Attributes = new HashMap<String, Object>();
+ virtualHost2Attributes.put(VirtualHost.NAME, "test1");
+ virtualHost2Attributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config2");
+ UUID virtualHost2Id = UUID.randomUUID();
+ addConfiguration(virtualHost2Id, VirtualHost.class.getSimpleName(), virtualHost2Attributes);
+
+ assertNotNull("Virtual host with id " + virtualHost1Id + " should exist", _store.getEntry(virtualHost1Id));
+ assertNotNull("Virtual host with id " + virtualHost2Id + " should exist", _store.getEntry(virtualHost2Id));
+
+ UUID[] deletedIds = _store.remove(virtualHost1Id, virtualHost2Id);
+ assertNotNull("Unexpected deleted ids", deletedIds);
+ assertEquals("Unexpected id of first deleted virtual host", virtualHost1Id , deletedIds[0]);
+ assertEquals("Unexpected id of second deleted virtual host", virtualHost2Id , deletedIds[1]);
+ assertNull("First virtual host configuration should be removed", _store.getEntry(virtualHost1Id));
+ assertNull("Second virtual host configuration should be removed", _store.getEntry(virtualHost2Id));
+ }
+
+ public void testSaveBroker()
+ {
+ ConfigurationEntry brokerConfigEntry = _store.getRootEntry();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Broker.DEFAULT_VIRTUAL_HOST, "test");
+ attributes.put(Broker.DEFAULT_AUTHENTICATION_PROVIDER, "authenticationProvider1");
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, 19);
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, 18);
+ attributes.put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, 17);
+ attributes.put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, 16);
+ attributes.put(Broker.ALERT_REPEAT_GAP, 15);
+ attributes.put(Broker.FLOW_CONTROL_SIZE_BYTES, 15);
+ attributes.put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, 13);
+ attributes.put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, 12);
+ attributes.put(Broker.DEAD_LETTER_QUEUE_ENABLED, false);
+ attributes.put(Broker.HOUSEKEEPING_CHECK_PERIOD, 11);
+ attributes.put(Broker.ACL_FILE, "/path/to/acl1");
+ attributes.put(Broker.SESSION_COUNT_LIMIT, 11000);
+ attributes.put(Broker.HEART_BEAT_DELAY, 12000);
+ attributes.put(Broker.STATISTICS_REPORTING_PERIOD, 14000);
+ attributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, false);
+ ConfigurationEntry updatedBrokerEntry = new ConfigurationEntry(_brokerId, Broker.class.getSimpleName(), attributes,
+ brokerConfigEntry.getChildrenIds(), _store);
+
+ _store.save(updatedBrokerEntry);
+
+ ConfigurationEntry newBrokerConfigEntry = _store.getRootEntry();
+ assertNotNull("Root entry does not exist", newBrokerConfigEntry);
+ assertEquals("Unexpected id", _brokerId, newBrokerConfigEntry.getId());
+ assertEquals("Unexpected type ", Broker.class.getSimpleName(), newBrokerConfigEntry.getType());
+ Map<String, Object> newBrokerattributes = newBrokerConfigEntry.getAttributes();
+ assertNotNull("Attributes cannot be null", newBrokerattributes);
+ assertEquals("Unexpected attributes", attributes, newBrokerattributes);
+ }
+
+ public void testSaveNewVirtualHost()
+ {
+ Map<String, Object> virtualHostAttributes = new HashMap<String, Object>();
+ virtualHostAttributes.put(VirtualHost.NAME, "test1");
+ virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1");
+ UUID virtualHostId = UUID.randomUUID();
+ ConfigurationEntry hostEntry = new ConfigurationEntry(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes,
+ Collections.<UUID> emptySet(), _store);
+
+ _store.save(hostEntry);
+
+ ConfigurationEntry configurationEntry = _store.getEntry(virtualHostId);
+ assertEquals("Unexpected virtual host configuration", hostEntry, configurationEntry);
+ assertEquals("Unexpected type", VirtualHost.class.getSimpleName(), configurationEntry.getType());
+ assertEquals("Unexpected virtual host attributes", hostEntry.getAttributes(), configurationEntry.getAttributes());
+ assertTrue("Unexpected virtual host children found", hostEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSaveExistingVirtualHost()
+ {
+ ConfigurationEntry hostEntry = _store.getEntry(_virtualHostId);
+ assertNotNull("Host configuration is not found", hostEntry);
+
+ Map<String, Object> virtualHostAttributes = new HashMap<String, Object>();
+ virtualHostAttributes.put(VirtualHost.NAME, "test");
+ virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/new/phantom/test/configuration");
+
+ ConfigurationEntry updatedEntry = new ConfigurationEntry(_virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes,
+ hostEntry.getChildrenIds(), _store);
+ _store.save(updatedEntry);
+
+ ConfigurationEntry newHostEntry = _store.getEntry(_virtualHostId);
+ assertEquals("Unexpected virtual host configuration", updatedEntry, newHostEntry);
+ assertEquals("Unexpected type", VirtualHost.class.getSimpleName(), newHostEntry.getType());
+ assertEquals("Unexpected virtual host attributes", updatedEntry.getAttributes(), newHostEntry.getAttributes());
+ assertEquals("Unexpected virtual host children found", updatedEntry.getChildrenIds(), newHostEntry.getChildrenIds());
+ }
+
+ public void testSaveNewAuthenticationProvider()
+ {
+ UUID authenticationProviderId = UUID.randomUUID();
+ Map<String, Object> authenticationProviderAttributes = new HashMap<String, Object>();
+ authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1");
+ authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManager.class.getSimpleName());
+ ConfigurationEntry providerEntry = new ConfigurationEntry(authenticationProviderId, AuthenticationProvider.class.getSimpleName(),
+ authenticationProviderAttributes, Collections.<UUID> emptySet(), _store);
+
+ _store.save(providerEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(authenticationProviderId);
+ assertEquals("Unexpected provider configuration", providerEntry, storeEntry);
+ assertEquals("Unexpected type", AuthenticationProvider.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected provider attributes", providerEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSaveExistingAuthenticationProvider()
+ {
+ ConfigurationEntry providerEntry = _store.getEntry(_authenticationProviderId);
+ assertNotNull("provider configuration is not found", providerEntry);
+
+ Map<String, Object> authenticationProviderAttributes = new HashMap<String, Object>();
+ authenticationProviderAttributes.put(AuthenticationProvider.NAME, "authenticationProvider1");
+ authenticationProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManager.class.getSimpleName());
+ ConfigurationEntry updatedEntry = new ConfigurationEntry(_authenticationProviderId, AuthenticationProvider.class.getSimpleName(),
+ authenticationProviderAttributes, Collections.<UUID> emptySet(), _store);
+ _store.save(updatedEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(_authenticationProviderId);
+ assertEquals("Unexpected provider configuration", updatedEntry, storeEntry);
+ assertEquals("Unexpected type", AuthenticationProvider.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected provider attributes", updatedEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSaveTrustStore()
+ {
+ UUID trustStoreId = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(TrustStore.NAME, getName());
+ attributes.put(TrustStore.PATH, "/path/to/truststore");
+ attributes.put(TrustStore.PASSWORD, "my-secret-password");
+ attributes.put(TrustStore.TYPE, "NON-JKS");
+ attributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD");
+ attributes.put(TrustStore.DESCRIPTION, "Description");
+
+ ConfigurationEntry trustStoreEntry = new ConfigurationEntry(trustStoreId, TrustStore.class.getSimpleName(), attributes,
+ Collections.<UUID> emptySet(), _store);
+
+ _store.save(trustStoreEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(trustStoreId);
+ assertEquals("Unexpected trust store configuration", trustStoreEntry, storeEntry);
+ assertEquals("Unexpected type", TrustStore.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected provider attributes", trustStoreEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSaveKeyStore()
+ {
+ UUID keyStoreId = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(KeyStore.NAME, getName());
+ attributes.put(KeyStore.PATH, "/path/to/truststore");
+ attributes.put(KeyStore.PASSWORD, "my-secret-password");
+ attributes.put(KeyStore.TYPE, "NON-JKS");
+ attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD");
+ attributes.put(KeyStore.DESCRIPTION, "Description");
+ attributes.put(KeyStore.CERTIFICATE_ALIAS, "Alias");
+
+ ConfigurationEntry keyStoreEntry = new ConfigurationEntry(keyStoreId, KeyStore.class.getSimpleName(), attributes, Collections.<UUID> emptySet(),
+ _store);
+
+ _store.save(keyStoreEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(keyStoreId);
+ assertEquals("Unexpected key store configuration", keyStoreEntry, storeEntry);
+ assertEquals("Unexpected type", KeyStore.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected provider attributes", keyStoreEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSaveGroupProvider()
+ {
+ UUID groupProviderId = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(GroupProvider.NAME, getName());
+
+ ConfigurationEntry groupProviderEntry = new ConfigurationEntry(groupProviderId, GroupProvider.class.getSimpleName(), attributes,
+ Collections.<UUID> emptySet(), _store);
+
+ _store.save(groupProviderEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(groupProviderId);
+ assertEquals("Unexpected group provider configuration", groupProviderEntry, storeEntry);
+ assertEquals("Unexpected type", GroupProvider.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected group provider attributes", groupProviderEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected provider children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testSavePort()
+ {
+ UUID portId = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ Set<String> tcpTransportSet = Collections.singleton(Transport.TCP.name());
+ attributes.put(Port.PORT, 9999);
+ attributes.put(Port.TRANSPORTS, tcpTransportSet);
+ attributes.put(Port.TCP_NO_DELAY, true);
+ attributes.put(Port.RECEIVE_BUFFER_SIZE, 1);
+ attributes.put(Port.SEND_BUFFER_SIZE, 2);
+ attributes.put(Port.NEED_CLIENT_AUTH, true);
+ attributes.put(Port.WANT_CLIENT_AUTH, true);
+
+ ConfigurationEntry portEntry = new ConfigurationEntry(portId, Port.class.getSimpleName(), attributes, Collections.<UUID> emptySet(), _store);
+
+ _store.save(portEntry);
+
+ ConfigurationEntry storeEntry = _store.getEntry(portId);
+ assertEquals("Unexpected port configuration", portEntry, storeEntry);
+ assertEquals("Unexpected type", Port.class.getSimpleName(), storeEntry.getType());
+ assertEquals("Unexpected port attributes", portEntry.getAttributes(), storeEntry.getAttributes());
+ assertTrue("Unexpected port children found", storeEntry.getChildrenIds().isEmpty());
+ }
+
+ public void testMultipleSave()
+ {
+ UUID virtualHostId = UUID.randomUUID();
+ Map<String, Object> virtualHostAttributes = new HashMap<String, Object>();
+ virtualHostAttributes.put(VirtualHost.NAME, "test1");
+ virtualHostAttributes.put(VirtualHost.CONFIG_PATH, "/path/to/phantom/virtualhost/config1");
+ ConfigurationEntry hostEntry = new ConfigurationEntry(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes,
+ Collections.<UUID> emptySet(), _store);
+
+ UUID keyStoreId = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(KeyStore.NAME, getName());
+ attributes.put(KeyStore.PATH, "/path/to/truststore");
+ attributes.put(KeyStore.PASSWORD, "my-secret-password");
+ attributes.put(KeyStore.TYPE, "NON-JKS");
+ attributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, "NON-STANDARD");
+ attributes.put(KeyStore.DESCRIPTION, "Description");
+ attributes.put(KeyStore.CERTIFICATE_ALIAS, "Alias");
+
+ ConfigurationEntry keyStoreEntry = new ConfigurationEntry(keyStoreId, KeyStore.class.getSimpleName(), attributes, Collections.<UUID> emptySet(),
+ _store);
+
+ _store.save(hostEntry, keyStoreEntry);
+
+ assertNotNull("Virtual host is not found", _store.getEntry(virtualHostId));
+ assertNotNull("Key store is not found", _store.getEntry(keyStoreId));
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java
new file mode 100644
index 0000000000..7c9f4889f8
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStoreTest.java
@@ -0,0 +1,216 @@
+package org.apache.qpid.server.configuration.store;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+
+public class JsonConfigurationEntryStoreTest extends ConfigurationEntryStoreTestCase
+{
+ private File _storeFile;
+ private ObjectMapper _objectMapper;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _objectMapper = new ObjectMapper();
+ _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ _storeFile.delete();
+ super.tearDown();
+ }
+
+ @Override
+ protected ConfigurationEntryStore createStore(UUID brokerId, Map<String, Object> brokerAttributes) throws Exception
+ {
+ _storeFile = createStoreFile(brokerId, brokerAttributes);
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(_storeFile.getAbsolutePath());
+ return store;
+ }
+
+ private File createStoreFile(UUID brokerId, Map<String, Object> brokerAttributes) throws IOException,
+ JsonGenerationException, JsonMappingException
+ {
+ Map<String, Object> brokerObjectMap = new HashMap<String, Object>();
+ brokerObjectMap.put(Broker.ID, brokerId);
+ brokerObjectMap.put("@type", Broker.class.getSimpleName());
+ brokerObjectMap.putAll(brokerAttributes);
+
+ StringWriter sw = new StringWriter();
+ _objectMapper.writeValue(sw, brokerObjectMap);
+
+ String brokerJson = sw.toString();
+
+ return TestFileUtils.createTempFile(this, ".json", brokerJson);
+ }
+
+ @Override
+ protected void addConfiguration(UUID id, String type, Map<String, Object> attributes)
+ {
+ ConfigurationEntryStore store = getStore();
+ store.save(new ConfigurationEntry(id, type, attributes, Collections.<UUID> emptySet(), store));
+ }
+
+ public void testAttributeIsResolvedFromSystemProperties()
+ {
+ String aclLocation = "path/to/acl/" + getTestName();
+ setTestSystemProperty("my.test.property", aclLocation);
+
+ ConfigurationEntryStore store = getStore();
+ ConfigurationEntry brokerConfigEntry = store.getRootEntry();
+ Map<String, Object> attributes = new HashMap<String, Object>(brokerConfigEntry.getAttributes());
+ attributes.put(Broker.ACL_FILE, "${my.test.property}");
+ ConfigurationEntry updatedBrokerEntry = new ConfigurationEntry(brokerConfigEntry.getId(), Broker.class.getSimpleName(),
+ attributes, brokerConfigEntry.getChildrenIds(), store);
+ store.save(updatedBrokerEntry);
+
+ JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore();
+ store2.open(_storeFile.getAbsolutePath());
+
+ assertEquals("Unresolved ACL value", aclLocation, store2.getRootEntry().getAttributes().get(Broker.ACL_FILE));
+ }
+
+ public void testOpenEmpty()
+ {
+ File file = TestFileUtils.createTempFile(this, ".json");
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(file.getAbsolutePath());
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ store.copyTo(file.getAbsolutePath());
+
+ JsonConfigurationEntryStore store2 = new JsonConfigurationEntryStore();
+ store2.open(file.getAbsolutePath());
+ ConfigurationEntry root2 = store.getRootEntry();
+ assertEquals("Unexpected root entry", root.getId(), root2.getId());
+ }
+
+ public void testOpenNotEmpty() throws Exception
+ {
+ UUID brokerId = UUID.randomUUID();
+ Map<String, Object> brokerAttributes = new HashMap<String, Object>();
+ brokerAttributes.put(Broker.NAME, getTestName());
+ File file = createStoreFile(brokerId, brokerAttributes);
+
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(file.getAbsolutePath());
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ assertEquals("Unexpected root entry", brokerId, root.getId());
+ Map<String, Object> attributes = root.getAttributes();
+ assertNotNull("Attributes not found", attributes);
+ assertEquals("Unexpected number of attriburtes", 1, attributes.size());
+ assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME));
+ }
+
+ public void testOpenInMemoryEmpty()
+ {
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(JsonConfigurationEntryStore.IN_MEMORY);
+
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ }
+
+ public void testOpenWithInitialStoreLocation() throws Exception
+ {
+ UUID brokerId = UUID.randomUUID();
+ Map<String, Object> brokerAttributes = new HashMap<String, Object>();
+ brokerAttributes.put(Broker.NAME, getTestName());
+ File initialStoreFile = createStoreFile(brokerId, brokerAttributes);
+
+ File storeFile = TestFileUtils.createTempFile(this, ".json");
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(storeFile.getAbsolutePath(), initialStoreFile.getAbsolutePath());
+
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ assertEquals("Unexpected root entry", brokerId, root.getId());
+ Map<String, Object> attributes = root.getAttributes();
+ assertNotNull("Attributes not found", attributes);
+ assertEquals("Unexpected number of attriburtes", 1, attributes.size());
+ assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME));
+ }
+
+ public void testOpenInMemoryWithInitialStoreLocation() throws Exception
+ {
+ UUID brokerId = UUID.randomUUID();
+ Map<String, Object> brokerAttributes = new HashMap<String, Object>();
+ brokerAttributes.put(Broker.NAME, getTestName());
+ File initialStoreFile = createStoreFile(brokerId, brokerAttributes);
+
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStoreFile.getAbsolutePath());
+
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ assertEquals("Unexpected root entry", brokerId, root.getId());
+ Map<String, Object> attributes = root.getAttributes();
+ assertNotNull("Attributes not found", attributes);
+ assertEquals("Unexpected number of attriburtes", 1, attributes.size());
+ assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME));
+ }
+
+ public void testOpenWithInitialStore() throws Exception
+ {
+ UUID brokerId = UUID.randomUUID();
+ Map<String, Object> brokerAttributes = new HashMap<String, Object>();
+ brokerAttributes.put(Broker.NAME, getTestName());
+ File initialStoreFile = createStoreFile(brokerId, brokerAttributes);
+
+ JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore();
+ initialStore.open(initialStoreFile.getAbsolutePath());
+
+ File storeFile = TestFileUtils.createTempFile(this, ".json");
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(storeFile.getAbsolutePath(), initialStore);
+
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ assertEquals("Unexpected root entry", brokerId, root.getId());
+ Map<String, Object> attributes = root.getAttributes();
+ assertNotNull("Attributes not found", attributes);
+ assertEquals("Unexpected number of attriburtes", 1, attributes.size());
+ assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME));
+ }
+
+ public void testOpenInMemoryWithInitialStore() throws Exception
+ {
+ UUID brokerId = UUID.randomUUID();
+ Map<String, Object> brokerAttributes = new HashMap<String, Object>();
+ brokerAttributes.put(Broker.NAME, getTestName());
+ File initialStoreFile = createStoreFile(brokerId, brokerAttributes);
+
+ JsonConfigurationEntryStore initialStore = new JsonConfigurationEntryStore();
+ initialStore.open(initialStoreFile.getAbsolutePath());
+
+ JsonConfigurationEntryStore store = new JsonConfigurationEntryStore();
+ store.open(JsonConfigurationEntryStore.IN_MEMORY, initialStore);
+
+ ConfigurationEntry root = store.getRootEntry();
+ assertNotNull("Root entry is not found", root);
+ assertEquals("Unexpected root entry", brokerId, root.getId());
+ Map<String, Object> attributes = root.getAttributes();
+ assertNotNull("Attributes not found", attributes);
+ assertEquals("Unexpected number of attriburtes", 1, attributes.size());
+ assertEquals("Unexpected name attribute", getTestName(), attributes.get(Broker.NAME));
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
new file mode 100644
index 0000000000..a67daac610
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
@@ -0,0 +1,341 @@
+package org.apache.qpid.server.configuration.store;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.any;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator;
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+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.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class ManagementModeStoreHandlerTest extends QpidTestCase
+{
+ private ManagementModeStoreHandler _handler;
+ private BrokerOptions _options;
+ private ConfigurationEntryStore _store;
+ private ConfigurationEntry _root;
+ private ConfigurationEntry _portEntry;
+ private UUID _rootId, _portEntryId;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _rootId = UUID.randomUUID();
+ _portEntryId = UUID.randomUUID();
+ _store = mock(ConfigurationEntryStore.class);
+ _root = mock(ConfigurationEntry.class);
+ _portEntry = mock(ConfigurationEntry.class);
+ when(_store.getRootEntry()).thenReturn(_root);
+ when(_root.getId()).thenReturn(_rootId);
+ when(_portEntry.getId()).thenReturn(_portEntryId);
+ when(_store.getEntry(_portEntryId)).thenReturn(_portEntry);
+ when(_store.getEntry(_rootId)).thenReturn(_root);
+ when(_root.getChildrenIds()).thenReturn(Collections.singleton(_portEntryId));
+ when(_portEntry.getType()).thenReturn(Port.class.getSimpleName());
+ _options = new BrokerOptions();
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ }
+
+ public void testOpenString()
+ {
+ try
+ {
+ _handler.open(TMP_FOLDER + File.separator + getTestName());
+ fail("Exception should be thrown on attempt to call open method on a handler");
+ }
+ catch (IllegalStateException e)
+ {
+ // pass
+ }
+ }
+
+ public void testOpenStringString()
+ {
+ try
+ {
+ _handler.open(TMP_FOLDER + File.separator + getTestName(),
+ BrokerConfigurationStoreCreator.DEFAULT_INITIAL_STORE_LOCATION);
+ fail("Exception should be thrown on attempt to call open method on a handler");
+ }
+ catch (IllegalStateException e)
+ {
+ // pass
+ }
+ }
+
+ public void testOpenStringConfigurationEntryStore()
+ {
+ try
+ {
+ _handler.open(TMP_FOLDER + File.separator + getTestName(), _store);
+ fail("Exception should be thrown on attempt to call open method on a handler");
+ }
+ catch (IllegalStateException e)
+ {
+ // pass
+ }
+ }
+
+ public void testGetRootEntryWithEmptyOptions()
+ {
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ assertEquals("Unexpected children", Collections.singleton(_portEntryId), root.getChildrenIds());
+ }
+
+ public void testGetRootEntryWithHttpPortOverriden()
+ {
+ _options.setManagementModeHttpPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ Collection<UUID> childrenIds = root.getChildrenIds();
+ assertEquals("Unexpected children size", 2, childrenIds.size());
+ assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
+ }
+
+ public void testGetRootEntryWithRmiPortOverriden()
+ {
+ _options.setManagementModeRmiPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ Collection<UUID> childrenIds = root.getChildrenIds();
+ assertEquals("Unexpected children size", 3, childrenIds.size());
+ assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
+ }
+
+ public void testGetRootEntryWithConnectorPortOverriden()
+ {
+ _options.setManagementModeConnectorPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ Collection<UUID> childrenIds = root.getChildrenIds();
+ assertEquals("Unexpected children size", 2, childrenIds.size());
+ assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
+ }
+
+ public void testGetRootEntryWithManagementPortsOverriden()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _options.setManagementModeRmiPort(2000);
+ _options.setManagementModeConnectorPort(3000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ Collection<UUID> childrenIds = root.getChildrenIds();
+ assertEquals("Unexpected children size", 4, childrenIds.size());
+ assertTrue("Store port entry id is not found", childrenIds.contains(_portEntryId));
+ }
+
+ public void testGetEntryByRootId()
+ {
+ ConfigurationEntry root = _handler.getEntry(_rootId);
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ assertEquals("Unexpected children", Collections.singleton(_portEntryId), root.getChildrenIds());
+ }
+
+ public void testGetEntryByPortId()
+ {
+ ConfigurationEntry portEntry = _handler.getEntry(_portEntryId);
+ assertEquals("Unexpected entry id", _portEntryId, portEntry.getId());
+ assertTrue("Unexpected children", portEntry.getChildrenIds().isEmpty());
+ assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
+ }
+
+ public void testGetEntryByCLIConnectorPortId()
+ {
+ _options.setManagementModeConnectorPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ UUID optionsPort = getOptionsPortId();
+ ConfigurationEntry portEntry = _handler.getEntry(optionsPort);
+ assertCLIPortEntry(portEntry, optionsPort, Protocol.JMX_RMI);
+ }
+
+ public void testGetEntryByCLIHttpPortId()
+ {
+ _options.setManagementModeHttpPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ UUID optionsPort = getOptionsPortId();
+ ConfigurationEntry portEntry = _handler.getEntry(optionsPort);
+ assertCLIPortEntry(portEntry, optionsPort, Protocol.HTTP);
+ }
+
+ public void testHttpPortEntryIsQuiesced()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTP));
+ when(_portEntry.getAttributes()).thenReturn(attributes);
+ _options.setManagementModeHttpPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ ConfigurationEntry portEntry = _handler.getEntry(_portEntryId);
+ assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
+ }
+
+ public void testRmiPortEntryIsQuiesced()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.RMI));
+ when(_portEntry.getAttributes()).thenReturn(attributes);
+ _options.setManagementModeRmiPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ ConfigurationEntry portEntry = _handler.getEntry(_portEntryId);
+ assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
+ }
+
+ public void testConnectorPortEntryIsQuiesced()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.JMX_RMI));
+ when(_portEntry.getAttributes()).thenReturn(attributes);
+ _options.setManagementModeRmiPort(9090);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ ConfigurationEntry portEntry = _handler.getEntry(_portEntryId);
+ assertEquals("Unexpected state", State.QUIESCED, portEntry.getAttributes().get(Port.STATE));
+ }
+
+ public void testVirtualHostEntryIsQuiesced()
+ {
+ UUID virtualHostId = UUID.randomUUID();
+ ConfigurationEntry virtualHost = mock(ConfigurationEntry.class);
+ when(virtualHost.getId()).thenReturn(virtualHostId);
+ when(virtualHost.getType()).thenReturn(VirtualHost.class.getSimpleName());
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.CONFIG_PATH, "/path/to/host.xml");
+ when(virtualHost.getAttributes()).thenReturn(attributes);
+ when(_store.getEntry(virtualHostId)).thenReturn(virtualHost);
+ when(_root.getChildrenIds()).thenReturn(new HashSet<UUID>(Arrays.asList(_portEntryId, virtualHostId)));
+
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ ConfigurationEntry hostEntry = _handler.getEntry(virtualHostId);
+ Map<String, Object> hostAttributes = hostEntry.getAttributes();
+ assertEquals("Unexpected state", State.QUIESCED, hostAttributes.get(VirtualHost.STATE));
+ hostAttributes.remove(VirtualHost.STATE);
+ assertEquals("Unexpected attributes", attributes, hostAttributes);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void assertCLIPortEntry(ConfigurationEntry portEntry, UUID optionsPort, Protocol protocol)
+ {
+ assertEquals("Unexpected entry id", optionsPort, portEntry.getId());
+ assertTrue("Unexpected children", portEntry.getChildrenIds().isEmpty());
+ Map<String, Object> attributes = portEntry.getAttributes();
+ assertEquals("Unexpected name", "MANAGEMENT-MODE-PORT-" + protocol.name(), attributes.get(Port.NAME));
+ assertEquals("Unexpected protocol", Collections.singleton(protocol), new HashSet<Protocol>(
+ (Collection<Protocol>) attributes.get(Port.PROTOCOLS)));
+ }
+
+ public void testSavePort()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _options.setManagementModeRmiPort(2000);
+ _options.setManagementModeConnectorPort(3000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, "TEST");
+ ConfigurationEntry configurationEntry = new ConfigurationEntry(_portEntryId, Port.class.getSimpleName(), attributes,
+ Collections.<UUID> emptySet(), null);
+ _handler.save(configurationEntry);
+ verify(_store).save(any(ConfigurationEntry.class));
+ }
+
+ public void testSaveRoot()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _options.setManagementModeRmiPort(2000);
+ _options.setManagementModeConnectorPort(3000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ ConfigurationEntry root = _handler.getRootEntry();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Broker.NAME, "TEST");
+ ConfigurationEntry configurationEntry = new ConfigurationEntry(_rootId, Broker.class.getSimpleName(), attributes,
+ root.getChildrenIds(), null);
+ _handler.save(configurationEntry);
+ verify(_store).save(any(ConfigurationEntry.class));
+ }
+
+ public void testSaveCLIHttpPort()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ UUID portId = getOptionsPortId();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.NAME, "TEST");
+ ConfigurationEntry configurationEntry = new ConfigurationEntry(portId, Port.class.getSimpleName(), attributes,
+ Collections.<UUID> emptySet(), null);
+ try
+ {
+ _handler.save(configurationEntry);
+ fail("Exception should be thrown on trying to save CLI port");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+ public void testRemove()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+
+ _handler.remove(_portEntryId);
+ verify(_store).remove(_portEntryId);
+ }
+
+ public void testRemoveCLIPort()
+ {
+ _options.setManagementModeHttpPort(1000);
+ _handler = new ManagementModeStoreHandler(_store, _options);
+ UUID portId = getOptionsPortId();
+ try
+ {
+ _handler.remove(portId);
+ fail("Exception should be thrown on trying to remove CLI port");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+
+ private UUID getOptionsPortId()
+ {
+ ConfigurationEntry root = _handler.getRootEntry();
+ assertEquals("Unexpected root id", _rootId, root.getId());
+ Collection<UUID> childrenIds = root.getChildrenIds();
+
+ childrenIds.remove(_portEntryId);
+ UUID optionsPort = childrenIds.iterator().next();
+ return optionsPort;
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java
new file mode 100644
index 0000000000..a77a0e9fcc
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java
@@ -0,0 +1,83 @@
+package org.apache.qpid.server.configuration.store;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.when;
+
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class StoreConfigurationChangeListenerTest extends QpidTestCase
+{
+ private ConfigurationEntryStore _store;
+ private StoreConfigurationChangeListener _listener;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _store = mock(ConfigurationEntryStore.class);
+ _listener = new StoreConfigurationChangeListener(_store);
+ }
+
+ public void testStateChanged()
+ {
+ notifyBrokerStarted();
+ UUID id = UUID.randomUUID();
+ ConfiguredObject object = mock(VirtualHost.class);
+ when(object.getId()).thenReturn(id);
+ _listener.stateChanged(object, State.ACTIVE, State.DELETED);
+ verify(_store).remove(id);
+ }
+
+ public void testChildAdded()
+ {
+ notifyBrokerStarted();
+ Broker broker = mock(Broker.class);
+ VirtualHost child = mock(VirtualHost.class);
+ _listener.childAdded(broker, child);
+ verify(_store).save(any(ConfigurationEntry.class), any(ConfigurationEntry.class));
+ }
+
+ public void testChildRemoved()
+ {
+ notifyBrokerStarted();
+ Broker broker = mock(Broker.class);
+ VirtualHost child = mock(VirtualHost.class);
+ _listener.childRemoved(broker, child);
+ verify(_store).save(any(ConfigurationEntry.class));
+ }
+
+ public void testAttributeSet()
+ {
+ notifyBrokerStarted();
+ Broker broker = mock(Broker.class);
+ _listener.attributeSet(broker, Broker.FLOW_CONTROL_SIZE_BYTES, null, 1);
+ verify(_store).save(any(ConfigurationEntry.class));
+ }
+
+ public void testChildAddedForVirtualHost()
+ {
+ notifyBrokerStarted();
+
+ VirtualHost object = mock(VirtualHost.class);
+ Queue queue = mock(Queue.class);
+ _listener.childAdded(object, queue);
+ verifyNoMoreInteractions(_store);
+ }
+
+ private void notifyBrokerStarted()
+ {
+ Broker broker = mock(Broker.class);
+ _listener.stateChanged(broker, State.INITIALISING, State.ACTIVE);
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java
new file mode 100644
index 0000000000..cd6302d55b
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/updater/TaskExecutorTest.java
@@ -0,0 +1,296 @@
+/*
+ *
+ * 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.updater;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.security.auth.Subject;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.logging.LogActor;
+import org.apache.qpid.server.logging.NullRootMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.TestLogActor;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.security.SecurityManager;
+
+public class TaskExecutorTest extends TestCase
+{
+ private TaskExecutor _executor;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _executor = new TaskExecutor();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ _executor.stopImmediately();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testGetState()
+ {
+ assertEquals("Unxpected initial state", State.INITIALISING, _executor.getState());
+ }
+
+ public void testStart()
+ {
+ _executor.start();
+ assertEquals("Unxpected started state", State.ACTIVE, _executor.getState());
+ }
+
+ public void testStopImmediately() throws Exception
+ {
+ _executor.start();
+ final CountDownLatch submitLatch = new CountDownLatch(2);
+ final CountDownLatch waitForCallLatch = new CountDownLatch(1);
+ final BlockingQueue<Exception> submitExceptions = new LinkedBlockingQueue<Exception>();
+
+ Runnable runnable = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ Future<?> f = _executor.submit(new NeverEndingCallable(waitForCallLatch));
+ submitLatch.countDown();
+ f.get();
+ }
+ catch (Exception e)
+ {
+ if (e instanceof ExecutionException)
+ {
+ e = (Exception) e.getCause();
+ }
+ submitExceptions.add(e);
+ }
+ }
+ };
+ new Thread(runnable).start();
+ new Thread(runnable).start();
+ assertTrue("Tasks have not been submitted", submitLatch.await(1000, TimeUnit.MILLISECONDS));
+ assertTrue("The first task has not been triggered", waitForCallLatch.await(1000, TimeUnit.MILLISECONDS));
+
+ _executor.stopImmediately();
+ assertEquals("Unxpected stopped state", State.STOPPED, _executor.getState());
+
+ Exception e = submitExceptions.poll(1000l, TimeUnit.MILLISECONDS);
+ assertNotNull("The task execution was not interrupted or cancelled", e);
+ Exception e2 = submitExceptions.poll(1000l, TimeUnit.MILLISECONDS);
+ assertNotNull("The task execution was not interrupted or cancelled", e2);
+
+ assertTrue("One of the exceptions should be CancellationException:", e2 instanceof CancellationException
+ || e instanceof CancellationException);
+ assertTrue("One of the exceptions should be InterruptedException:", e2 instanceof InterruptedException
+ || e instanceof InterruptedException);
+ }
+
+ public void testStop()
+ {
+ _executor.start();
+ _executor.stop();
+ assertEquals("Unxpected stopped state", State.STOPPED, _executor.getState());
+ }
+
+ public void testSubmitAndWait() throws Exception
+ {
+ _executor.start();
+ Object result = _executor.submitAndWait(new Callable<String>()
+ {
+ @Override
+ public String call() throws Exception
+ {
+ return "DONE";
+ }
+ });
+ assertEquals("Unexpected task execution result", "DONE", result);
+ }
+
+ public void testSubmitAndWaitInNotAuthorizedContext()
+ {
+ _executor.start();
+ Object subject = _executor.submitAndWait(new SubjectRetriever());
+ assertNull("Subject must be null", subject);
+ }
+
+ public void testSubmitAndWaitInAuthorizedContext()
+ {
+ _executor.start();
+ Subject subject = new Subject();
+ Object result = Subject.doAs(subject, new PrivilegedAction<Object>()
+ {
+ @Override
+ public Object run()
+ {
+ return _executor.submitAndWait(new SubjectRetriever());
+ }
+ });
+ assertEquals("Unexpected subject", subject, result);
+ }
+
+ public void testSubmitAndWaitInAuthorizedContextWithNullSubject()
+ {
+ _executor.start();
+ Object result = Subject.doAs(null, new PrivilegedAction<Object>()
+ {
+ @Override
+ public Object run()
+ {
+ return _executor.submitAndWait(new SubjectRetriever());
+ }
+ });
+ assertEquals("Unexpected subject", null, result);
+ }
+
+ public void testSubmitAndWaitReThrowsOriginalRuntimeException()
+ {
+ final RuntimeException exception = new RuntimeException();
+ _executor.start();
+ try
+ {
+ _executor.submitAndWait(new Callable<Void>()
+ {
+
+ @Override
+ public Void call() throws Exception
+ {
+ throw exception;
+ }
+ });
+ fail("Exception is expected");
+ }
+ catch (Exception e)
+ {
+ assertEquals("Unexpected exception", exception, e);
+ }
+ }
+
+ public void testSubmitAndWaitPassesOriginalCheckedException()
+ {
+ final Exception exception = new Exception();
+ _executor.start();
+ try
+ {
+ _executor.submitAndWait(new Callable<Void>()
+ {
+
+ @Override
+ public Void call() throws Exception
+ {
+ throw exception;
+ }
+ });
+ fail("Exception is expected");
+ }
+ catch (Exception e)
+ {
+ assertEquals("Unexpected exception", exception, e.getCause());
+ }
+ }
+
+ public void testSubmitAndWaitCurrentActorAndSecurityManagerSubjectAreRespected() throws Exception
+ {
+ _executor.start();
+ LogActor actor = new TestLogActor(new NullRootMessageLogger());
+ Subject subject = new Subject();
+ Subject currentSecurityManagerSubject = SecurityManager.getThreadSubject();
+ final AtomicReference<LogActor> taskLogActor = new AtomicReference<LogActor>();
+ final AtomicReference<Subject> taskSubject = new AtomicReference<Subject>();
+ try
+ {
+ CurrentActor.set(actor);
+ SecurityManager.setThreadSubject(subject);
+ _executor.submitAndWait(new Callable<Void>()
+ {
+ @Override
+ public Void call() throws Exception
+ {
+ taskLogActor.set(CurrentActor.get());
+ taskSubject.set(SecurityManager.getThreadSubject());
+ return null;
+ }
+ });
+ }
+ finally
+ {
+ SecurityManager.setThreadSubject(currentSecurityManagerSubject);
+ CurrentActor.remove();
+ }
+ assertEquals("Unexpected task log actor", actor, taskLogActor.get());
+ assertEquals("Unexpected security manager subject", subject, taskSubject.get());
+ }
+
+ private class SubjectRetriever implements Callable<Subject>
+ {
+ @Override
+ public Subject call() throws Exception
+ {
+ return Subject.getSubject(AccessController.getContext());
+ }
+ }
+
+ private class NeverEndingCallable implements Callable<Void>
+ {
+ private CountDownLatch _waitLatch;
+
+ public NeverEndingCallable(CountDownLatch waitLatch)
+ {
+ super();
+ _waitLatch = waitLatch;
+ }
+
+ @Override
+ public Void call() throws Exception
+ {
+ if (_waitLatch != null)
+ {
+ _waitLatch.countDown();
+ }
+
+ // wait forever
+ synchronized (this)
+ {
+ this.wait();
+ }
+ return null;
+ }
+ }
+}
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 4befd26ece..0bb698a46c 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
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.log4j.Logger;
@@ -54,25 +53,56 @@ import org.apache.qpid.server.queue.IncomingMessage;
import org.apache.qpid.server.queue.MockStoredMessage;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.queue.SimpleAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
+public class AbstractHeadersExchangeTestBase extends QpidTestCase
{
private static final Logger _log = Logger.getLogger(AbstractHeadersExchangeTestBase.class);
private final HeadersExchange exchange = new HeadersExchange();
- protected final Set<TestQueue> queues = new HashSet<TestQueue>();
-
+ private final Set<TestQueue> queues = new HashSet<TestQueue>();
+ private VirtualHost _virtualHost;
private int count;
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _virtualHost = BrokerTestHelper.createVirtualHost(getClass().getName());
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_virtualHost != null)
+ {
+ _virtualHost.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
public void testDoNothing()
{
// this is here only to make junit under Eclipse happy
}
+ public VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
protected TestQueue bindDefault(String... bindings) throws AMQException
{
String queueName = "Queue" + (++count);
@@ -83,7 +113,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
protected void unbind(TestQueue queue, String... bindings) throws AMQException
{
String queueName = queue.getName();
- exchange.onUnbind(new Binding(null, null, queueName, queue, exchange, getHeadersMap(bindings)));
+ exchange.onUnbind(new Binding(null, queueName, queue, exchange, getHeadersMap(bindings)));
}
protected int getCount()
@@ -93,9 +123,9 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
private TestQueue bind(String key, String queueName, Map<String,Object> args) throws AMQException
{
- TestQueue queue = new TestQueue(new AMQShortString(queueName));
+ TestQueue queue = new TestQueue(new AMQShortString(queueName), _virtualHost);
queues.add(queue);
- exchange.onBind(new Binding(null, null, key, queue, exchange, args));
+ exchange.onBind(new Binding(null, key, queue, exchange, args));
return queue;
}
@@ -274,10 +304,10 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
return getNameShortString().toString();
}
- public TestQueue(AMQShortString name) throws AMQException
+ public TestQueue(AMQShortString name, VirtualHost host) throws AMQException
{
- 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);
+ super(UUIDGenerator.generateRandomUUID(), name, false, new AMQShortString("test"), true, false, host, Collections.EMPTY_MAP);
+ host.getQueueRegistry().registerQueue(this);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java
new file mode 100644
index 0000000000..341ab1b372
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/DefaultExchangeFactoryTest.java
@@ -0,0 +1,226 @@
+/*
+ *
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.plugin.ExchangeType;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+@SuppressWarnings("rawtypes")
+public class DefaultExchangeFactoryTest extends QpidTestCase
+{
+ private DirectExchangeType _directExchangeType;
+ private TopicExchangeType _topicExchangeType;
+ private FanoutExchangeType _fanoutExchangeType;
+ private HeadersExchangeType _headersExchangeType;
+
+ private List<ExchangeType> _stubbedExchangeTypes;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ _directExchangeType = new DirectExchangeType();
+ _topicExchangeType = new TopicExchangeType();
+ _fanoutExchangeType = new FanoutExchangeType();
+ _headersExchangeType = new HeadersExchangeType();
+ _stubbedExchangeTypes = new ArrayList<ExchangeType>();
+ }
+
+ public void testCreateDefaultExchangeFactory()
+ {
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_topicExchangeType);
+ _stubbedExchangeTypes.add(_fanoutExchangeType);
+ _stubbedExchangeTypes.add(_headersExchangeType);
+
+ DefaultExchangeFactory factory = new TestExchangeFactory();
+
+ Collection<ExchangeType<? extends Exchange>> registeredTypes = factory.getRegisteredTypes();
+ assertEquals("Unexpected number of exchange types", _stubbedExchangeTypes.size(), registeredTypes.size());
+ assertTrue("Direct exchange type is not found", registeredTypes.contains(_directExchangeType));
+ assertTrue("Fanout exchange type is not found", registeredTypes.contains(_fanoutExchangeType));
+ assertTrue("Topic exchange type is not found", registeredTypes.contains(_topicExchangeType));
+ assertTrue("Headers exchange type is not found", registeredTypes.contains(_headersExchangeType));
+ }
+
+ public void testCreateDefaultExchangeFactoryWithoutAllBaseExchangeTypes()
+ {
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory without all base classes");
+ }
+ catch (IllegalStateException e)
+ {
+ // pass
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithoutDireactExchangeType()
+ {
+ _stubbedExchangeTypes.add(_topicExchangeType);
+ _stubbedExchangeTypes.add(_fanoutExchangeType);
+ _stubbedExchangeTypes.add(_headersExchangeType);
+
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory without all base classes");
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _directExchangeType.getName(), e.getMessage());
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithoutTopicExchangeType()
+ {
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_fanoutExchangeType);
+ _stubbedExchangeTypes.add(_headersExchangeType);
+
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory without all base classes");
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _topicExchangeType.getName(), e.getMessage());
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithoutFanoutExchangeType()
+ {
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_topicExchangeType);
+ _stubbedExchangeTypes.add(_headersExchangeType);
+
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory without all base classes");
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _fanoutExchangeType.getName(), e.getMessage());
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithoutHeadersExchangeType()
+ {
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_topicExchangeType);
+ _stubbedExchangeTypes.add(_fanoutExchangeType);
+
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory without all base classes");
+ }
+ catch (IllegalStateException e)
+ {
+ assertEquals("Unexpected exception message", "Did not find expected exchange type: " + _headersExchangeType.getName(), e.getMessage());
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithDuplicateExchangeTypeName()
+ {
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_directExchangeType);
+
+ try
+ {
+ new TestExchangeFactory();
+ fail("Cannot create factory with duplicate exchange type names");
+ }
+ catch (IllegalStateException e)
+ {
+ assertTrue( "Unexpected exception message", e.getMessage().contains("ExchangeType with type name '"
+ + _directExchangeType.getName() + "' is already registered using class '"
+ + DirectExchangeType.class.getName()));
+ }
+ }
+
+ public void testCreateDefaultExchangeFactoryWithCustomExchangeType()
+ {
+ ExchangeType<?> customeExchangeType = new ExchangeType<Exchange>()
+ {
+ @Override
+ public AMQShortString getName()
+ {
+ return new AMQShortString("my-custom-exchange");
+ }
+
+ @Override
+ public Exchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket,
+ boolean autoDelete) throws AMQException
+ {
+ return null;
+ }
+
+ @Override
+ public AMQShortString getDefaultExchangeName()
+ {
+ return null;
+ }
+ };
+
+ _stubbedExchangeTypes.add(customeExchangeType);
+ _stubbedExchangeTypes.add(_directExchangeType);
+ _stubbedExchangeTypes.add(_topicExchangeType);
+ _stubbedExchangeTypes.add(_fanoutExchangeType);
+ _stubbedExchangeTypes.add(_headersExchangeType);
+
+ DefaultExchangeFactory factory = new TestExchangeFactory();
+
+ Collection<ExchangeType<? extends Exchange>> registeredTypes = factory.getRegisteredTypes();
+ assertEquals("Unexpected number of exchange types", _stubbedExchangeTypes.size(), registeredTypes.size());
+ assertTrue("Direct exchange type is not found", registeredTypes.contains(_directExchangeType));
+ assertTrue("Fanout exchange type is not found", registeredTypes.contains(_fanoutExchangeType));
+ assertTrue("Topic exchange type is not found", registeredTypes.contains(_topicExchangeType));
+ assertTrue("Headers exchange type is not found", registeredTypes.contains(_headersExchangeType));
+ assertTrue("Custom exchange type is not found", registeredTypes.contains(customeExchangeType));
+ }
+
+ private final class TestExchangeFactory extends DefaultExchangeFactory
+ {
+ private TestExchangeFactory()
+ {
+ super(null);
+ }
+
+ @Override
+ protected Iterable<ExchangeType> loadExchangeTypes()
+ {
+ return _stubbedExchangeTypes;
+ }
+ }
+
+}
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 3988edcb3c..833df34fd8 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
@@ -160,7 +160,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -171,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -181,7 +181,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Altered value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -192,7 +192,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -204,7 +204,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -217,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -231,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -245,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
@@ -256,7 +256,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -268,7 +268,7 @@ public class HeadersBindingTest extends TestCase
matchHeaders.setString("A", "Value of A");
- Binding b = new Binding(null, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -281,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -295,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -309,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertTrue(new HeadersBinding(b).matches(matchHeaders));
}
@@ -323,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, null, getQueueName(), _queue, null, bindHeaders);
+ Binding b = new Binding(null, getQueueName(), _queue, null, bindHeaders);
assertFalse(new HeadersBinding(b).matches(matchHeaders));
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
index 326d36df05..bd6a02d69b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/HeadersExchangeTest.java
@@ -23,8 +23,7 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.util.BrokerTestHelper;
public class HeadersExchangeTest extends AbstractHeadersExchangeTestBase
{
@@ -34,10 +33,15 @@ public class HeadersExchangeTest extends AbstractHeadersExchangeTestBase
public void setUp() throws Exception
{
super.setUp();
- // Just use the first vhost.
- VirtualHost
- virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next();
- _protocolSession = new InternalTestProtocolSession(virtualHost);
+ BrokerTestHelper.setUp();
+ _protocolSession = new InternalTestProtocolSession(getVirtualHost(), BrokerTestHelper.createBrokerMock());
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
}
public void testSimple() throws AMQException
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 92274afece..f1bf632235 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
@@ -31,42 +31,55 @@ 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;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.IncomingMessage;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class TopicExchangeTest extends InternalBrokerBaseCase
+public class TopicExchangeTest extends QpidTestCase
{
private TopicExchange _exchange;
-
private VirtualHost _vhost;
private MessageStore _store;
- private InternalTestProtocolSession _protocolSession;
-
@Override
public void setUp() throws Exception
{
super.setUp();
+ BrokerTestHelper.setUp();
_exchange = new TopicExchange();
- _vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next();
+ _vhost = BrokerTestHelper.createVirtualHost(getName());
_store = new MemoryMessageStore();
- _protocolSession = new InternalTestProtocolSession(_vhost);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_vhost != null)
+ {
+ _vhost.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
public void testNoRoute() throws AMQException
{
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));
+ _exchange.registerQueue(new Binding(null, "a.*.#.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -78,7 +91,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testDirectMatch() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "ab", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -105,7 +118,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testStarMatch() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a*", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.*",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.*",queue, _exchange, null));
IncomingMessage message = createMessage("a.b");
@@ -144,7 +157,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashMatch() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.#",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.#",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -207,7 +220,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMidHash() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.*.#.b",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.*.#.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.d.b");
@@ -237,7 +250,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMatchafterHash() throws AMQException
{
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));
+ _exchange.registerQueue(new Binding(null, "a.*.#.b.c",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b");
@@ -283,7 +296,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashAfterHash() throws AMQException
{
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));
+ _exchange.registerQueue(new Binding(null, "a.*.#.b.c.#.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b.c");
@@ -310,7 +323,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testHashHash() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a#", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.#.*.#.d",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.#.*.#.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.c.b.b.c");
@@ -336,7 +349,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testSubMatchFails() throws AMQException
{
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));
+ _exchange.registerQueue(new Binding(null, "a.b.c.d",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -366,7 +379,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMoreRouting() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a.b.c");
@@ -381,7 +394,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
public void testMoreQueue() throws AMQException
{
AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "a", false, null, false, false, _vhost, null);
- _exchange.registerQueue(new Binding(null, null, "a.b",queue, _exchange, null));
+ _exchange.registerQueue(new Binding(null, "a.b",queue, _exchange, null));
IncomingMessage message = createMessage("a");
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java b/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
index fabbe8640e..be31f3d039 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.logging;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import java.util.LinkedList;
import java.util.List;
@@ -34,9 +33,9 @@ public class UnitTestMessageLogger extends AbstractRootMessageLogger
}
- public UnitTestMessageLogger(ServerConfiguration config)
+ public UnitTestMessageLogger(boolean statusUpdatesEnabled)
{
- super(config);
+ super(statusUpdatesEnabled);
}
public void rawMessage(String message, String logHierarchy)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java
index f739d3fcb9..e2472dbf01 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java
@@ -20,9 +20,8 @@
*/
package org.apache.qpid.server.logging.actors;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.util.BrokerTestHelper;
import java.util.List;
@@ -38,24 +37,17 @@ import java.util.List;
public class AMQPChannelActorTest extends BaseConnectionActorTestCase
{
- @Override
- public void configure()
+ public void setUp()
{
- // Prevent defaulting Logging to ON
+ // do nothing
}
-
- @Override
- public void createBroker() throws Exception
+ private void setUpNow() throws Exception
{
- //prevent auto-broker startup
- }
+ super.setUp();
+ AMQChannel channel = BrokerTestHelper.createChannel(1, getSession());
- private void startBrokerNow() throws Exception
- {
- super.createBroker();
-
- _amqpActor = new AMQPChannelActor(getChannel(), _rootLogger);
+ setAmqpActor(new AMQPChannelActor(channel, getRootLogger()));
}
@@ -68,13 +60,11 @@ public class AMQPChannelActorTest extends BaseConnectionActorTestCase
*/
public void testChannel() throws Exception
{
- getConfigXml().setProperty("status-updates", "ON");
-
- startBrokerNow();
+ setUpNow();
- final String message = sendTestLogMessage(_amqpActor);
+ final String message = sendTestLogMessage(getAmqpActor());
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 1, logs.size());
@@ -95,128 +85,22 @@ public class AMQPChannelActorTest extends BaseConnectionActorTestCase
// Verify that the logged message contains the 'ch:1' marker
assertTrue("Message was not logged as part of channel 1" + logs.get(0),
logs.get(0).toString().contains("/ch:1"));
-
- }
-
- /**
- * Test that if logging is configured to be off in the configuration that
- * no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testChannelLoggingOFF() throws Exception, AMQException
- {
- getConfigXml().setProperty("status-updates", "OFF");
-
- // Start the broker now.
- startBrokerNow();
-
- sendTestLogMessage(_amqpActor);
-
- List<Object> logs = _rawLogger.getLogMessages();
-
- assertEquals("Message log size not as expected.", 0, logs.size());
-
- }
-
- /**
- * Test that if logging is configured to be off in the configuration that
- * no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testChannelLoggingOfF() throws Exception, AMQException
- {
- getConfigXml().setProperty("status-updates", "OfF");
-
- startBrokerNow();
-
- sendTestLogMessage(_amqpActor);
-
- List<Object> logs = _rawLogger.getLogMessages();
-
- assertEquals("Message log size not as expected.", 0, logs.size());
-
- }
-
- /**
- * Test that if logging is configured to be off in the configuration that
- * no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testChannelLoggingOff() throws Exception, AMQException
- {
- getConfigXml().setProperty("status-updates", "Off");
-
- startBrokerNow();
-
- sendTestLogMessage(_amqpActor);
-
- List<Object> logs = _rawLogger.getLogMessages();
-
- assertEquals("Message log size not as expected.", 0, logs.size());
-
}
/**
- * Test that if logging is configured to be off in the configuration that
+ * Test that if logging is configured to be off via system property that
* no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
*/
- public void testChannelLoggingofF() throws Exception, AMQException
+ public void testChannelLoggingOFF() throws Exception
{
- getConfigXml().setProperty("status-updates", "ofF");
+ setStatusUpdatesEnabled(false);
- startBrokerNow();
+ setUpNow();
- sendTestLogMessage(_amqpActor);
+ sendTestLogMessage(getAmqpActor());
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 0, logs.size());
-
}
-
- /**
- * Test that if logging is configured to be off in the configuration that
- * no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testChannelLoggingoff() throws Exception, AMQException
- {
- getConfigXml().setProperty("status-updates", "off");
-
- startBrokerNow();
-
- sendTestLogMessage(_amqpActor);
-
- List<Object> logs = _rawLogger.getLogMessages();
-
- assertEquals("Message log size not as expected.", 0, logs.size());
-
- }
-
- /**
- * Test that if logging is configured to be off in the configuration that
- * no logging is presented
- * @throws ConfigurationException
- * @throws AMQException
- */
- public void testChannelLoggingoFf() throws Exception, AMQException
- {
- getConfigXml().setProperty("status-updates", "oFf");
-
- startBrokerNow();
-
- sendTestLogMessage(_amqpActor);
-
- List<Object> logs = _rawLogger.getLogMessages();
-
- assertEquals("Message log size not as expected.", 0, logs.size());
-
- }
-
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java
index 4eda9e9da1..d1cf256563 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java
@@ -38,16 +38,9 @@ import java.util.List;
public class AMQPConnectionActorTest extends BaseConnectionActorTestCase
{
@Override
- public void configure()
+ public void setUp()
{
- // Prevent defaulting Logging to ON
- }
-
-
- @Override
- public void createBroker()
- {
- //Prevent auto-broker startup
+ //Prevent logger creation
}
/**
@@ -60,13 +53,11 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase
*/
public void testConnection() throws Exception
{
- getConfigXml().setProperty("status-updates", "ON");
-
- super.createBroker();
+ super.setUp();
final String message = sendLogMessage();
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 1, logs.size());
@@ -90,14 +81,13 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase
public void testConnectionLoggingOff() throws Exception, AMQException
{
- getConfigXml().setProperty("status-updates", "OFF");
+ setStatusUpdatesEnabled(false);
- // Start the broker now.
- super.createBroker();
+ super.setUp();
sendLogMessage();
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 0, logs.size());
@@ -107,7 +97,7 @@ public class AMQPConnectionActorTest extends BaseConnectionActorTestCase
{
final String message = "test logging";
- _amqpActor.message(new LogSubject()
+ getAmqpActor().message(new LogSubject()
{
public String toLogString()
{
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java
new file mode 100644
index 0000000000..bf38bb64bf
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AbstractManagementActorTest.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.actors;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.logging.NullRootMessageLogger;
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AbstractManagementActorTest extends QpidTestCase
+{
+ private AbstractManagementActor _logActor;
+
+ @Override
+ public void setUp()
+ {
+ _logActor = new AbstractManagementActor(new NullRootMessageLogger(), AbstractManagementActor.UNKNOWN_PRINCIPAL)
+ {
+ @Override
+ public String getLogMessage()
+ {
+ return null;
+ }
+ };
+ }
+
+ public void testGetPrincipalName()
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("guest");
+
+ final String principalName = Subject.doAs(subject,
+ new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return _logActor.getPrincipalName();
+ }
+ });
+
+ assertEquals("guest", principalName);
+ }
+
+ public void testGetPrincipalNameUsingSubjectWithoutAuthenticatedPrincipal()
+ {
+ Subject subject = new Subject(true, Collections.<Principal>emptySet(), Collections.emptySet(), Collections.emptySet());
+
+ final String principalName = Subject.doAs(subject,
+ new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return _logActor.getPrincipalName();
+ }
+ });
+
+ assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, principalName);
+ }
+
+ public void testGetPrincipalWithoutSubject()
+ {
+ assertEquals(AbstractManagementActor.UNKNOWN_PRINCIPAL, _logActor.getPrincipalName());
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java
index ec2cdd5585..30c3a51604 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java
@@ -20,39 +20,39 @@
*/
package org.apache.qpid.server.logging.actors;
-import org.apache.qpid.server.configuration.ServerConfiguration;
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.UnitTestMessageLogger;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class BaseActorTestCase extends InternalBrokerBaseCase
+public class BaseActorTestCase extends QpidTestCase
{
- protected LogActor _amqpActor;
- protected UnitTestMessageLogger _rawLogger;
- protected RootMessageLogger _rootLogger;
+ private boolean _statusUpdatesEnabled = true;
+ private LogActor _amqpActor;
+ private UnitTestMessageLogger _rawLogger;
+ private RootMessageLogger _rootLogger;
@Override
- public void configure()
+ public void setUp() throws Exception
{
- getConfiguration().getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on");
- }
-
- @Override
- public void createBroker() throws Exception
- {
- super.createBroker();
-
- _rawLogger = new UnitTestMessageLogger(getConfiguration());
+ super.setUp();
+ CurrentActor.removeAll();
+ CurrentActor.setDefault(null);
+ _rawLogger = new UnitTestMessageLogger(_statusUpdatesEnabled);
_rootLogger = _rawLogger;
}
+ @Override
public void tearDown() throws Exception
{
- _rawLogger.clearLogMessages();
-
+ if(_rawLogger != null)
+ {
+ _rawLogger.clearLogMessages();
+ }
+ CurrentActor.removeAll();
+ CurrentActor.setDefault(null);
super.tearDown();
}
@@ -87,4 +87,34 @@ public class BaseActorTestCase extends InternalBrokerBaseCase
});
}
+ public boolean isStatusUpdatesEnabled()
+ {
+ return _statusUpdatesEnabled;
+ }
+
+ public void setStatusUpdatesEnabled(boolean statusUpdatesEnabled)
+ {
+ _statusUpdatesEnabled = statusUpdatesEnabled;
+ }
+
+ public LogActor getAmqpActor()
+ {
+ return _amqpActor;
+ }
+
+ public void setAmqpActor(LogActor amqpActor)
+ {
+ _amqpActor = amqpActor;
+ }
+
+ public UnitTestMessageLogger getRawLogger()
+ {
+ return _rawLogger;
+ }
+
+ public RootMessageLogger getRootLogger()
+ {
+ return _rootLogger;
+ }
+
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java
index 956d296dce..09dd48e4d3 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java
@@ -20,14 +20,43 @@
*/
package org.apache.qpid.server.logging.actors;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.util.BrokerTestHelper;
+
public class BaseConnectionActorTestCase extends BaseActorTestCase
{
+ private AMQProtocolSession _session;
@Override
- public void createBroker() throws Exception
+ public void setUp() throws Exception
{
- super.createBroker();
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _session = BrokerTestHelper.createSession();
+
+ setAmqpActor(new AMQPConnectionActor(_session, getRootLogger()));
+ }
- _amqpActor = new AMQPConnectionActor(getSession(), _rootLogger);
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_session != null)
+ {
+ _session.getVirtualHost().close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
+
+ public AMQProtocolSession getSession()
+ {
+ return _session;
+ }
+
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
index f73765f5aa..8ea5510ce6 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/CurrentActorTest.java
@@ -70,12 +70,7 @@ public class CurrentActorTest extends BaseConnectionActorTestCase
*/
public void testLIFO() throws AMQException, ConfigurationException
{
- // This test only needs the local objects created, _session etc.
- // So stopping the broker and making them useless will not affect the
- // test, but the extra actors the test broker adds will so by stopping
- // we remove the session actor and so all is good.
- stopBroker();
-
+ assertTrue("Unexpected actor: " + CurrentActor.get(), CurrentActor.get() instanceof TestLogActor);
AMQPConnectionActor connectionActor = new AMQPConnectionActor(getSession(),
new NullRootMessageLogger());
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java
new file mode 100644
index 0000000000..905de4b639
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/HttpManagementActorTest.java
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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.actors;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+
+import java.security.PrivilegedAction;
+import java.util.List;
+
+public class HttpManagementActorTest extends BaseActorTestCase
+{
+ private static final String IP = "127.0.0.1";
+ private static final int PORT = 1;
+ private static final String SUFFIX = "(" + IP + ":" + PORT + ")] ";
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ setAmqpActor(new HttpManagementActor(getRootLogger(), IP, PORT));
+ }
+
+ public void testSubjectPrincipalNameAppearance()
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("guest");
+
+ final String message = Subject.doAs(subject, new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return sendTestLogMessage(getAmqpActor());
+ }
+ });
+
+ assertNotNull("Test log message is not created!", message);
+
+ List<Object> logs = getRawLogger().getLogMessages();
+ assertEquals("Message log size not as expected.", 1, logs.size());
+
+ String logMessage = logs.get(0).toString();
+ assertTrue("Message was not found in log message", logMessage.contains(message));
+ assertTrue("Message does not contain expected value: " + logMessage, logMessage.contains("[mng:guest" + SUFFIX));
+ }
+
+ /** It's necessary to test successive calls because HttpManagementActor caches
+ * its log message based on principal name */
+ public void testGetLogMessageCaching()
+ {
+ assertLogMessageWithoutPrincipal();
+ assertLogMessageWithPrincipal("my_principal");
+ assertLogMessageWithPrincipal("my_principal2");
+ assertLogMessageWithoutPrincipal();
+ }
+
+ private void assertLogMessageWithoutPrincipal()
+ {
+ String message = getAmqpActor().getLogMessage();
+ assertEquals("Unexpected log message", "[mng:" + AbstractManagementActor.UNKNOWN_PRINCIPAL + SUFFIX, message);
+ }
+
+ private void assertLogMessageWithPrincipal(String principalName)
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject(principalName);
+ final String message = Subject.doAs(subject, new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ return getAmqpActor().getLogMessage();
+ }
+ });
+
+ assertEquals("Unexpected log message", "[mng:" + principalName + SUFFIX, message);
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java
index cb866245f0..a0bfa592db 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java
@@ -20,10 +20,11 @@
*/
package org.apache.qpid.server.logging.actors;
-import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.TestPrincipalUtils;
+
import java.security.PrivilegedAction;
-import java.util.Collections;
import java.util.List;
public class ManagementActorTest extends BaseActorTestCase
@@ -34,10 +35,10 @@ public class ManagementActorTest extends BaseActorTestCase
private String _threadName;
@Override
- public void createBroker() throws Exception
+ public void setUp() throws Exception
{
- super.createBroker();
- _amqpActor = new ManagementActor(_rootLogger);
+ super.setUp();
+ setAmqpActor(new ManagementActor(getRootLogger()));
// Set the thread name to be the same as a RMI JMX Connection would use
_threadName = Thread.currentThread().getName();
@@ -56,14 +57,14 @@ public class ManagementActorTest extends BaseActorTestCase
*
* The test sends a message then verifies that it entered the logs.
*
- * The log message should be fully repalaced (no '{n}' values) and should
+ * The log message should be fully replaced (no '{n}' values) and should
* not contain any channel identification.
*/
public void testConnection()
{
- final String message = sendTestLogMessage(_amqpActor);
+ final String message = sendTestLogMessage(getAmqpActor());
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 1, logs.size());
@@ -94,21 +95,20 @@ public class ManagementActorTest extends BaseActorTestCase
*/
public void testSubjectPrincipalNameAppearance()
{
- Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal("guest")), Collections.EMPTY_SET,
- Collections.EMPTY_SET);
+ Subject subject = TestPrincipalUtils.createTestSubject("guest");
final String message = Subject.doAs(subject, new PrivilegedAction<String>()
{
public String run()
{
- return sendTestLogMessage(_amqpActor);
+ return sendTestLogMessage(getAmqpActor());
}
});
// Verify that the log message was created
assertNotNull("Test log message is not created!", message);
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
// Verify that at least one log message was added to log
assertEquals("Message log size not as expected.", 1, logs.size());
@@ -130,8 +130,8 @@ public class ManagementActorTest extends BaseActorTestCase
public void testGetLogMessageWithoutSubjectButWithActorPrincipal()
{
String principalName = "my_principal";
- _amqpActor = new ManagementActor(_rootLogger, principalName);
- String message = _amqpActor.getLogMessage();
+ setAmqpActor(new ManagementActor(getRootLogger(), principalName));
+ String message = getAmqpActor().getLogMessage();
assertEquals("Unexpected log message", "[mng:" + principalName + "(" + IP + ")] ", message);
}
@@ -149,7 +149,7 @@ public class ManagementActorTest extends BaseActorTestCase
assertLogMessageInRMIThreadWithPrincipal("RMI TCP Connection(1)-" + IP, "my_principal");
Thread.currentThread().setName("RMI TCP Connection(2)-" + IP );
- String message = _amqpActor.getLogMessage();
+ String message = getAmqpActor().getLogMessage();
assertEquals("Unexpected log message", "[mng:N/A(" + IP + ")] ", message);
assertLogMessageWithoutPrincipal("TEST");
@@ -158,28 +158,26 @@ public class ManagementActorTest extends BaseActorTestCase
private void assertLogMessageInRMIThreadWithoutPrincipal(String threadName)
{
Thread.currentThread().setName(threadName );
- String message = _amqpActor.getLogMessage();
+ String message = getAmqpActor().getLogMessage();
assertEquals("Unexpected log message", "[mng:N/A(" + IP + ")] ", message);
}
private void assertLogMessageWithoutPrincipal(String threadName)
{
Thread.currentThread().setName(threadName );
- String message = _amqpActor.getLogMessage();
+ String message = getAmqpActor().getLogMessage();
assertEquals("Unexpected log message", "[" + threadName +"] ", message);
}
private void assertLogMessageInRMIThreadWithPrincipal(String threadName, String principalName)
{
Thread.currentThread().setName(threadName);
- Subject subject = new Subject(true, Collections.singleton(new JMXPrincipal(principalName)), Collections.EMPTY_SET,
- Collections.EMPTY_SET);
-
+ Subject subject = TestPrincipalUtils.createTestSubject(principalName);
final String message = Subject.doAs(subject, new PrivilegedAction<String>()
{
public String run()
{
- return _amqpActor.getLogMessage();
+ return getAmqpActor().getLogMessage();
}
});
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java
index 409f7c84b7..2dc44c58ce 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java
@@ -22,14 +22,16 @@ package org.apache.qpid.server.logging.actors;
import java.util.List;
+import org.apache.qpid.server.util.BrokerTestHelper;
+
public class QueueActorTest extends BaseConnectionActorTestCase
{
@Override
- public void createBroker() throws Exception
+ public void setUp() throws Exception
{
- super.createBroker();
- _amqpActor = new QueueActor(getQueue(), _rootLogger);
+ super.setUp();
+ setAmqpActor(new QueueActor(BrokerTestHelper.createQueue(getName(), getSession().getVirtualHost()), getRootLogger()));
}
/**
@@ -42,9 +44,9 @@ public class QueueActorTest extends BaseConnectionActorTestCase
*/
public void testQueueActor()
{
- final String message = sendTestLogMessage(_amqpActor);
+ final String message = sendTestLogMessage(getAmqpActor());
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 1, logs.size());
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java
index 8eaa165853..58fca488c4 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.logging.actors;
import org.apache.qpid.server.subscription.MockSubscription;
+import org.apache.qpid.server.util.BrokerTestHelper;
import java.util.List;
@@ -37,15 +38,15 @@ public class SubscriptionActorTest extends BaseConnectionActorTestCase
{
@Override
- public void createBroker() throws Exception
+ public void setUp() throws Exception
{
- super.createBroker();
+ super.setUp();
MockSubscription mockSubscription = new MockSubscription();
- mockSubscription.setQueue(getQueue(), false);
+ mockSubscription.setQueue(BrokerTestHelper.createQueue(getName(), getSession().getVirtualHost()), false);
- _amqpActor = new SubscriptionActor(_rootLogger, mockSubscription);
+ setAmqpActor(new SubscriptionActor(getRootLogger(), mockSubscription));
}
/**
@@ -58,9 +59,9 @@ public class SubscriptionActorTest extends BaseConnectionActorTestCase
*/
public void testSubscription()
{
- final String message = sendTestLogMessage(_amqpActor);
+ final String message = sendTestLogMessage(getAmqpActor());
- List<Object> logs = _rawLogger.getLogMessages();
+ List<Object> logs = getRawLogger().getLogMessages();
assertEquals("Message log size not as expected.", 1, logs.size());
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/LoggingManagementFacadeTest.java
index f871baffe6..72b34868ba 100644
--- 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/LoggingManagementFacadeTest.java
@@ -20,17 +20,19 @@
package org.apache.qpid.server.logging.log4j;
import java.io.File;
+import java.io.InputStream;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Level;
+import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.util.FileUtils;
import junit.framework.TestCase;
-public class LoggingFacadeTest extends TestCase
+public class LoggingManagementFacadeTest extends TestCase
{
- private LoggingFacade _loggingFacade;
+ private LoggingManagementFacade _loggingFacade;
private String _log4jXmlFile;
@Override
@@ -38,7 +40,7 @@ public class LoggingFacadeTest extends TestCase
{
super.setUp();
_log4jXmlFile = createTestLog4jXml();
- _loggingFacade = LoggingFacade.configure(_log4jXmlFile);
+ _loggingFacade = LoggingManagementFacade.configure(_log4jXmlFile);
}
public void testGetAvailableLoggerLevels() throws Exception
@@ -236,10 +238,6 @@ public class LoggingFacadeTest extends TestCase
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();
+ return TestFileUtils.createTempFileFromResource(this, "LoggingFacadeTest.log4j.xml").getAbsolutePath();
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
index 24e7225d82..229d75c69f 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java
@@ -29,11 +29,12 @@ import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.logging.UnitTestMessageLogger;
import org.apache.qpid.server.logging.actors.TestLogActor;
import org.apache.qpid.server.logging.subjects.TestBlankSubject;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.List;
-public abstract class AbstractTestMessages extends InternalBrokerBaseCase
+public abstract class AbstractTestMessages extends QpidTestCase
{
protected Configuration _config = new PropertiesConfiguration();
protected LogMessage _logMessage = null;
@@ -49,6 +50,14 @@ public abstract class AbstractTestMessages extends InternalBrokerBaseCase
_logger = new UnitTestMessageLogger();
_actor = new TestLogActor(_logger);
+ BrokerTestHelper.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
}
protected List<Object> performLog()
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
index 4364376000..1cb4da55c3 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ExchangeMessagesTest.java
@@ -21,7 +21,7 @@
package org.apache.qpid.server.logging.messages;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import java.util.List;
@@ -30,12 +30,9 @@ import java.util.List;
*/
public class ExchangeMessagesTest extends AbstractTestMessages
{
- public void testExchangeCreated_Transient()
+ public void testExchangeCreated_Transient() throws Exception
{
- // Get the Default Exchange on the Test Vhost for testing
- Exchange exchange = ApplicationRegistry.getInstance().
- getVirtualHostRegistry().getVirtualHost("test").
- getExchangeRegistry().getDefaultExchange();
+ Exchange exchange = BrokerTestHelper.createExchange("test");
String type = exchange.getTypeShortString().toString();
String name = exchange.getNameShortString().toString();
@@ -48,12 +45,9 @@ public class ExchangeMessagesTest extends AbstractTestMessages
validateLogMessage(log, "EXH-1001", expected);
}
- public void testExchangeCreated_Persistent()
+ public void testExchangeCreated_Persistent() throws Exception
{
- // Get the Default Exchange on the Test Vhost for testing
- Exchange exchange = ApplicationRegistry.getInstance().
- getVirtualHostRegistry().getVirtualHost("test").
- getExchangeRegistry().getDefaultExchange();
+ Exchange exchange = BrokerTestHelper.createExchange("test");
String type = exchange.getTypeShortString().toString();
String name = exchange.getNameShortString().toString();
@@ -76,12 +70,9 @@ public class ExchangeMessagesTest extends AbstractTestMessages
validateLogMessage(log, "EXH-1002", expected);
}
- public void testExchangeDiscardedMessage()
+ public void testExchangeDiscardedMessage() throws Exception
{
- // Get the Default Exchange on the Test Vhost for testing
- final Exchange exchange = ApplicationRegistry.getInstance().
- getVirtualHostRegistry().getVirtualHost("test").
- getExchangeRegistry().getDefaultExchange();
+ Exchange exchange = BrokerTestHelper.createExchange("test");
final String name = exchange.getNameShortString().toString();
final String routingKey = "routingKey";
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java
index 4bfbae44ac..dfc9357402 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/messages/ManagementConsoleMessagesTest.java
@@ -29,10 +29,10 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages
{
public void testManagementStartup()
{
- _logMessage = ManagementConsoleMessages.STARTUP();
+ _logMessage = ManagementConsoleMessages.STARTUP("My");
List<Object> log = performLog();
- String[] expected = {"Startup"};
+ String[] expected = {"My Management Startup"};
validateLogMessage(log, "MNG-1001", expected);
}
@@ -65,29 +65,20 @@ public class ManagementConsoleMessagesTest extends AbstractTestMessages
public void testManagementReady()
{
- _logMessage = ManagementConsoleMessages.READY(false);
+ _logMessage = ManagementConsoleMessages.READY("My");
List<Object> log = performLog();
- String[] expected = {"Ready"};
-
- validateLogMessage(log, "MNG-1004", expected);
-
- _logger.clearLogMessages();
-
- _logMessage = ManagementConsoleMessages.READY(true);
- log = performLog();
-
- expected = new String[]{"Ready : Using the platform JMX Agent"};
+ String[] expected = {"My Management Ready"};
validateLogMessage(log, "MNG-1004", expected);
}
public void testManagementStopped()
{
- _logMessage = ManagementConsoleMessages.STOPPED();
+ _logMessage = ManagementConsoleMessages.STOPPED("My");
List<Object> log = performLog();
- String[] expected = {"Stopped"};
+ String[] expected = {"My Management Stopped"};
validateLogMessage(log, "MNG-1005", expected);
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
index c2558d2d1b..193e8a490d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java
@@ -20,21 +20,19 @@
*/
package org.apache.qpid.server.logging.subjects;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
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.UnitTestMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.TestLogActor;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.List;
@@ -49,29 +47,39 @@ import java.util.List;
* The resulting log file is then validated.
*
*/
-public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase
+public abstract class AbstractTestLogSubject extends QpidTestCase
{
- protected Configuration _config = new PropertiesConfiguration();
protected LogSubject _subject = null;
@Override
public void setUp() throws Exception
{
super.setUp();
-
- _config.setProperty(ServerConfiguration.STATUS_UPDATES, "ON");
+ BrokerTestHelper.setUp();
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ try
+ {
+ CurrentActor.removeAll();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
- protected List<Object> performLog() throws ConfigurationException
+ protected List<Object> performLog(boolean statusUpdatesEnabled)
{
if (_subject == null)
{
throw new NullPointerException("LogSubject has not been set");
}
- ServerConfiguration serverConfig = new ServerConfiguration(_config);
- UnitTestMessageLogger logger = new UnitTestMessageLogger(serverConfig);
+ UnitTestMessageLogger logger = new UnitTestMessageLogger(statusUpdatesEnabled);
LogActor actor = new TestLogActor(logger);
@@ -247,11 +255,10 @@ public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase
/**
* Test that when Logging occurs a single log statement is provided
*
- * @throws ConfigurationException
*/
- public void testEnabled() throws ConfigurationException
+ public void testEnabled()
{
- List<Object> logs = performLog();
+ List<Object> logs = performLog(true);
assertEquals("Log has incorrect message count", 1, logs.size());
@@ -267,15 +274,11 @@ public abstract class AbstractTestLogSubject extends InternalBrokerBaseCase
protected abstract void validateLogStatement(String message);
/**
- * Ensure that when status-updates are off this does not perform logging
- *
- * @throws ConfigurationException
+ * Ensure that when status updates are off this does not perform logging
*/
- public void testDisabled() throws ConfigurationException
+ public void testDisabled()
{
- _config.setProperty(ServerConfiguration.STATUS_UPDATES, "OFF");
-
- List<Object> logs = performLog();
+ List<Object> logs = performLog(false);
assertEquals("Log has incorrect message count", 0, logs.size());
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
index e80c4c4679..dd8d28e836 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/BindingLogSubjectTest.java
@@ -24,7 +24,7 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
/**
@@ -38,13 +38,12 @@ public class BindingLogSubjectTest extends AbstractTestLogSubject
private Exchange _exchange;
private VirtualHost _testVhost;
+ @Override
public void setUp() throws Exception
{
super.setUp();
- _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost("test");
- // Configure items for subjectCreation
+ _testVhost = BrokerTestHelper.createVirtualHost("test");
_routingKey = new AMQShortString("RoutingKey");
_exchange = _testVhost.getExchangeRegistry().getDefaultExchange();
_queue = new MockAMQQueue("BindingLogSubjectTest");
@@ -53,6 +52,16 @@ public class BindingLogSubjectTest extends AbstractTestLogSubject
_subject = new BindingLogSubject(String.valueOf(_routingKey), _exchange, _queue);
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_testVhost != null)
+ {
+ _testVhost.close();
+ }
+ super.tearDown();
+ }
+
/**
* Validate that the logged Subject message is as expected:
* MESSAGE [Blank][vh(/test)/ex(direct/<<default>>)/qu(BindingLogSubjectTest)/rk(RoutingKey)] <Log Message>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java
index 6bc5effa05..d75e033739 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ChannelLogSubjectTest.java
@@ -34,6 +34,7 @@ public class ChannelLogSubjectTest extends ConnectionLogSubjectTest
{
super.setUp();
+
AMQChannel channel = new AMQChannel(getSession(), _channelID, getSession().getVirtualHost().getMessageStore());
_subject = new ChannelLogSubject(channel);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java
index c246fff2a8..7dc4c443ba 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubjectTest.java
@@ -20,17 +20,34 @@
*/
package org.apache.qpid.server.logging.subjects;
+import org.apache.qpid.server.protocol.InternalTestProtocolSession;
+import org.apache.qpid.server.util.BrokerTestHelper;
+
/**
* Validate ConnectionLogSubjects are logged as expected
*/
public class ConnectionLogSubjectTest extends AbstractTestLogSubject
{
+ private InternalTestProtocolSession _session;
+
+ @Override
public void setUp() throws Exception
{
super.setUp();
- _subject = new ConnectionLogSubject(getSession());
+ _session = BrokerTestHelper.createSession("test");
+ _subject = new ConnectionLogSubject(_session);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_session != null)
+ {
+ _session.getVirtualHost().close();
+ }
+ super.tearDown();
}
/**
@@ -40,7 +57,12 @@ public class ConnectionLogSubjectTest extends AbstractTestLogSubject
*/
protected void validateLogStatement(String message)
{
- verifyConnection(getSession().getSessionID(), "InternalTestProtocolSession", "127.0.0.1:1", "test", message);
+ verifyConnection(_session.getSessionID(), "InternalTestProtocolSession", "127.0.0.1:1", "test", message);
+ }
+
+ public InternalTestProtocolSession getSession()
+ {
+ return _session;
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java
index cc06b05bf6..8d1b89bf3c 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubjectTest.java
@@ -21,7 +21,7 @@
package org.apache.qpid.server.logging.subjects;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -33,17 +33,27 @@ public class ExchangeLogSubjectTest extends AbstractTestLogSubject
private Exchange _exchange;
private VirtualHost _testVhost;
+ @Override
public void setUp() throws Exception
{
super.setUp();
- _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost("test");
+ _testVhost = BrokerTestHelper.createVirtualHost("test");
_exchange = _testVhost.getExchangeRegistry().getDefaultExchange();
_subject = new ExchangeLogSubject(_exchange,_testVhost);
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_testVhost != null)
+ {
+ _testVhost.close();
+ }
+ super.tearDown();
+ }
+
/**
* Validate that the logged Subject message is as expected:
* MESSAGE [Blank][vh(/test)/ex(direct/<<default>>)] <Log Message>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java
index c62b24c3b9..65fd249d03 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubjectTest.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.server.logging.subjects;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
/**
@@ -30,16 +30,26 @@ public class MessageStoreLogSubjectTest extends AbstractTestLogSubject
{
private VirtualHost _testVhost;
+ @Override
public void setUp() throws Exception
{
super.setUp();
- _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost("test");
+ _testVhost = BrokerTestHelper.createVirtualHost("test");
_subject = new MessageStoreLogSubject(_testVhost, _testVhost.getMessageStore().getClass().getSimpleName());
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_testVhost != null)
+ {
+ _testVhost.close();
+ }
+ super.tearDown();
+ }
+
/**
* Validate that the logged Subject message is as expected:
* MESSAGE [Blank][vh(/test)/ms(MemoryMessageStore)] <Log Message>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java
index 1f432be57a..e2765f338b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/QueueLogSubjectTest.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.logging.subjects;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
/**
@@ -39,8 +39,7 @@ public class QueueLogSubjectTest extends AbstractTestLogSubject
{
super.setUp();
- _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost("test");
+ _testVhost = BrokerTestHelper.createVirtualHost("test");
_queue = new MockAMQQueue("QueueLogSubjectTest");
((MockAMQQueue) _queue).setVirtualHost(_testVhost);
@@ -48,6 +47,16 @@ public class QueueLogSubjectTest extends AbstractTestLogSubject
_subject = new QueueLogSubject(_queue);
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_testVhost != null)
+ {
+ _testVhost.close();
+ }
+ super.tearDown();
+ }
+
/**
* Validate that the logged Subject message is as expected:
* MESSAGE [Blank][vh(/test)/qu(QueueLogSubjectTest)] <Log Message>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java
index 0c356e1838..153d01f355 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubjectTest.java
@@ -23,12 +23,13 @@ package org.apache.qpid.server.logging.subjects;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.flow.LimitlessCreditManager;
+import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
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.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
/**
@@ -42,23 +43,24 @@ public class SubscriptionLogSubjectTest extends AbstractTestLogSubject
private int _channelID = 1;
private Subscription _subscription;
+ @Override
public void setUp() throws Exception
{
super.setUp();
- _testVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost("test");
+ InternalTestProtocolSession session = BrokerTestHelper.createSession();
+ _testVhost = session.getVirtualHost();
_queue = new MockAMQQueue("SubscriptionLogSubjectTest");
((MockAMQQueue) _queue).setVirtualHost(_testVhost);
- AMQChannel channel = new AMQChannel(getSession(), _channelID, getSession().getVirtualHost().getMessageStore());
+ AMQChannel channel = new AMQChannel(session, _channelID, _testVhost.getMessageStore());
- getSession().addChannel(channel);
+ session.addChannel(channel);
SubscriptionFactory factory = new SubscriptionFactoryImpl();
- _subscription = factory.createSubscription(_channelID, getSession(), new AMQShortString("cTag"),
+ _subscription = factory.createSubscription(_channelID, session, new AMQShortString("cTag"),
false, null, false,
new LimitlessCreditManager());
@@ -67,6 +69,16 @@ public class SubscriptionLogSubjectTest extends AbstractTestLogSubject
_subject = new SubscriptionLogSubject(_subscription);
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ if (_testVhost != null)
+ {
+ _testVhost.close();
+ }
+ super.tearDown();
+ }
+
/**
* Validate that the logged Subject message is as expected:
* MESSAGE [Blank][sub:0(vh(/test)/qu(SubscriptionLogSubjectTest))] <Log Message>
diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java
new file mode 100644
index 0000000000..7c1db6348b
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/BrokerShutdownTest.java
@@ -0,0 +1,189 @@
+/*
+ *
+ * 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
+import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider;
+import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.logging.RootMessageLogger;
+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.State;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+import java.io.File;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * QPID-1390 : Test to validate that the AuthenticationManger can successfully unregister any new SASL providers when
+ * the broker is stopped.
+ */
+public class BrokerShutdownTest extends QpidTestCase
+{
+ private Provider[] _defaultProviders;
+ private Broker _broker;
+ private TaskExecutor _taskExecutor;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ // Get default providers
+ _defaultProviders = Security.getProviders();
+
+ super.setUp();
+
+ _taskExecutor = new TaskExecutor();
+ _taskExecutor.start();
+
+ // Startup the new broker and register the new providers
+ _broker = startBroker();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ if (_taskExecutor != null)
+ {
+ _taskExecutor.stopImmediately();
+ }
+ }
+
+ }
+
+ private Broker startBroker() throws Exception
+ {
+ ConfigurationEntryStore store = mock(ConfigurationEntryStore.class);
+ UUID brokerId = UUID.randomUUID();
+ UUID authenticationProviderId = UUID.randomUUID();
+
+ ConfigurationEntry root = new ConfigurationEntry(brokerId, Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(),
+ Collections.singleton(authenticationProviderId), store);
+
+ File file = TestFileUtils.createTempFile(BrokerShutdownTest.this, ".db.users");
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ attributes.put(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH, file.getAbsolutePath());
+ ConfigurationEntry authenticationProviderEntry = new ConfigurationEntry(authenticationProviderId, AuthenticationProvider.class.getSimpleName(), attributes,
+ Collections.<UUID> emptySet(), store);
+
+ when(store.getRootEntry()).thenReturn(root);
+ when(store.getEntry(brokerId)).thenReturn(root);
+ when(store.getEntry(authenticationProviderId)).thenReturn(authenticationProviderEntry);
+
+ // mocking the required object
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ VirtualHostRegistry virtualHostRegistry = mock(VirtualHostRegistry.class);
+ LogRecorder logRecorder = mock(LogRecorder.class);
+ RootMessageLogger rootMessageLogger = mock(RootMessageLogger.class);
+
+ // recover the broker from the store
+ RecovererProvider provider = new DefaultRecovererProvider(statisticsGatherer, virtualHostRegistry, logRecorder, rootMessageLogger, _taskExecutor);
+ ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName());
+
+ Broker broker = (Broker) brokerRecoverer.create(provider, store.getRootEntry());
+
+ // start broker
+ broker.setDesiredState(State.INITIALISING, State.ACTIVE);
+ return broker;
+ }
+
+ private void stopBroker()
+ {
+ _broker.setDesiredState(State.ACTIVE, State.STOPPED);
+ }
+
+ /**
+ * QPID-1399 : Ensure that the Authentication manager unregisters any SASL providers created during
+ * broker start-up.
+ *
+ */
+ public void testAuthenticationMangerCleansUp() throws Exception
+ {
+
+ // Get the providers after initialisation
+ Provider[] providersAfterInitialisation = Security.getProviders();
+
+ // Find the additions
+ List<Provider> additions = new LinkedList<Provider>();
+ for (Provider afterInit : providersAfterInitialisation)
+ {
+ boolean found = false;
+ for (Provider defaultProvider : _defaultProviders)
+ {
+ if (defaultProvider == afterInit)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ // Record added registies
+ if (!found)
+ {
+ additions.add(afterInit);
+ }
+ }
+
+ assertFalse("No new SASL mechanisms added by initialisation.", additions.isEmpty());
+
+ // Close the registry which will perform the close the
+ // AuthenticationManager
+ stopBroker();
+
+ // Validate that the SASL plugins have been removed.
+ Provider[] providersAfterClose = Security.getProviders();
+
+ assertTrue("No providers unregistered", providersAfterInitialisation.length > providersAfterClose.length);
+
+ // Ensure that the additions are not still present after close().
+ for (Provider afterClose : providersAfterClose)
+ {
+ assertFalse("Added provider not unregistered", additions.contains(afterClose));
+ }
+ }
+
+}
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
index 643132d371..c686a24e99 100644
--- 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
@@ -70,8 +70,12 @@ public class UUIDGeneratorTest extends QpidTestCase
idSet.add(id6);
UUID id7 = UUIDGenerator.generateVhostAliasUUID(value, value);
idSet.add(id7);
+ UUID id8 = UUIDGenerator.generateGroupUUID(value, value);
+ idSet.add(id8);
+ UUID id9 = UUIDGenerator.generateGroupMemberUUID(value, value, value);
+ idSet.add(id9);
- assertEquals("The produced UUIDs were not all unique", 7, idSet.size());
+ assertEquals("The produced UUIDs were not all unique", 9, idSet.size());
}
public void testQueueIdGeneration() throws Exception
diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java
new file mode 100644
index 0000000000..585fecae83
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.plugin.QpidServiceLoader;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+
+public class AuthenticationProviderFactoryTest extends TestCase
+{
+
+ public void testCreatePasswordCredentialManagingAuthenticationProvider()
+ {
+ AuthenticationProvider provider = testForFactory(mock(PrincipalDatabaseAuthenticationManager.class));
+ assertTrue("The created provider should match the factory's AuthenticationManager type",
+ provider instanceof PasswordCredentialManagingAuthenticationProvider);
+ }
+
+ public void testCreateNonPasswordCredentialManagingAuthenticationProvider()
+ {
+ AuthenticationProvider provider = testForFactory(mock(AuthenticationManager.class));
+ assertFalse("The created provider should match the factory's AuthenticationManager type",
+ provider instanceof PasswordCredentialManagingAuthenticationProvider);
+ }
+
+ @SuppressWarnings("unchecked")
+ private AuthenticationProvider testForFactory(AuthenticationManager authenticationManager)
+ {
+ UUID id = UUID.randomUUID();
+ Map<String, Object> attributes = new HashMap<String, Object>();
+
+ QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader = mock(QpidServiceLoader.class);
+ AuthenticationManagerFactory authenticationManagerFactory = mock(AuthenticationManagerFactory.class);
+ ConfigurationEntry configurationEntry = mock(ConfigurationEntry.class);
+
+ when(configurationEntry.getId()).thenReturn(id);
+ Broker broker = mock(Broker.class);
+
+ when(authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(
+ Collections.singleton(authenticationManagerFactory));
+ when(authenticationManagerFactory.createInstance(attributes)).thenReturn(authenticationManager);
+
+ AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(authManagerFactoryServiceLoader);
+ AuthenticationProvider provider = providerFactory.create(id, broker, attributes, null);
+
+ assertNotNull("Provider is not created", provider);
+ assertEquals("Unexpected ID", id, provider.getId());
+
+ return provider;
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
new file mode 100644
index 0000000000..14c5c265c9
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
@@ -0,0 +1,212 @@
+/*
+ *
+ * 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 static org.mockito.Mockito.mock;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class PortFactoryTest extends QpidTestCase
+{
+ private UUID _portId = UUID.randomUUID();
+ private int _portNumber = 123;
+ private Set<String> _tcpStringSet = Collections.singleton(Transport.SSL.name());
+ private Set<Transport> _tcpTransportSet = Collections.singleton(Transport.SSL);
+
+ private Map<String, Object> _attributes = new HashMap<String, Object>();
+
+ private Broker _broker = mock(Broker.class);
+ private PortFactory _portFactory;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, null);
+ setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, null);
+ _portFactory = new PortFactory();
+
+ _attributes.put(Port.PORT, _portNumber);
+ _attributes.put(Port.TRANSPORTS, _tcpStringSet);
+
+ _attributes.put(Port.TCP_NO_DELAY, "true");
+ _attributes.put(Port.RECEIVE_BUFFER_SIZE, "1");
+ _attributes.put(Port.SEND_BUFFER_SIZE, "2");
+ _attributes.put(Port.NEED_CLIENT_AUTH, "true");
+ _attributes.put(Port.WANT_CLIENT_AUTH, "true");
+ _attributes.put(Port.BINDING_ADDRESS, "127.0.0.1");
+ }
+
+ public void testDefaultProtocols()
+ {
+ Collection<Protocol> protocols = _portFactory.getDefaultProtocols();
+ EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, Protocol.AMQP_0_10,
+ Protocol.AMQP_1_0);
+ assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols));
+ }
+
+ public void testDefaultProtocolsWhenProtocolExcludeSystemPropertyIsSet()
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, Protocol.AMQP_1_0.name() + ","
+ + Protocol.AMQP_0_10.name());
+ _portFactory = new PortFactory();
+ Collection<Protocol> protocols = _portFactory.getDefaultProtocols();
+ EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1);
+ assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols));
+ }
+
+ public void testDefaultProtocolsWhenProtocolIncludeSystemPropertyIsSet()
+ {
+ setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, Protocol.AMQP_1_0.name() + ","
+ + Protocol.AMQP_0_10.name() + "," + Protocol.AMQP_0_9_1.name());
+ setTestSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, Protocol.AMQP_0_10.name() + ","
+ + Protocol.AMQP_0_9_1.name());
+ _portFactory = new PortFactory();
+ Collection<Protocol> protocols = _portFactory.getDefaultProtocols();
+ EnumSet<Protocol> expected = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, Protocol.AMQP_0_10);
+ assertEquals("Unexpected protocols", new HashSet<Protocol>(expected), new HashSet<Protocol>(protocols));
+ }
+
+ public void testCreatePortWithMinimumAttributes()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(Port.PORT, 1);
+ Port port = _portFactory.createPort(_portId, _broker, attributes);
+
+ assertNotNull(port);
+ assertTrue(port instanceof AmqpPortAdapter);
+ assertEquals("Unexpected port", 1, port.getPort());
+ assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports());
+ assertEquals("Unexpected protocols", _portFactory.getDefaultProtocols(), port.getProtocols());
+ assertEquals("Unexpected send buffer size", PortFactory.DEFAULT_AMQP_SEND_BUFFER_SIZE,
+ port.getAttribute(Port.SEND_BUFFER_SIZE));
+ assertEquals("Unexpected receive buffer size", PortFactory.DEFAULT_AMQP_RECEIVE_BUFFER_SIZE,
+ port.getAttribute(Port.RECEIVE_BUFFER_SIZE));
+ assertEquals("Unexpected need client auth", PortFactory.DEFAULT_AMQP_NEED_CLIENT_AUTH,
+ port.getAttribute(Port.NEED_CLIENT_AUTH));
+ assertEquals("Unexpected want client auth", PortFactory.DEFAULT_AMQP_WANT_CLIENT_AUTH,
+ port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, port.getAttribute(Port.TCP_NO_DELAY));
+ assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, port.getAttribute(Port.BINDING_ADDRESS));
+ }
+
+ public void testCreateAmqpPort()
+ {
+ Set<Protocol> amqp010ProtocolSet = Collections.singleton(Protocol.AMQP_0_10);
+ Set<String> amqp010StringSet = Collections.singleton(Protocol.AMQP_0_10.name());
+ _attributes.put(Port.PROTOCOLS, amqp010StringSet);
+
+ Port port = _portFactory.createPort(_portId, _broker, _attributes);
+
+ assertNotNull(port);
+ assertTrue(port instanceof AmqpPortAdapter);
+ assertEquals(_portId, port.getId());
+ assertEquals(_portNumber, port.getPort());
+ assertEquals(_tcpTransportSet, port.getTransports());
+ assertEquals(amqp010ProtocolSet, port.getProtocols());
+ assertEquals("Unexpected send buffer size", 2, port.getAttribute(Port.SEND_BUFFER_SIZE));
+ assertEquals("Unexpected receive buffer size", 1, port.getAttribute(Port.RECEIVE_BUFFER_SIZE));
+ assertEquals("Unexpected need client auth", true, port.getAttribute(Port.NEED_CLIENT_AUTH));
+ assertEquals("Unexpected want client auth", true, port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertEquals("Unexpected tcp no delay", true, port.getAttribute(Port.TCP_NO_DELAY));
+ assertEquals("Unexpected binding", "127.0.0.1", port.getAttribute(Port.BINDING_ADDRESS));
+ }
+
+ public void testCreateNonAmqpPort()
+ {
+ Set<Protocol> nonAmqpProtocolSet = Collections.singleton(Protocol.JMX_RMI);
+ Set<String> nonAmqpStringSet = Collections.singleton(Protocol.JMX_RMI.name());
+ _attributes = new HashMap<String, Object>();
+ _attributes.put(Port.PROTOCOLS, nonAmqpStringSet);
+ _attributes.put(Port.PORT, _portNumber);
+ _attributes.put(Port.TRANSPORTS, _tcpStringSet);
+
+ Port port = _portFactory.createPort(_portId, _broker, _attributes);
+
+ assertNotNull(port);
+ assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPortAdapter);
+ assertEquals(_portId, port.getId());
+ assertEquals(_portNumber, port.getPort());
+ assertEquals(_tcpTransportSet, port.getTransports());
+ assertEquals(nonAmqpProtocolSet, port.getProtocols());
+ assertNull("Unexpected send buffer size", port.getAttribute(Port.SEND_BUFFER_SIZE));
+ assertNull("Unexpected receive buffer size", port.getAttribute(Port.RECEIVE_BUFFER_SIZE));
+ assertNull("Unexpected need client auth", port.getAttribute(Port.NEED_CLIENT_AUTH));
+ assertNull("Unexpected want client auth", port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertNull("Unexpected tcp no delay", port.getAttribute(Port.TCP_NO_DELAY));
+ assertNull("Unexpected binding", port.getAttribute(Port.BINDING_ADDRESS));
+ }
+
+ public void testCreateNonAmqpPortWithPartiallySetAttributes()
+ {
+ Set<Protocol> nonAmqpProtocolSet = Collections.singleton(Protocol.JMX_RMI);
+ Set<String> nonAmqpStringSet = Collections.singleton(Protocol.JMX_RMI.name());
+ _attributes = new HashMap<String, Object>();
+ _attributes.put(Port.PROTOCOLS, nonAmqpStringSet);
+ _attributes.put(Port.PORT, _portNumber);
+
+ Port port = _portFactory.createPort(_portId, _broker, _attributes);
+
+ assertNotNull(port);
+ assertFalse("Port should be a PortAdapter, not its AMQP-specific subclass", port instanceof AmqpPortAdapter);
+ assertEquals(_portId, port.getId());
+ assertEquals(_portNumber, port.getPort());
+ assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports());
+ assertEquals(nonAmqpProtocolSet, port.getProtocols());
+ assertNull("Unexpected send buffer size", port.getAttribute(Port.SEND_BUFFER_SIZE));
+ assertNull("Unexpected receive buffer size", port.getAttribute(Port.RECEIVE_BUFFER_SIZE));
+ assertNull("Unexpected need client auth", port.getAttribute(Port.NEED_CLIENT_AUTH));
+ assertNull("Unexpected want client auth", port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertNull("Unexpected tcp no delay", port.getAttribute(Port.TCP_NO_DELAY));
+ assertNull("Unexpected binding", port.getAttribute(Port.BINDING_ADDRESS));
+ }
+
+ public void testCreateMixedAmqpAndNonAmqpThrowsException()
+ {
+ Set<String> mixedProtocolSet = new HashSet<String>(Arrays.asList(Protocol.AMQP_0_10.name(), Protocol.JMX_RMI.name()));
+ _attributes.put(Port.PROTOCOLS, mixedProtocolSet);
+
+ try
+ {
+ _portFactory.createPort(_portId, _broker, _attributes);
+ fail("Exception not thrown");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ // pass
+ }
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java b/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java
new file mode 100644
index 0000000000..dd48d7b56d
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/model/configuration/ConfigurationEntryTest.java
@@ -0,0 +1,129 @@
+/*
+ *
+ * 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.configuration;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.ConfigurationEntryStore;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.VirtualHost;
+
+public class ConfigurationEntryTest extends TestCase
+{
+ public void testGetChildren()
+ {
+ ConfigurationEntryStore store = mock(ConfigurationEntryStore.class);
+
+ ConfigurationEntry virtualHostEntry1 = new ConfigurationEntry(UUID.randomUUID(), VirtualHost.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store);
+ ConfigurationEntry virtualHostEntry2 = new ConfigurationEntry(UUID.randomUUID(), VirtualHost.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store);
+ ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), Port.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), store);
+
+ when(store.getEntry(virtualHostEntry1.getId())).thenReturn(virtualHostEntry1);
+ when(store.getEntry(virtualHostEntry2.getId())).thenReturn(virtualHostEntry2);
+ when(store.getEntry(portEntry.getId())).thenReturn(portEntry);
+
+ Set<UUID> childrenIds = new HashSet<UUID>();
+ childrenIds.add(virtualHostEntry1.getId());
+ childrenIds.add(virtualHostEntry2.getId());
+ childrenIds.add(portEntry.getId());
+ ConfigurationEntry parentEntry = new ConfigurationEntry(UUID.randomUUID(), Broker.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), childrenIds, store);
+
+ Map<String, Collection<ConfigurationEntry>> children = parentEntry.getChildren();
+ assertNotNull("Null is returned for children", children);
+ assertEquals("Unexpected size", 2, children.size());
+ Collection<ConfigurationEntry> virtualHosts = children.get(VirtualHost.class.getSimpleName());
+ Collection<ConfigurationEntry> ports = children.get(Port.class.getSimpleName());
+ assertEquals("Unexpected virtual hosts",
+ new HashSet<ConfigurationEntry>(Arrays.asList(virtualHostEntry1, virtualHostEntry2)),
+ new HashSet<ConfigurationEntry>(virtualHosts));
+ assertEquals("Unexpected ports", new HashSet<ConfigurationEntry>(Arrays.asList(portEntry)),
+ new HashSet<ConfigurationEntry>(ports));
+ }
+
+ public void testHashCode()
+ {
+ ConfigurationEntryStore store = mock(ConfigurationEntryStore.class);
+
+ UUID id = UUID.randomUUID();
+ ConfigurationEntry entry1 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store);
+ ConfigurationEntry entry2 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(),
+ Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store);
+ ConfigurationEntry entryWithDifferentId = new ConfigurationEntry(UUID.randomUUID(),
+ VirtualHost.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.singleton(UUID.randomUUID()), store);
+
+ assertTrue(entry1.hashCode() == entry2.hashCode());
+ assertFalse(entry1.hashCode() == entryWithDifferentId.hashCode());
+ }
+
+ public void testEqualsObject()
+ {
+ ConfigurationEntryStore store = mock(ConfigurationEntryStore.class);
+
+ UUID id = UUID.randomUUID();
+ Map<String, Object> attributes1 = new HashMap<String, Object>();
+ attributes1.put(VirtualHost.NAME, "name1");
+ Set<UUID> childrenIds = Collections.singleton(UUID.randomUUID());
+ ConfigurationEntry entry1 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), attributes1,
+ childrenIds, store);
+
+ Map<String, Object> attributes2 = new HashMap<String, Object>();
+ attributes2.put(VirtualHost.NAME, "name2");
+
+ ConfigurationEntry entry2 = new ConfigurationEntry(id, VirtualHost.class.getSimpleName(), attributes1,
+ childrenIds, store);
+ ConfigurationEntry entryWithDifferentId = new ConfigurationEntry(UUID.randomUUID(),
+ VirtualHost.class.getSimpleName(), attributes1, childrenIds, store);
+
+ assertTrue(entry1.equals(entry2));
+ assertFalse("Entries should be diferrent because of diferrent IDs", entry1.equals(entryWithDifferentId));
+
+ ConfigurationEntry entryWithDifferentChildId = new ConfigurationEntry(id,
+ VirtualHost.class.getSimpleName(), attributes1, Collections.singleton(UUID.randomUUID()), store);
+ assertFalse("Entries should be diferrent because of diferrent children", entry1.equals(entryWithDifferentChildId));
+
+ ConfigurationEntry entryWithDifferentName = new ConfigurationEntry(id,
+ VirtualHost.class.getSimpleName(), attributes2, childrenIds, store);
+ assertFalse("Entries should be diferrent because of diferrent attributes", entry1.equals(entryWithDifferentName));
+
+ ConfigurationEntry entryWithDifferentType = new ConfigurationEntry(id,
+ Broker.class.getSimpleName(), attributes1, childrenIds, store);
+ assertFalse("Entries should be diferrent because of diferrent types", entry1.equals(entryWithDifferentType));
+ }
+}
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
deleted file mode 100644
index 20abdd48cd..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtilTest.java
+++ /dev/null
@@ -1,94 +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.plugins;
-
-import org.osgi.framework.Version;
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- *
- */
-public class OsgiSystemPackageUtilTest extends QpidTestCase
-{
- private OsgiSystemPackageUtil _util = null; // Object under test
-
- private Map<String, String> _map = new TreeMap<String, String>(); // Use a TreeMap for unit test in order for determinstic results.
-
- public void testWithOnePackage() throws Exception
- {
- _map.put("org.xyz", "1.0.0");
-
- _util = new OsgiSystemPackageUtil(null, _map);
-
- final String systemPackageString = _util.getFormattedSystemPackageString();
-
- assertEquals("org.xyz; version=1.0.0", systemPackageString);
- }
-
- public void testWithTwoPackages() throws Exception
- {
- _map.put("org.xyz", "1.0.0");
- _map.put("org.abc", "1.2.3");
-
- _util = new OsgiSystemPackageUtil(null, _map);
-
- final String systemPackageString = _util.getFormattedSystemPackageString();
-
- assertEquals("org.abc; version=1.2.3, org.xyz; version=1.0.0", systemPackageString);
- }
-
- public void testWithNoPackages() throws Exception
- {
- _util = new OsgiSystemPackageUtil(null, _map);
-
- final String systemPackageString = _util.getFormattedSystemPackageString();
-
- assertNull(systemPackageString);
- }
-
- public void testWithQpidPackageWithQpidReleaseNumberSet() throws Exception
- {
- _map.put("org.apache.qpid.xyz", "1.0.0");
- _map.put("org.abc", "1.2.3");
-
- _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.19.0", systemPackageString);
- }
-
- public void testWithQpidPackageWithoutQpidReleaseNumberSet() throws Exception
- {
- _map.put("org.apache.qpid.xyz", "1.0.0");
- _map.put("org.abc", "1.2.3");
-
- _util = new OsgiSystemPackageUtil(null, _map);
-
- final String systemPackageString = _util.getFormattedSystemPackageString();
-
- assertEquals("org.abc; version=1.2.3, org.apache.qpid.xyz; version=1.0.0", systemPackageString);
- }
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java b/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java
deleted file mode 100644
index b4bda9a032..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/plugins/PluginTest.java
+++ /dev/null
@@ -1,55 +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.plugins;
-
-import org.apache.qpid.server.exchange.ExchangeType;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import java.util.Map;
-
-public class PluginTest extends InternalBrokerBaseCase
-{
- private static final String TEST_EXCHANGE_CLASS = "org.apache.qpid.extras.exchanges.example.TestExchangeType";
-
- private static final String PLUGIN_DIRECTORY = System.getProperty("example.plugin.target");
- private static final String CACHE_DIRECTORY = System.getProperty("example.cache.target");
-
- @Override
- public void configure()
- {
- getConfiguration().getConfig().addProperty("plugin-directory", PLUGIN_DIRECTORY);
- getConfiguration().getConfig().addProperty("cache-directory", CACHE_DIRECTORY);
- }
-
- public void disabled_testLoadExchanges() throws Exception
- {
- PluginManager manager = getRegistry().getPluginManager();
- Map<String, ExchangeType<?>> exchanges = manager.getExchanges();
- assertNotNull("No exchanges found in " + PLUGIN_DIRECTORY, exchanges);
- assertEquals("Wrong number of exchanges found in " + PLUGIN_DIRECTORY, 2, exchanges.size());
- assertNotNull("Wrong exchange found in " + PLUGIN_DIRECTORY, exchanges.get(TEST_EXCHANGE_CLASS));
- }
-
- public void testNoExchanges() throws Exception
- {
- PluginManager manager = new PluginManager("/path/to/nowhere", "/tmp", null);
- Map<String, ExchangeType<?>> exchanges = manager.getExchanges();
- assertTrue("Exchanges found", exchanges.isEmpty());
- }
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
index 96c67941f9..3216f8886a 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
@@ -28,10 +28,11 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.output.ProtocolOutputConverter;
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.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.subscription.ClientDeliveryMethod;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionImpl;
@@ -39,6 +40,8 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.TestNetworkConnection;
import javax.security.auth.Subject;
+
+import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -55,19 +58,28 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
private AtomicInteger _deliveryCount = new AtomicInteger(0);
private static final AtomicLong ID_GENERATOR = new AtomicLong(0);
- public InternalTestProtocolSession(VirtualHost virtualHost) throws AMQException
+ public InternalTestProtocolSession(VirtualHost virtualHost, Broker broker) throws AMQException
{
- super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkConnection(), ID_GENERATOR.getAndIncrement());
+ super(broker, new TestNetworkConnection(), ID_GENERATOR.getAndIncrement());
_channelDelivers = new HashMap<Integer, Map<AMQShortString, LinkedList<DeliveryPair>>>();
- // Need to authenticate session for it to be representative testing.
- setAuthorizedSubject(new Subject(true, Collections.singleton(new UsernamePrincipal("InternalTestProtocolSession")),
- Collections.EMPTY_SET, Collections.EMPTY_SET));
-
+ setTestAuthorizedSubject();
setVirtualHost(virtualHost);
}
+ private void setTestAuthorizedSubject()
+ {
+ Principal principal = new AuthenticatedPrincipal(new UsernamePrincipal("InternalTestProtocolSession"));
+ Subject authorizedSubject = new Subject(
+ true,
+ Collections.singleton(principal),
+ Collections.emptySet(),
+ Collections.emptySet());
+
+ setAuthorizedSubject(authorizedSubject);
+ }
+
public ProtocolOutputConverter getProtocolOutputConverter()
{
return this;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
index e8ee2c4d0b..99dd42e179 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
@@ -23,20 +23,24 @@ package org.apache.qpid.server.protocol;
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
-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.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
/** Test class to test MBean operations for AMQMinaProtocolSession. */
-public class MaxChannelsTest extends InternalBrokerBaseCase
+public class MaxChannelsTest extends QpidTestCase
{
- private AMQProtocolEngine _session;
+ private AMQProtocolEngine _session;
- public void testChannels() throws Exception
+ @Override
+ public void setUp() throws Exception
{
- VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- _session = new InternalTestProtocolSession(vhost);
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _session = BrokerTestHelper.createSession();
+ }
+ public void testChannels() throws Exception
+ {
// check the channel count is correct
int channelCount = _session.getChannels().size();
assertEquals("Initial channel count wrong", 0, channelCount);
@@ -45,13 +49,15 @@ public class MaxChannelsTest extends InternalBrokerBaseCase
_session.setMaximumNumberOfChannels(maxChannels);
assertEquals("Number of channels not correctly set.", new Long(maxChannels), _session.getMaximumNumberOfChannels());
+ for (long currentChannel = 0L; currentChannel < maxChannels; currentChannel++)
+ {
+ _session.addChannel(new AMQChannel(_session, (int) currentChannel, null));
+ }
try
{
- for (long currentChannel = 0L; currentChannel < maxChannels; currentChannel++)
- {
- _session.addChannel(new AMQChannel(_session, (int) currentChannel, null));
- }
+ _session.addChannel(new AMQChannel(_session, (int) maxChannels, null));
+ fail("Cannot create more channels then maximum");
}
catch (AMQException e)
{
@@ -63,14 +69,14 @@ public class MaxChannelsTest extends InternalBrokerBaseCase
@Override
public void tearDown() throws Exception
{
- try {
- _session.closeSession();
- } catch (AMQException e) {
- // Yikes
- fail(e.getMessage());
- }
+ try
+ {
+ _session.getVirtualHost().close();
+ _session.closeSession();
+ }
finally
{
+ BrokerTestHelper.tearDown();
super.tearDown();
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
index 6081be8efd..02b8c74feb 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java
@@ -20,36 +20,52 @@
*/
package org.apache.qpid.server.protocol;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.protocol.ServerProtocolEngine;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.transport.TestNetworkConnection;
+import static org.mockito.Mockito.when;
import java.nio.ByteBuffer;
import java.util.EnumSet;
import java.util.Set;
+import org.apache.qpid.protocol.ServerProtocolEngine;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.transport.TestNetworkConnection;
+
public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
{
+ private VirtualHost _virtualHost;
+ private Broker _broker;
+ @Override
protected void setUp() throws Exception
{
super.setUp();
+ BrokerTestHelper.setUp();
+ _broker = BrokerTestHelper.createBrokerMock();
+ VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry();
+ when(_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)).thenReturn("default");
- //the factory needs a registry instance
- ApplicationRegistry.initialise(new TestApplicationRegistry(new ServerConfiguration(new XMLConfiguration())));
+ // AMQP 1-0 connection needs default vhost to be present
+ _virtualHost = BrokerTestHelper.createVirtualHost("default", virtualHostRegistry);
}
- protected void tearDown()
+ @Override
+ protected void tearDown() throws Exception
{
- //the factory opens a registry instance
- ApplicationRegistry.remove();
+ try
+ {
+ _virtualHost.close();
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
-
+
private static final byte[] AMQP_0_8_HEADER =
new byte[] { (byte) 'A',
(byte) 'M',
@@ -108,6 +124,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
(byte) 0
};
+
private byte[] getAmqpHeader(final AmqpProtocolVersion version)
{
switch(version)
@@ -137,7 +154,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
Set<AmqpProtocolVersion> versions = EnumSet.allOf(AmqpProtocolVersion.class);
MultiVersionProtocolEngineFactory factory =
- new MultiVersionProtocolEngineFactory(versions, null);
+ new MultiVersionProtocolEngineFactory(_broker, versions, null);
//create a dummy to retrieve the 'current' ID number
long previousId = factory.newProtocolEngine().getConnectionId();
@@ -160,6 +177,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
assertEquals("ID was not as expected following receipt of the AMQP version header", expectedID, engine.getConnectionId());
previousId = expectedID;
+ engine.closed();
}
}
@@ -174,7 +192,7 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase
try
{
- new MultiVersionProtocolEngineFactory(versions, AmqpProtocolVersion.v0_9);
+ new MultiVersionProtocolEngineFactory(_broker, versions, AmqpProtocolVersion.v0_9);
fail("should not have been allowed to create the factory");
}
catch(IllegalArgumentException iae)
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 c3d58f3bdc..81ad57c040 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
@@ -36,8 +36,9 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
@Override
public void setUp() throws Exception
{
- _arguments = new FieldTable();
- _arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 3);
+ FieldTable arguments = new FieldTable();
+ arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 3);
+ setArguments(arguments);
super.setUp();
}
@@ -45,25 +46,26 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
{
// Enqueue messages in order
- _queue.enqueue(createMessage(1L, (byte) 10));
- _queue.enqueue(createMessage(2L, (byte) 4));
- _queue.enqueue(createMessage(3L, (byte) 0));
+ SimpleAMQQueue queue = getQueue();
+ queue.enqueue(createMessage(1L, (byte) 10));
+ queue.enqueue(createMessage(2L, (byte) 4));
+ queue.enqueue(createMessage(3L, (byte) 0));
// Enqueue messages in reverse order
- _queue.enqueue(createMessage(4L, (byte) 0));
- _queue.enqueue(createMessage(5L, (byte) 4));
- _queue.enqueue(createMessage(6L, (byte) 10));
+ queue.enqueue(createMessage(4L, (byte) 0));
+ queue.enqueue(createMessage(5L, (byte) 4));
+ queue.enqueue(createMessage(6L, (byte) 10));
// Enqueue messages out of order
- _queue.enqueue(createMessage(7L, (byte) 4));
- _queue.enqueue(createMessage(8L, (byte) 10));
- _queue.enqueue(createMessage(9L, (byte) 0));
+ queue.enqueue(createMessage(7L, (byte) 4));
+ queue.enqueue(createMessage(8L, (byte) 10));
+ queue.enqueue(createMessage(9L, (byte) 0));
// Register subscriber
- _queue.registerSubscription(_subscription, false);
+ queue.registerSubscription(getSubscription(), false);
Thread.sleep(150);
- ArrayList<QueueEntry> msgs = _subscription.getMessages();
+ ArrayList<QueueEntry> msgs = getSubscription().getMessages();
try
{
assertEquals(1L, msgs.get(0).getMessage().getMessageNumber());
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 186be4dff7..0f82345271 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,23 +20,23 @@
*/
package org.apache.qpid.server.queue;
+import static org.mockito.Mockito.when;
+
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DefaultExchangeFactory;
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.model.Broker;
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.util.TestApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -50,19 +50,19 @@ public class AMQQueueFactoryTest extends QpidTestCase
{
super.setUp();
- CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
-
+ BrokerTestHelper.setUp();
XMLConfiguration configXml = new XMLConfiguration();
- configXml.addProperty("virtualhosts.virtualhost(-1).name", getName());
- configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName());
+ configXml.addProperty("store.class", TestableMemoryMessageStore.class.getName());
- ServerConfiguration configuration = new ServerConfiguration(configXml);
- ApplicationRegistry registry = new TestApplicationRegistry(configuration);
- ApplicationRegistry.initialise(registry);
- registry.getVirtualHostRegistry().setDefaultVirtualHostName(getName());
+ Broker broker = BrokerTestHelper.createBrokerMock();
+ if (getName().equals("testDeadLetterQueueDoesNotInheritDLQorMDCSettings"))
+ {
+ when(broker.getAttribute(Broker.MAXIMUM_DELIVERY_ATTEMPTS)).thenReturn(5);
+ when(broker.getAttribute(Broker.DEAD_LETTER_QUEUE_ENABLED)).thenReturn(true);
+ }
- _virtualHost = registry.getVirtualHostRegistry().getVirtualHost(getName());
+ _virtualHost = BrokerTestHelper.createVirtualHost(new VirtualHostConfiguration(getName(), configXml, broker));
_queueRegistry = _virtualHost.getQueueRegistry();
@@ -73,11 +73,12 @@ public class AMQQueueFactoryTest extends QpidTestCase
{
try
{
- super.tearDown();
+ _virtualHost.close();
}
finally
{
- ApplicationRegistry.remove();
+ BrokerTestHelper.tearDown();
+ super.tearDown();
}
}
@@ -172,11 +173,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
* are not applied to the DLQ itself.
* @throws AMQException
*/
- public void testDeadLetterQueueDoesNotInheritDLQorMDCSettings() throws AMQException
+ public void testDeadLetterQueueDoesNotInheritDLQorMDCSettings() throws Exception
{
- ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("deadLetterQueues","true");
- ApplicationRegistry.getInstance().getConfiguration().getConfig().addProperty("maximumDeliveryCount","5");
-
String queueName = "testDeadLetterQueueEnabled";
AMQShortString dlExchangeName = new AMQShortString(queueName + DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
AMQShortString dlQueueName = new AMQShortString(queueName + AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
@@ -336,11 +334,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
try
{
// change DLQ name to make its length bigger than exchange name
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterExchangeSuffix", "_DLE");
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterQueueSuffix", "_DLQUEUE");
-
+ setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, "_DLE");
+ setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, "_DLQUEUE");
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner",
@@ -353,13 +348,6 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertTrue("Unexpected exception message!", e.getMessage().contains("DLQ queue name")
&& e.getMessage().contains("length exceeds limit of 255"));
}
- finally
- {
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
- }
}
/**
@@ -372,11 +360,8 @@ public class AMQQueueFactoryTest extends QpidTestCase
try
{
// change DLQ name to make its length bigger than exchange name
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterExchangeSuffix", "_DLEXCHANGE");
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterQueueSuffix", "_DLQ");
-
+ setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, "_DLEXCHANGE");
+ setTestSystemProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, "_DLQ");
FieldTable fieldTable = new FieldTable();
fieldTable.setBoolean(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, "owner",
@@ -389,13 +374,6 @@ public class AMQQueueFactoryTest extends QpidTestCase
assertTrue("Unexpected exception message!", e.getMessage().contains("DL exchange name")
&& e.getMessage().contains("length exceeds limit of 255"));
}
- finally
- {
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX);
- ApplicationRegistry.getInstance().getConfiguration().getConfig()
- .addProperty("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX);
- }
}
private String generateStringWithLength(char ch, int length)
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 190d5c777b..cbbf183232 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,18 +32,16 @@ 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;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.ArrayList;
import java.util.Set;
@@ -51,7 +49,7 @@ import java.util.Set;
/**
* Tests that acknowledgements are handled correctly.
*/
-public class AckTest extends InternalBrokerBaseCase
+public class AckTest extends QpidTestCase
{
private Subscription _subscription;
@@ -70,15 +68,19 @@ public class AckTest extends InternalBrokerBaseCase
public void setUp() throws Exception
{
super.setUp();
- _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- _messageStore = new TestableMemoryMessageStore();
- _protocolSession = new InternalTestProtocolSession(_virtualHost);
- _channel = new AMQChannel(_protocolSession,5, _messageStore /*dont need exchange registry*/);
-
- _protocolSession.addChannel(_channel);
+ BrokerTestHelper.setUp();
+ _channel = BrokerTestHelper.createChannel(5);
+ _protocolSession = _channel.getProtocolSession();
+ _virtualHost = _protocolSession.getVirtualHost();
+ _queue = BrokerTestHelper.createQueue(getTestName(), _virtualHost);
+ _messageStore = (TestableMemoryMessageStore)_virtualHost.getMessageStore();
+ }
- _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), "myQ", false, "guest", true, false,
- _virtualHost, null);
+ @Override
+ protected void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
}
private void publishMessages(int count) throws AMQException
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.java
new file mode 100644
index 0000000000..2f160678ba
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/InboundMessageAdapterTest.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.queue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.message.AMQMessageHeader;
+import org.apache.qpid.server.message.ServerMessage;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class InboundMessageAdapterTest extends QpidTestCase
+{
+ private ServerMessage<?> _mockMessage;
+ private QueueEntry _mockQueueEntry;
+ private InboundMessageAdapter _inboundMessageAdapter;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _mockMessage = mock(ServerMessage.class);
+ _mockQueueEntry = mock(QueueEntry.class);
+ when(_mockQueueEntry.getMessage()).thenReturn(_mockMessage);
+
+ _inboundMessageAdapter = new InboundMessageAdapter(_mockQueueEntry);
+ }
+
+ public void testGetRoutingKey() throws Exception
+ {
+ String routingKey = getTestName();
+ when(_mockMessage.getRoutingKey()).thenReturn(routingKey);
+
+ assertEquals("Unexpected value for routing key", routingKey, _inboundMessageAdapter.getRoutingKey());
+ }
+
+ public void testGetRoutingKeyShortString() throws Exception
+ {
+ String routingKey = getTestName();
+ when(_mockMessage.getRoutingKey()).thenReturn(routingKey);
+
+ AMQShortString routingKeyShortString = AMQShortString.valueOf(routingKey);
+ assertEquals("Unexpected value for routing key short string", routingKeyShortString, _inboundMessageAdapter.getRoutingKeyShortString());
+ }
+
+ public void testGetMessageHeader() throws Exception
+ {
+ AMQMessageHeader mockMessageHeader = mock(AMQMessageHeader.class);
+ when(_mockQueueEntry.getMessageHeader()).thenReturn(mockMessageHeader);
+
+ assertSame("unexpected message header", mockMessageHeader, _inboundMessageAdapter.getMessageHeader());
+ }
+
+ public void testIsRedelivered() throws Exception
+ {
+ when(_mockQueueEntry.isRedelivered()).thenReturn(true);
+ assertTrue("unexpected isRedelivered value", _inboundMessageAdapter.isRedelivered());
+
+ when(_mockQueueEntry.isRedelivered()).thenReturn(false);
+ assertFalse("unexpected isRedelivered value", _inboundMessageAdapter.isRedelivered());
+ }
+
+ public void testIsPersistent() throws Exception
+ {
+ when(_mockQueueEntry.isPersistent()).thenReturn(true);
+ assertTrue("unexpected isPersistent value", _inboundMessageAdapter.isPersistent());
+
+ when(_mockQueueEntry.isPersistent()).thenReturn(false);
+ assertFalse("unexpected isPersistent value", _inboundMessageAdapter.isPersistent());
+ }
+
+ public void testGetSize() throws Exception
+ {
+ long size = 32526215;
+ when(_mockQueueEntry.getSize()).thenReturn(size);
+ assertEquals("unexpected getSize value", size, _inboundMessageAdapter.getSize());
+ }
+}
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 bcb8d54636..358246330a 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
@@ -23,10 +23,8 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.QueueConfigType;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.QueueConfiguration;
+import org.apache.qpid.server.configuration.plugins.AbstractConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.logging.LogSubject;
import org.apache.qpid.server.message.ServerMessage;
@@ -106,11 +104,6 @@ public class MockAMQQueue implements AMQQueue
return 0;
}
- public ConfigStore getConfigStore()
- {
- return getVirtualHost().getConfigStore();
- }
-
public long getMessageDequeueCount()
{
return 0;
@@ -186,22 +179,6 @@ public class MockAMQQueue implements AMQQueue
return null;
}
- @Override
- public UUID getQMFId()
- {
- return null;
- }
-
- public QueueConfigType getConfigType()
- {
- return null;
- }
-
- public ConfiguredObject getParent()
- {
- return null;
- }
-
public boolean isDurable()
{
return false;
@@ -532,16 +509,11 @@ public class MockAMQQueue implements AMQQueue
}
- public void configure(ConfigurationPlugin config)
+ public void configure(QueueConfiguration config)
{
}
- public ConfigurationPlugin getConfiguration()
- {
- return null;
- }
-
public AuthorizationHolder getAuthorizationHolder()
{
return _authorizationHolder;
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 2cd423d4c9..ece42f7de3 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
@@ -28,8 +28,6 @@ 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;
import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQSecurityException;
@@ -39,7 +37,6 @@ import org.apache.qpid.framing.BasicContentHeaderProperties;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
@@ -47,16 +44,15 @@ import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.queue.BaseQueue.PostEnqueueAction;
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.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.ArrayList;
import java.util.Collections;
@@ -64,17 +60,17 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-public class SimpleAMQQueueTest extends InternalBrokerBaseCase
+public class SimpleAMQQueueTest extends QpidTestCase
{
- protected SimpleAMQQueue _queue;
- protected VirtualHost _virtualHost;
- protected AMQShortString _qname = new AMQShortString("qname");
- protected AMQShortString _owner = new AMQShortString("owner");
- protected AMQShortString _routingKey = new AMQShortString("routing key");
- protected DirectExchange _exchange;
- protected MockSubscription _subscription = new MockSubscription();
- protected FieldTable _arguments = null;
+ private SimpleAMQQueue _queue;
+ private VirtualHost _virtualHost;
+ private AMQShortString _qname = new AMQShortString("qname");
+ private AMQShortString _owner = new AMQShortString("owner");
+ private AMQShortString _routingKey = new AMQShortString("routing key");
+ private DirectExchange _exchange;
+ private MockSubscription _subscription = new MockSubscription();
+ private FieldTable _arguments = null;
private MessagePublishInfo info = new MessagePublishInfo()
{
@@ -108,25 +104,29 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void setUp() throws Exception
{
super.setUp();
- //Create Application Registry for test
- ApplicationRegistry applicationRegistry = (ApplicationRegistry)ApplicationRegistry.getInstance();
+ BrokerTestHelper.setUp();
- PropertiesConfiguration env = new PropertiesConfiguration();
- final VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(getClass().getName(), env);
- vhostConfig.setMessageStoreClass(TestableMemoryMessageStore.class.getName());
- _virtualHost = new VirtualHostImpl(ApplicationRegistry.getInstance(), vhostConfig);
- applicationRegistry.getVirtualHostRegistry().registerVirtualHost(_virtualHost);
+ _virtualHost = BrokerTestHelper.createVirtualHost(getClass().getName());
- _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), _qname.asString(), false, _owner.asString(), false, false, _virtualHost, FieldTable.convertToMap(_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);
+ _exchange = (DirectExchange) _virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.DIRECT_EXCHANGE_NAME);
}
@Override
public void tearDown() throws Exception
{
- _queue.stop();
- super.tearDown();
+ try
+ {
+ _queue.stop();
+ _virtualHost.close();
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
public void testCreateQueue() throws AMQException
@@ -659,7 +659,7 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
public void onRollback()
{
}
- }, 0L);
+ });
// Check that it is enqueued
AMQQueue data = store.getMessages().get(1L);
@@ -1269,6 +1269,26 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
}
+ public SimpleAMQQueue getQueue()
+ {
+ return _queue;
+ }
+
+ public MockSubscription getSubscription()
+ {
+ return _subscription;
+ }
+
+ public FieldTable getArguments()
+ {
+ return _arguments;
+ }
+
+ public void setArguments(FieldTable arguments)
+ {
+ _arguments = arguments;
+ }
+
public class TestMessage extends AMQMessage
{
private final long _tag;
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 6b82cd361a..4abb7233dc 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
@@ -20,20 +20,33 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
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.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class SimpleAMQQueueThreadPoolTest extends InternalBrokerBaseCase
+public class SimpleAMQQueueThreadPoolTest extends QpidTestCase
{
- public void test() throws AMQException
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+
+ public void test() throws Exception
{
int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount();
- VirtualHost test = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
+ VirtualHost test = BrokerTestHelper.createVirtualHost("test");
try
{
@@ -50,7 +63,7 @@ public class SimpleAMQQueueThreadPoolTest extends InternalBrokerBaseCase
}
finally
{
- ApplicationRegistry.remove();
+ test.close();
}
}
}
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
deleted file mode 100644
index 9af950d385..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
+++ /dev/null
@@ -1,104 +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.registry;
-
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import java.security.Provider;
-import java.security.Security;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * QPID-1390 : Test to validate that the AuthenticationManger can successfully unregister any new SASL providers when
- * The ApplicationRegistry is closed.
- *
- * This should be expanded as QPID-1399 is implemented.
- */
-public class ApplicationRegistryShutdownTest extends InternalBrokerBaseCase
-{
-
- private Provider[] _defaultProviders;
- @Override
- public void setUp() throws Exception
- {
- // Get default providers
- _defaultProviders = Security.getProviders();
-
- //Startup the new broker and register the new providers
- super.setUp();
- }
-
-
- /**
- * QPID-1399 : Ensure that the Authentication manager unregisters any SASL providers created during
- * ApplicationRegistry initialisation.
- *
- */
- public void testAuthenticationMangerCleansUp() throws Exception
- {
-
- // Get the providers after initialisation
- Provider[] providersAfterInitialisation = Security.getProviders();
-
- // Find the additions
- List additions = new LinkedList();
- for (Provider afterInit : providersAfterInitialisation)
- {
- boolean found = false;
- for (Provider defaultProvider : _defaultProviders)
- {
- if (defaultProvider == afterInit)
- {
- found=true;
- break;
- }
- }
-
- // Record added registies
- if (!found)
- {
- additions.add(afterInit);
- }
- }
-
- assertFalse("No new SASL mechanisms added by initialisation.", additions.isEmpty());
-
- //Close the registry which will perform the close the AuthenticationManager
- stopBroker();
-
- //Validate that the SASL plugFins have been removed.
- Provider[] providersAfterClose = Security.getProviders();
-
- assertTrue("No providers unregistered", providersAfterInitialisation.length > providersAfterClose.length);
-
- //Ensure that the additions are not still present after close().
- for (Provider afterClose : providersAfterClose)
- {
- assertFalse("Added provider not unregistered", additions.contains(afterClose));
- }
- }
-
-
-
-
-
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
new file mode 100644
index 0000000000..b1bc9bea68
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import javax.security.auth.Subject;
+import javax.security.sasl.SaslServer;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.group.GroupPrincipalAccessor;
+
+public class SubjectCreatorTest extends TestCase
+{
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+
+ private AuthenticationManager _authenticationManager = mock(AuthenticationManager.class);
+ private GroupPrincipalAccessor _groupPrincipalAccessor = mock(GroupPrincipalAccessor.class);
+ private SubjectCreator _subjectCreator = new SubjectCreator(_authenticationManager, _groupPrincipalAccessor);
+
+ private Principal _userPrincipal = mock(Principal.class);
+ private Principal _group1 = mock(Principal.class);
+ private Principal _group2 = mock(Principal.class);
+
+ private AuthenticationResult _authenticationResult;
+ private SaslServer _testSaslServer = mock(SaslServer.class);
+ private byte[] _saslResponseBytes = PASSWORD.getBytes();
+
+ @Override
+ public void setUp()
+ {
+ _authenticationResult = new AuthenticationResult(_userPrincipal);
+ when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult);
+
+ when(_groupPrincipalAccessor.getGroupPrincipals(USERNAME))
+ .thenReturn(new HashSet<Principal>(Arrays.asList(_group1, _group2)));
+ }
+
+ public void testAuthenticateUsernameAndPasswordReturnsSubjectWithUserAndGroupPrincipals()
+ {
+ final SubjectAuthenticationResult actualResult = _subjectCreator.authenticate(USERNAME, PASSWORD);
+
+ assertEquals(AuthenticationStatus.SUCCESS, actualResult.getStatus());
+
+ final Subject actualSubject = actualResult.getSubject();
+
+ assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size());
+
+ assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal)));
+ assertTrue(actualSubject.getPrincipals().contains(_group1));
+ assertTrue(actualSubject.getPrincipals().contains(_group2));
+
+ assertTrue(actualSubject.isReadOnly());
+ }
+
+ public void testSaslAuthenticationSuccessReturnsSubjectWithUserAndGroupPrincipals() throws Exception
+ {
+ when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult);
+ when(_testSaslServer.isComplete()).thenReturn(true);
+ when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME);
+
+ SubjectAuthenticationResult result = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes);
+
+ final Subject actualSubject = result.getSubject();
+ assertEquals("Should contain one user principal and two groups ", 3, actualSubject.getPrincipals().size());
+
+ assertTrue(actualSubject.getPrincipals().contains(new AuthenticatedPrincipal(_userPrincipal)));
+ assertTrue(actualSubject.getPrincipals().contains(_group1));
+ assertTrue(actualSubject.getPrincipals().contains(_group2));
+
+ assertTrue(actualSubject.isReadOnly());
+ }
+
+ public void testAuthenticateUnsuccessfulWithUsernameReturnsNullSubjectAndCorrectStatus()
+ {
+ testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.CONTINUE);
+ testUnsuccessfulAuthentication(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+
+ private void testUnsuccessfulAuthentication(AuthenticationStatus expectedStatus)
+ {
+ AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus);
+
+ when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(failedAuthenticationResult);
+
+ SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(USERNAME, PASSWORD);
+
+ assertSame(expectedStatus, subjectAuthenticationResult.getStatus());
+ assertNull(subjectAuthenticationResult.getSubject());
+ }
+
+ public void testAuthenticateUnsuccessfulWithSaslServerReturnsNullSubjectAndCorrectStatus()
+ {
+ testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.CONTINUE);
+ testUnsuccessfulAuthenticationWithSaslServer(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+
+ private void testUnsuccessfulAuthenticationWithSaslServer(AuthenticationStatus expectedStatus)
+ {
+ AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus);
+
+ when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(failedAuthenticationResult);
+ when(_testSaslServer.isComplete()).thenReturn(false);
+
+ SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes);
+
+ assertSame(expectedStatus, subjectAuthenticationResult.getStatus());
+ assertNull(subjectAuthenticationResult.getSubject());
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java
new file mode 100644
index 0000000000..cd5791952f
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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;
+
+import java.security.Principal;
+
+import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+
+import junit.framework.TestCase;
+
+public class AuthenticatedPrincipalTest extends TestCase
+{
+
+ private AuthenticatedPrincipal _authenticatedPrincipal = new AuthenticatedPrincipal(new UsernamePrincipal("name"));
+
+ public void testGetAuthenticatedPrincipalFromSubject()
+ {
+ final Subject subject = createSubjectContainingAuthenticatedPrincipal();
+ final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ assertSame(_authenticatedPrincipal, actual);
+ }
+
+ public void testAuthenticatedPrincipalNotInSubject()
+ {
+ try
+ {
+ AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(new Subject());
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+ }
+
+ public void testGetOptionalAuthenticatedPrincipalFromSubject()
+ {
+ final Subject subject = createSubjectContainingAuthenticatedPrincipal();
+ final AuthenticatedPrincipal actual = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject);
+ assertSame(_authenticatedPrincipal, actual);
+ }
+
+ public void testGetOptionalAuthenticatedPrincipalFromSubjectReturnsNullIfMissing()
+ {
+ Subject subjectWithNoPrincipals = new Subject();
+ assertNull(AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithNoPrincipals));
+
+ Subject subjectWithoutAuthenticatedPrincipal = new Subject();
+ subjectWithoutAuthenticatedPrincipal.getPrincipals().add(new UsernamePrincipal("name1"));
+ assertNull("Should return null for a subject containing a principal that isn't an AuthenticatedPrincipal",
+ AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subjectWithoutAuthenticatedPrincipal));
+ }
+
+ public void testTooManyAuthenticatedPrincipalsInSubject()
+ {
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name1")));
+ subject.getPrincipals().add(new AuthenticatedPrincipal(new UsernamePrincipal("name2")));
+
+ try
+ {
+ AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(subject);
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException iae)
+ {
+ // PASS
+ }
+ }
+
+ private Subject createSubjectContainingAuthenticatedPrincipal()
+ {
+ final Principal other = new Principal()
+ {
+ public String getName()
+ {
+ return "otherprincipal";
+ }
+ };
+
+ final Subject subject = new Subject();
+ subject.getPrincipals().add(_authenticatedPrincipal);
+ subject.getPrincipals().add(other);
+ return subject;
+ }
+
+ public void testEqualsAndHashcode()
+ {
+ AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+ AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+
+ assertTrue(user1principal1.equals(user1principal1));
+ assertTrue(user1principal1.equals(user1principal2));
+ assertTrue(user1principal2.equals(user1principal1));
+
+ assertEquals(user1principal1.hashCode(), user1principal2.hashCode());
+ }
+
+ public void testEqualsAndHashcodeWithSameWrappedObject()
+ {
+ UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1");
+ AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(wrappedPrincipal);
+ AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(wrappedPrincipal);
+
+ assertTrue(user1principal1.equals(user1principal1));
+ assertTrue(user1principal1.equals(user1principal2));
+ assertTrue(user1principal2.equals(user1principal1));
+
+ assertEquals(user1principal1.hashCode(), user1principal2.hashCode());
+ }
+
+ public void testEqualsWithDifferentUsernames()
+ {
+ AuthenticatedPrincipal user1principal1 = new AuthenticatedPrincipal(new UsernamePrincipal("user1"));
+ AuthenticatedPrincipal user1principal2 = new AuthenticatedPrincipal(new UsernamePrincipal("user2"));
+
+ assertFalse(user1principal1.equals(user1principal2));
+ assertFalse(user1principal2.equals(user1principal1));
+ }
+
+ public void testEqualsWithDisimilarObjects()
+ {
+ UsernamePrincipal wrappedPrincipal = new UsernamePrincipal("user1");
+ AuthenticatedPrincipal authenticatedPrincipal = new AuthenticatedPrincipal(wrappedPrincipal);
+
+ assertFalse(authenticatedPrincipal.equals(wrappedPrincipal));
+ assertFalse(wrappedPrincipal.equals(authenticatedPrincipal));
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java
new file mode 100644
index 0000000000..e9d8d16fce
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipalTestHelper.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+/**
+ * Helper class for testing that sets of principals contain {@link AuthenticatedPrincipal}'s that wrap
+ * expected {@link Principal}'s.
+ */
+public class AuthenticatedPrincipalTestHelper
+{
+ public static void assertOnlyContainsWrapped(Principal wrappedPrincipal, Set<Principal> principals)
+ {
+ assertOnlyContainsWrappedAndSecondaryPrincipals(wrappedPrincipal, Collections.<Principal>emptySet(), principals);
+ }
+
+
+ public static void assertOnlyContainsWrappedAndSecondaryPrincipals(
+ Principal expectedWrappedPrincipal,
+ Set<Principal> expectedSecondaryPrincipals,
+ Set<Principal> actualPrincipals)
+ {
+ Assert.assertEquals("Principal set should contain one principal " + "but the principal set is: " + actualPrincipals,
+ 1 + expectedSecondaryPrincipals.size(),
+ actualPrincipals.size());
+
+ Set<Principal> expectedSet = new HashSet<Principal>(expectedSecondaryPrincipals);
+ expectedSet.add(new AuthenticatedPrincipal(expectedWrappedPrincipal));
+
+ Assert.assertEquals(expectedSet, actualPrincipals);
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java
new file mode 100644
index 0000000000..a023cbdbb2
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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;
+
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrappedAndSecondaryPrincipals;
+import static org.mockito.Mockito.mock;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+public class AuthenticationResultTest extends TestCase
+{
+ public void testConstructWithAuthenticationStatusContinue()
+ {
+ AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.CONTINUE);
+ assertSame(AuthenticationResult.AuthenticationStatus.CONTINUE, authenticationResult.getStatus());
+ assertTrue(authenticationResult.getPrincipals().isEmpty());
+ }
+
+ public void testConstructWithAuthenticationStatusError()
+ {
+ AuthenticationResult authenticationResult = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ assertSame(AuthenticationResult.AuthenticationStatus.ERROR, authenticationResult.getStatus());
+ assertTrue(authenticationResult.getPrincipals().isEmpty());
+ }
+
+ public void testConstructWithAuthenticationStatusSuccessThrowsException()
+ {
+ try
+ {
+ new AuthenticationResult(AuthenticationResult.AuthenticationStatus.SUCCESS);
+ fail("Exception not thrown");
+ }
+ catch(IllegalArgumentException e)
+ {
+ // PASS
+ }
+ }
+
+ public void testConstructWithPrincipal()
+ {
+ Principal mainPrincipal = mock(Principal.class);
+ AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal);
+
+ assertOnlyContainsWrapped(mainPrincipal, authenticationResult.getPrincipals());
+ assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+ }
+
+ public void testConstructWithNullPrincipalThrowsException()
+ {
+ try
+ {
+ new AuthenticationResult((Principal)null);
+ fail("Exception not thrown");
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+
+ public void testConstructWithSetOfPrincipals()
+ {
+ Principal mainPrincipal = mock(Principal.class);
+ Principal secondaryPrincipal = mock(Principal.class);
+ Set<Principal> secondaryPrincipals = Collections.singleton(secondaryPrincipal);
+
+ AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal, secondaryPrincipals);
+
+ assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, secondaryPrincipals, authenticationResult.getPrincipals());
+ assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+ }
+
+ public void testConstructWithSetOfPrincipalsDeDuplicatesMainPrincipal()
+ {
+ Principal mainPrincipal = mock(Principal.class);
+ Principal secondaryPrincipal = mock(Principal.class);
+
+ Set<Principal> secondaryPrincipalsContainingDuplicateOfMainPrincipal = new HashSet<Principal>(
+ Arrays.asList(secondaryPrincipal, mainPrincipal));
+ Set<Principal> deDuplicatedSecondaryPrincipals = Collections.singleton(secondaryPrincipal);
+
+ AuthenticationResult authenticationResult = new AuthenticationResult(
+ mainPrincipal, secondaryPrincipalsContainingDuplicateOfMainPrincipal);
+
+ assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, deDuplicatedSecondaryPrincipals, authenticationResult.getPrincipals());
+
+ assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java
index 7ce03eaa79..ea6b40e3de 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/TestPrincipalUtils.java
@@ -18,9 +18,12 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.auth;
import javax.security.auth.Subject;
+
+import org.apache.qpid.server.security.group.GroupPrincipal;
+
import java.security.Principal;
import java.util.Collections;
import java.util.HashSet;
@@ -28,21 +31,19 @@ import java.util.Set;
public class TestPrincipalUtils
{
-
/**
- * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals.
+ * Creates a test subject, with exactly one {@link AuthenticatedPrincipal} and zero or more GroupPrincipals.
*/
public static Subject createTestSubject(final String username, final String... groups)
{
final Set<Principal> principals = new HashSet<Principal>(1 + groups.length);
- principals.add(new UsernamePrincipal(username));
+ principals.add(new AuthenticatedPrincipal(username));
for (String group : groups)
{
principals.add(new GroupPrincipal(group));
}
-
- final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
- return subject;
+
+ return new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java
index 75bc76c688..5e025d3ca8 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/UsernamePrincipalTest.java
@@ -18,13 +18,10 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.auth;
import junit.framework.TestCase;
-import javax.security.auth.Subject;
-import java.security.Principal;
-
/**
* Tests the UsernamePrincipal.
*
@@ -70,54 +67,4 @@ public class UsernamePrincipalTest extends TestCase
UsernamePrincipal principal = new UsernamePrincipal("string");
assertFalse(principal.equals(null));
}
-
- public void testGetUsernamePrincipalFromSubject()
- {
- final UsernamePrincipal expected = new UsernamePrincipal("name");
- final Principal other = new Principal()
- {
- public String getName()
- {
- return "otherprincipal";
- }
- };
-
- final Subject subject = new Subject();
- subject.getPrincipals().add(expected);
- subject.getPrincipals().add(other);
-
- final UsernamePrincipal actual = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- assertSame(expected, actual);
- }
-
- public void testUsernamePrincipalNotInSubject()
- {
- try
- {
- UsernamePrincipal.getUsernamePrincipalFromSubject(new Subject());
- fail("Exception not thrown");
- }
- catch (IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- public void testTooManyUsernamePrincipalInSubject()
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal("name1"));
- subject.getPrincipals().add(new UsernamePrincipal("name2"));
- try
- {
-
- UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- fail("Exception not thrown");
- }
- catch (IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
index 33740af1e7..7b244e219e 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
@@ -23,7 +23,7 @@ package org.apache.qpid.server.security.auth.database;
import junit.framework.TestCase;
import org.apache.commons.codec.binary.Base64;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
index b8601f0e5c..8e62324f7d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
@@ -22,7 +22,7 @@ package org.apache.qpid.server.security.auth.database;
import junit.framework.TestCase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import javax.security.auth.login.AccountNotFoundException;
import java.io.BufferedReader;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
index 4203cb0e07..f670d80ae8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
@@ -21,14 +21,13 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.HashMap;
import java.util.LinkedList;
@@ -123,22 +122,6 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase
return equal;
}
- private char[] convertPassword(String password) throws UnsupportedEncodingException
- {
- byte[] passwdBytes = password.getBytes("utf-8");
-
- char[] passwd = new char[passwdBytes.length];
-
- int index = 0;
-
- for (byte b : passwdBytes)
- {
- passwd[index++] = (char) b;
- }
-
- return passwd;
- }
-
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
{
@@ -166,4 +149,10 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase
{
//No file to update from, so do nothing.
}
+
+ @Override
+ public void setPasswordFile(String passwordFile)
+ {
+ throw new UnsupportedOperationException();
+ }
}
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
index 9dcd22c088..cfeb7c525b 100644
--- 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
@@ -20,26 +20,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+
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;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase
+public class AnonymousAuthenticationManagerTest extends QpidTestCase
{
-
- private AuthenticationManager _manager = null;
-
- public void setUp() throws Exception
- {
- _manager = AnonymousAuthenticationManager.INSTANCE;
- }
-
+ private AuthenticationManager _manager = new AnonymousAuthenticationManager();
public void tearDown() throws Exception
{
@@ -49,29 +40,6 @@ public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase
}
}
- 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());
@@ -102,7 +70,8 @@ public class AnonymousAuthenticationManagerTest extends InternalBrokerBaseCase
assertEquals("Expected authentication to be successful",
AuthenticationResult.AuthenticationStatus.SUCCESS,
result.getStatus());
- assertNotNull("Subject should not be null", result.getSubject());
+
+ assertOnlyContainsWrapped(AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL, result.getPrincipals());
}
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
deleted file mode 100644
index efb8df3a38..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistryTest.java
+++ /dev/null
@@ -1,304 +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.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/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java
new file mode 100644
index 0000000000..04e09e073f
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+
+public class Base64MD5PasswordFileAuthenticationManagerFactoryTest extends TestCase
+{
+ AuthenticationManagerFactory _factory = new Base64MD5PasswordFileAuthenticationManagerFactory();
+ private Map<String, Object> _configuration = new HashMap<String, Object>();
+ private File _emptyPasswordFile;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _emptyPasswordFile = File.createTempFile(getName(), "passwd");
+ _emptyPasswordFile.deleteOnExit();
+ }
+
+ public void testBase64MD5InstanceCreated() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
+
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNotNull(manager);
+ assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager);
+ assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof Base64MD5PasswordFilePrincipalDatabase);
+ }
+
+ public void testPasswordFileNotFound() throws Exception
+ {
+ //delete the file
+ _emptyPasswordFile.delete();
+
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
+
+ try
+ {
+ _factory.createInstance(_configuration);
+ }
+ catch (RuntimeException re)
+ {
+ assertTrue(re.getCause() instanceof FileNotFoundException);
+ }
+ }
+
+ public void testReturnsNullWhenNoConfig() throws Exception
+ {
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager");
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ public void testReturnsNullWhenConfigForPlainPDImplementationNoPasswordFileValueSpecified() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ if (_emptyPasswordFile == null && _emptyPasswordFile.exists())
+ {
+ _emptyPasswordFile.delete();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+} \ No newline at end of file
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
index c1a55ef2ad..a66d73c47d 100644
--- 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
@@ -18,58 +18,18 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+
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;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ExternalAuthenticationManagerTest extends InternalBrokerBaseCase
+public class ExternalAuthenticationManagerTest extends QpidTestCase
{
-
- 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);
- }
+ private AuthenticationManager _manager = new ExternalAuthenticationManager();
public void testGetMechanisms() throws Exception
{
@@ -103,12 +63,12 @@ public class ExternalAuthenticationManagerTest extends InternalBrokerBaseCase
assertEquals("Expected authentication to be successful",
AuthenticationResult.AuthenticationStatus.SUCCESS,
result.getStatus());
- assertEquals("Expected principal to be unchanged",
- principal,
- result.getSubject().getPrincipals().iterator().next());
+
+ assertOnlyContainsWrapped(principal, result.getPrincipals());
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,
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java
new file mode 100644
index 0000000000..d428f8b211
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.File;
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
+
+public class PlainPasswordFileAuthenticationManagerFactoryTest extends TestCase
+{
+ AuthenticationManagerFactory _factory = new PlainPasswordFileAuthenticationManagerFactory();
+ private Map<String, Object> _configuration = new HashMap<String, Object>();
+ private File _emptyPasswordFile;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _emptyPasswordFile = File.createTempFile(getName(), "passwd");
+ _emptyPasswordFile.deleteOnExit();
+ }
+
+ public void testPlainInstanceCreated() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
+
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNotNull(manager);
+ assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager);
+ assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof PlainPasswordFilePrincipalDatabase);
+ }
+
+ public void testPasswordFileNotFound() throws Exception
+ {
+ //delete the file
+ _emptyPasswordFile.delete();
+
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
+
+ try
+ {
+ _factory.createInstance(_configuration);
+ }
+ catch (RuntimeException re)
+ {
+ assertTrue(re.getCause() instanceof FileNotFoundException);
+ }
+ }
+
+ public void testReturnsNullWhenNoConfig() throws Exception
+ {
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager");
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ public void testReturnsNullWhenConfigForPlainPDImplementationNoPasswordFileValueSpecified() throws Exception
+ {
+ _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ if (_emptyPasswordFile == null && _emptyPasswordFile.exists())
+ {
+ _emptyPasswordFile.delete();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+}
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 47c189e4fa..1ae667804a 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
@@ -20,132 +20,92 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
+import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-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.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
-import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.security.Provider;
-import java.security.Security;
+import javax.security.sasl.SaslServerFactory;
+
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.test.utils.QpidTestCase;
/**
- *
* Tests the public methods of PrincipalDatabaseAuthenticationManager.
*
*/
-public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBaseCase
+public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase
{
+ private static final String MOCK_MECH_NAME = "MOCK-MECH-NAME";
+ private static final UsernamePrincipal PRINCIPAL = new UsernamePrincipal("guest");
+
private AuthenticationManager _manager = null; // Class under test
- private String TEST_USERNAME = "guest";
- private String TEST_PASSWORD = "guest";
+ private PrincipalDatabase _principalDatabase;
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#tearDown()
- */
@Override
public void tearDown() throws Exception
{
- super.tearDown();
if (_manager != null)
{
_manager.close();
}
+ super.tearDown();
}
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#setUp()
- */
- @Override
- public void setUp() throws Exception
+ private void setupMocks() throws Exception
{
- super.setUp();
-
- final String passwdFilename = createPasswordFile().getCanonicalPath();
- final ConfigurationPlugin config = getConfig(PlainPasswordFilePrincipalDatabase.class.getName(),
- "passwordFile", passwdFilename);
+ _principalDatabase = mock(PrincipalDatabase.class);
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(config);
- }
+ AuthenticationProviderInitialiser _mockMechInitialiser = mock(AuthenticationProviderInitialiser.class);
+ Map<String, AuthenticationProviderInitialiser> _initialisers = Collections.singletonMap(MOCK_MECH_NAME, _mockMechInitialiser);
- /**
- * Tests where the case where the config specifies a PD implementation
- * that is not found.
- */
- public void testPrincipalDatabaseImplementationNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig("not.Found", null, null));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
+ when(_principalDatabase.getMechanisms()).thenReturn(_initialisers);
- /**
- * Tests where the case where the config specifies a PD implementation
- * of the wrong type.
- */
- public void testPrincipalDatabaseImplementationWrongType() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(String.class.getName(), null, null)); // Not a PrincipalDatabase implementation
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
+ _manager = new PrincipalDatabaseAuthenticationManager(_principalDatabase);
+ _manager.initialise();
}
- /**
- * Tests the case where a setter with the desired name cannot be found.
- */
- public void testPrincipalDatabaseSetterNotFound() throws Exception
+ private void setupMocksWithInitialiser() throws Exception
{
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "noMethod", "test"));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
+ _principalDatabase = mock(PrincipalDatabase.class);
- /**
- * QPID-1347. Make sure the exception message and stack trace is reasonable for an absent password file.
- */
- public void testPrincipalDatabaseThrowsSetterFileNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "passwordFile", "/not/found"));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
+ UsernamePasswordInitialiser usernamePasswordInitialiser = new UsernamePasswordInitialiser()
{
- // PASS
- assertNotNull("Expected an underlying cause", ce.getCause());
- assertEquals(FileNotFoundException.class, ce.getCause().getClass());
- }
+ @Override
+ public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
+ {
+ return MySaslServerFactory.class;
+ }
+
+ @Override
+ public String getMechanismName()
+ {
+ return MOCK_MECH_NAME;
+ }
+ };
+
+ Map<String,AuthenticationProviderInitialiser> initialisers = new HashMap<String, AuthenticationProviderInitialiser>();
+ initialisers.put(MOCK_MECH_NAME, usernamePasswordInitialiser);
+
+ when(_principalDatabase.getMechanisms()).thenReturn(initialisers);
+
+ usernamePasswordInitialiser.initialise(_principalDatabase);
+
+ _manager = new PrincipalDatabaseAuthenticationManager(_principalDatabase);
+ _manager.initialise();
}
/**
@@ -153,11 +113,16 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
*/
public void testRegisteredMechanisms() throws Exception
{
+ //Ensure we haven't registered anything yet (though this would really indicate a prior test failure!)
+ Provider qpidProvider = Security.getProvider(AuthenticationManager.PROVIDER_NAME);
+ assertNull(qpidProvider);
+
+ setupMocksWithInitialiser();
+
assertNotNull(_manager.getMechanisms());
- // relies on those mechanisms attached to PropertiesPrincipalDatabaseManager
- assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms());
+ assertEquals(MOCK_MECH_NAME, _manager.getMechanisms());
- Provider qpidProvider = Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME);
+ qpidProvider = Security.getProvider(AuthenticationManager.PROVIDER_NAME);
assertNotNull(qpidProvider);
}
@@ -167,96 +132,103 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
*/
public void testSaslMechanismCreation() throws Exception
{
- SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost", null);
+ setupMocksWithInitialiser();
+
+ SaslServer server = _manager.createSaslServer(MOCK_MECH_NAME, "localhost", null);
assertNotNull(server);
// Merely tests the creation of the mechanism. Mechanisms themselves are tested
// by their own tests.
}
-
+
/**
* Tests that the authenticate method correctly interprets an
* authentication success.
- *
+ *
*/
public void testSaslAuthenticationSuccess() throws Exception
{
+ setupMocks();
+
SaslServer testServer = createTestSaslServer(true, false);
-
+
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- final Subject subject = result.getSubject();
- assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
+
+ assertOnlyContainsWrapped(PRINCIPAL, result.getPrincipals());
assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
}
/**
- *
+ *
* Tests that the authenticate method correctly interprets an
* authentication not complete.
- *
+ *
*/
public void testSaslAuthenticationNotCompleted() throws Exception
{
+ setupMocks();
+
SaslServer testServer = createTestSaslServer(false, false);
-
+
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
+ assertEquals("Principals was not expected size", 0, result.getPrincipals().size());
+
assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
}
/**
- *
+ *
* Tests that the authenticate method correctly interprets an
* authentication error.
- *
+ *
*/
public void testSaslAuthenticationError() throws Exception
{
+ setupMocks();
+
SaslServer testServer = createTestSaslServer(false, true);
-
+
AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
+ assertEquals("Principals was not expected size", 0, result.getPrincipals().size());
assertEquals(AuthenticationStatus.ERROR, result.getStatus());
}
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
public void testNonSaslAuthenticationSuccess() throws Exception
{
+ setupMocks();
+
+ when(_principalDatabase.verifyPassword("guest", "guest".toCharArray())).thenReturn(true);
+
AuthenticationResult result = _manager.authenticate("guest", "guest");
- final Subject subject = result.getSubject();
- assertFalse("Subject should not be set read-only", subject.isReadOnly());
- assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
+ assertOnlyContainsWrapped(PRINCIPAL, result.getPrincipals());
assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
}
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
public void testNonSaslAuthenticationNotCompleted() throws Exception
{
+ setupMocks();
+
+ when(_principalDatabase.verifyPassword("guest", "wrongpassword".toCharArray())).thenReturn(false);
+
AuthenticationResult result = _manager.authenticate("guest", "wrongpassword");
- assertNull(result.getSubject());
+ assertEquals("Principals was not expected size", 0, result.getPrincipals().size());
assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
}
-
+
/**
* Tests the ability to de-register the provider.
*/
public void testClose() throws Exception
{
- assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms());
- assertNotNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME));
+ setupMocksWithInitialiser();
+
+ assertEquals(MOCK_MECH_NAME, _manager.getMechanisms());
+ assertNotNull(Security.getProvider(AuthenticationManager.PROVIDER_NAME));
_manager.close();
// Check provider has been removed.
assertNull(_manager.getMechanisms());
- assertNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME));
+ assertNull(Security.getProvider(AuthenticationManager.PROVIDER_NAME));
_manager = null;
}
@@ -265,94 +237,90 @@ public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBa
*/
private SaslServer createTestSaslServer(final boolean complete, final boolean throwSaslException)
{
- return new SaslServer()
- {
- public String getMechanismName()
- {
- return null;
- }
+ return new MySaslServer(throwSaslException, complete);
+ }
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- if (throwSaslException)
- {
- throw new SaslException("Mocked exception");
- }
- return null;
- }
+ public static final class MySaslServer implements SaslServer
+ {
+ private final boolean _throwSaslException;
+ private final boolean _complete;
- public boolean isComplete()
- {
- return complete;
- }
+ public MySaslServer()
+ {
+ this(false, true);
+ }
- public String getAuthorizationID()
- {
- return complete ? "guest" : null;
- }
+ private MySaslServer(boolean throwSaslException, boolean complete)
+ {
+ _throwSaslException = throwSaslException;
+ _complete = complete;
+ }
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- return null;
- }
+ public String getMechanismName()
+ {
+ return null;
+ }
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ public byte[] evaluateResponse(byte[] response) throws SaslException
+ {
+ if (_throwSaslException)
{
- return null;
+ throw new SaslException("Mocked exception");
}
+ return null;
+ }
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
+ public boolean isComplete()
+ {
+ return _complete;
+ }
- public void dispose() throws SaslException
- {
- }
- };
- }
+ public String getAuthorizationID()
+ {
+ return _complete ? "guest" : null;
+ }
- private ConfigurationPlugin getConfig(final String clazz, final String argName, final String argValue) throws Exception
- {
- final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration();
+ public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
+ {
+ return null;
+ }
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("pd-auth-manager.principal-database.class", clazz);
+ public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
+ {
+ return null;
+ }
- if (argName != null)
+ public Object getNegotiatedProperty(String propName)
{
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.name", argName);
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.value", argValue);
+ return null;
}
- // 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 dispose() throws SaslException
+ {
+ }
}
- private File createPasswordFile() throws Exception
+ public static class MySaslServerFactory implements SaslServerFactory
{
- BufferedWriter writer = null;
- try
- {
- File testFile = File.createTempFile(this.getClass().getName(),"tmp");
- testFile.deleteOnExit();
-
- writer = new BufferedWriter(new FileWriter(testFile));
- writer.write(TEST_USERNAME + ":" + TEST_PASSWORD);
- writer.newLine();
-
- return testFile;
-
- }
- finally
+ @Override
+ public SaslServer createSaslServer(String mechanism, String protocol,
+ String serverName, Map<String, ?> props, CallbackHandler cbh)
+ throws SaslException
{
- if (writer != null)
+ if (MOCK_MECH_NAME.equals(mechanism))
{
- writer.close();
+ return new MySaslServer();
}
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public String[] getMechanismNames(Map<String, ?> props)
+ {
+ return new String[]{MOCK_MECH_NAME};
}
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java
new file mode 100644
index 0000000000..1424bee611
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+
+import junit.framework.TestCase;
+
+public class SimpleLDAPAuthenticationManagerFactoryTest extends TestCase
+{
+ private SimpleLDAPAuthenticationManagerFactory _factory = new SimpleLDAPAuthenticationManagerFactory();
+ private Map<String, Object> _configuration = new HashMap<String, Object>();
+
+ public void testInstanceCreated() throws Exception
+ {
+ _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE);
+ _configuration.put("providerUrl", "ldaps://example.com:636/");
+ _configuration.put("searchContext", "dc=example");
+
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNotNull(manager);
+ }
+
+ public void testReturnsNullWhenNoConfig() throws Exception
+ {
+ AuthenticationManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+}
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 c0c55de92a..52b525dd80 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,20 +20,26 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.security.Principal;
+import java.util.regex.Pattern;
+
+import javax.security.auth.Subject;
+
import junit.framework.TestCase;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.SubjectCreator;
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 javax.management.remote.JMXPrincipal;
-import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import java.net.InetSocketAddress;
-import java.util.Collections;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.SecurityManager;
/**
* Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager.
@@ -41,36 +47,35 @@ import java.util.Collections;
*/
public class RMIPasswordAuthenticatorTest extends TestCase
{
- private final String USERNAME = "guest";
- private final String PASSWORD = "guest";
+ private static final String USERNAME = "guest";
+ private static final String PASSWORD = "password";
+
+ private final Broker _broker = mock(Broker.class);
+ private final SecurityManager _securityManager = mock(SecurityManager.class);
+ private final Subject _loginSubject = new Subject();
+ private final String[] _credentials = new String[] {USERNAME, PASSWORD};
+
private RMIPasswordAuthenticator _rmipa;
- private String[] _credentials;
+
+ private SubjectCreator _usernamePasswordOkaySuvjectCreator = createMockSubjectCreator(true, null);
+ private SubjectCreator _badPasswordSubjectCreator = createMockSubjectCreator(false, null);
protected void setUp() throws Exception
{
- _rmipa = new RMIPasswordAuthenticator(new InetSocketAddress(5672));
-
- _credentials = new String[] {USERNAME, PASSWORD};
+ when(_broker.getSecurityManager()).thenReturn(_securityManager);
+ _rmipa = new RMIPasswordAuthenticator(_broker, new InetSocketAddress(8999));
}
/**
- * Tests a successful authentication. Ensures that a populated read-only subject it returned.
+ * Tests a successful authentication. Ensures that the expected subject is returned.
*/
public void testAuthenticationSuccess()
{
- final Subject expectedSubject = new Subject(true,
- Collections.singleton(new JMXPrincipal(USERNAME)),
- Collections.EMPTY_SET,
- Collections.EMPTY_SET);
-
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(true, null));
-
+ when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySuvjectCreator);
+ when(_securityManager.accessManagement()).thenReturn(true);
Subject newSubject = _rmipa.authenticate(_credentials);
- assertTrue("Subject must be readonly", newSubject.isReadOnly());
- assertTrue("Returned subject does not equal expected value",
- newSubject.equals(expectedSubject));
-
+ assertSame("Subject must be unchanged", _loginSubject, newSubject);
}
/**
@@ -78,7 +83,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
*/
public void testUsernameOrPasswordInvalid()
{
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null));
+ when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_badPasswordSubjectCreator);
try
{
@@ -89,17 +94,31 @@ public class RMIPasswordAuthenticatorTest extends TestCase
{
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ }
+ }
+
+ public void testAuthorisationFailure()
+ {
+ when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySuvjectCreator);
+ when(_securityManager.accessManagement()).thenReturn(false);
+ try
+ {
+ _rmipa.authenticate(_credentials);
+ fail("Exception not thrown");
+ }
+ catch (SecurityException se)
+ {
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.USER_NOT_AUTHORISED_FOR_MANAGEMENT, se.getMessage());
}
}
- /**
- * Tests case where authentication system itself fails.
- */
- public void testAuthenticationFailure()
+ public void testSubjectCreatorInternalFailure()
{
final Exception mockAuthException = new Exception("Mock Auth system failure");
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, mockAuthException));
+ SubjectCreator subjectCreator = createMockSubjectCreator(false, mockAuthException);
+ when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator);
try
{
@@ -112,13 +131,13 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
-
/**
* Tests case where authentication manager is not set.
*/
- public void testNullAuthenticationManager() throws Exception
+ public void testNullSubjectCreator() throws Exception
{
- _rmipa.setAuthenticationManager(null);
+ when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(null);
+
try
{
_rmipa.authenticate(_credentials);
@@ -126,8 +145,7 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
catch (SecurityException se)
{
- assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
+ assertTrue("Unexpected exception message", Pattern.matches("Can't get subject creator for .*:8999", se.getMessage()));
}
}
@@ -155,11 +173,13 @@ public class RMIPasswordAuthenticatorTest extends TestCase
*/
public void testWithIllegalNumberOfArguments()
{
+ String[] credentials;
+
// Test handling of incorrect number of credentials
try
{
- _credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
+ _rmipa.authenticate(credentials);
fail("SecurityException expected due to supplying wrong number of credentials");
}
catch (SecurityException se)
@@ -172,8 +192,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null array
- _credentials = null;
- _rmipa.authenticate(_credentials);
+ credentials = null;
+ _rmipa.authenticate(credentials);
fail("SecurityException expected due to not supplying an array of credentials");
}
catch (SecurityException se)
@@ -185,8 +205,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null password
- _credentials = new String[]{USERNAME, null};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, null};
+ _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null password");
}
catch (SecurityException se)
@@ -198,8 +218,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null username
- _credentials = new String[]{null, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{null, PASSWORD};
+ _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null username");
}
catch (SecurityException se)
@@ -209,55 +229,30 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
- private AuthenticationManager createTestAuthenticationManager(final boolean successfulAuth, final Exception exception)
+ private SubjectCreator createMockSubjectCreator(final boolean successfulAuth, final Exception exception)
{
- return new AuthenticationManager()
+ SubjectCreator subjectCreator = mock(SubjectCreator.class);
+
+ SubjectAuthenticationResult subjectAuthenticationResult;
+
+ if (exception != null) {
+
+ subjectAuthenticationResult = new SubjectAuthenticationResult(
+ new AuthenticationResult(AuthenticationStatus.ERROR, exception));
+ }
+ else if (successfulAuth)
{
- public void configure(ConfigurationPlugin config)
- {
- throw new UnsupportedOperationException();
- }
-
- public void initialise()
- {
- throw new UnsupportedOperationException();
- }
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public String getMechanisms()
- {
- throw new UnsupportedOperationException();
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException
- {
- throw new UnsupportedOperationException();
- }
-
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- throw new UnsupportedOperationException();
- }
-
- public AuthenticationResult authenticate(String username, String password)
- {
- if (exception != null) {
- return new AuthenticationResult(AuthenticationStatus.ERROR, exception);
- }
- else if (successfulAuth)
- {
- return new AuthenticationResult(new Subject());
- }
- else
- {
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
- }
-
- };
+
+ subjectAuthenticationResult = new SubjectAuthenticationResult(
+ new AuthenticationResult(mock(Principal.class)), _loginSubject);
+ }
+ else
+ {
+ subjectAuthenticationResult = new SubjectAuthenticationResult(new AuthenticationResult(AuthenticationStatus.CONTINUE));
+ }
+
+ when(subjectCreator.authenticate(anyString(), anyString())).thenReturn(subjectAuthenticationResult);
+
+ return subjectCreator;
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java b/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java
index 8c7f3ad6ef..f94d8ddfc3 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java
@@ -86,4 +86,10 @@ public class TestPrincipalDatabase implements PrincipalDatabase
// TODO Auto-generated method stub
}
+ @Override
+ public void setPasswordFile(String passwordFile) throws IOException
+ {
+ // TODO Auto-generated method stub
+ }
+
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java
new file mode 100644
index 0000000000..b020c1655a
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupDatabaseTest.java
@@ -0,0 +1,456 @@
+/*
+ * 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.group;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.qpid.server.security.group.FileGroupDatabase;
+
+import junit.framework.TestCase;
+
+public class FileGroupDatabaseTest extends TestCase
+{
+ private static final String USER1 = "user1";
+ private static final String USER2 = "user2";
+ private static final String USER3 = "user3";
+
+ private static final String MY_GROUP = "myGroup";
+ private static final String MY_GROUP2 = "myGroup2";
+ private static final String MY_GROUP1 = "myGroup1";
+
+ private FileGroupDatabase _groupDatabase = new FileGroupDatabase();
+ private String _groupFile;
+
+ public void testGetAllGroups() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", USER1);
+
+ Set<String> groups = _groupDatabase.getAllGroups();
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP));
+ }
+
+ public void testGetAllGroupsWhenGroupFileEmpty() throws Exception
+ {
+ _groupDatabase.setGroupFile(_groupFile);
+
+ Set<String> groups = _groupDatabase.getAllGroups();
+ assertEquals(0, groups.size());
+ }
+
+ public void testMissingGroupFile() throws Exception
+ {
+ try
+ {
+ _groupDatabase.setGroupFile("/not/a/file");
+ fail("Exception not thrown");
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ // PASS
+ }
+ }
+
+ public void testInvalidFormat() throws Exception
+ {
+ writeGroupFile("name.notvalid", USER1);
+
+ try
+ {
+ _groupDatabase.setGroupFile(_groupFile);
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException gde)
+ {
+ // PASS
+ }
+ }
+
+ public void testGetUsersInGroup() throws Exception
+ {
+ writeGroupFile("myGroup.users", "user1,user2,user3");
+
+ _groupDatabase.setGroupFile(_groupFile);
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(3, users.size());
+ }
+
+ public void testDuplicateUsersInGroupAreConflated() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user1,user3,user1");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(2, users.size());
+ }
+
+ public void testGetUsersWithEmptyGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertTrue(users.isEmpty());
+ }
+
+ public void testGetUsersInNonExistentGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2,user3");
+
+ Set<String> users = _groupDatabase.getUsersInGroup("groupDoesntExist");
+ assertNotNull(users);
+ assertTrue(users.isEmpty());
+ }
+
+ public void testGetUsersInNullGroup() throws Exception
+ {
+ writeAndSetGroupFile();
+ assertTrue(_groupDatabase.getUsersInGroup(null).isEmpty());
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserBelongsToOneGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP));
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserBelongsToTwoGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup1.users", "user1,user2",
+ "myGroup2.users", "user1,user3");
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(2, groups.size());
+ assertTrue(groups.contains(MY_GROUP1));
+ assertTrue(groups.contains(MY_GROUP2));
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserAddedToGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup1.users", "user1,user2",
+ "myGroup2.users", USER2);
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP1));
+
+ _groupDatabase.addUserToGroup(USER1, MY_GROUP2);
+
+ groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(2, groups.size());
+ assertTrue(groups.contains(MY_GROUP1));
+ assertTrue(groups.contains(MY_GROUP2));
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP2);
+ assertEquals(2, users.size());
+ assertTrue(users.contains(USER1));
+ assertTrue(users.contains(USER2));
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserRemovedFromGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup1.users", "user1,user2",
+ "myGroup2.users", "user1,user2");
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(2, groups.size());
+ assertTrue(groups.contains(MY_GROUP1));
+ assertTrue(groups.contains(MY_GROUP2));
+
+ _groupDatabase.removeUserFromGroup(USER1, MY_GROUP2);
+
+ groups = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP1));
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserAdddedToGroupTheyAreAlreadyIn() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", USER1);
+ _groupDatabase.addUserToGroup(USER1, MY_GROUP);
+
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER1);
+
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP));
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertEquals(1, users.size());
+ assertTrue(users.contains(USER1));
+ }
+
+ public void testGetGroupPrincipalsForUserWhenUserNotKnown() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+ Set<String> groups = _groupDatabase.getGroupsForUser(USER3);
+ assertEquals(0, groups.size());
+ }
+
+ public void testGetGroupPrincipalsForNullUser() throws Exception
+ {
+ writeAndSetGroupFile();
+ assertTrue(_groupDatabase.getGroupsForUser(null).isEmpty());
+ }
+
+ public void testAddUserToExistingGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(2, users.size());
+
+ _groupDatabase.addUserToGroup(USER3, MY_GROUP);
+
+ users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(3, users.size());
+ }
+
+ public void testAddUserToEmptyGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(0, users.size());
+
+ _groupDatabase.addUserToGroup(USER3, MY_GROUP);
+
+ users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(1, users.size());
+ }
+
+ public void testAddUserToNonExistentGroup() throws Exception
+ {
+ writeAndSetGroupFile();
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(0, users.size());
+
+ try
+ {
+ _groupDatabase.addUserToGroup(USER3, MY_GROUP);
+ fail("Expected exception not thrown");
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+
+ users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(0, users.size());
+ }
+
+ public void testRemoveUserFromExistingGroup() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(2, users.size());
+
+ _groupDatabase.removeUserFromGroup(USER2, MY_GROUP);
+
+ users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertNotNull(users);
+ assertEquals(1, users.size());
+ }
+
+ public void testRemoveUserFromNonexistentGroup() throws Exception
+ {
+ writeAndSetGroupFile();
+
+ try
+ {
+ _groupDatabase.removeUserFromGroup(USER1, MY_GROUP);
+ fail("Expected exception not thrown");
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+
+ assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty());
+ }
+
+ public void testRemoveUserFromGroupTwice() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", USER1);
+ assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).contains(USER1));
+
+ _groupDatabase.removeUserFromGroup(USER1, MY_GROUP);
+ assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty());
+
+ _groupDatabase.removeUserFromGroup(USER1, MY_GROUP);
+ assertTrue(_groupDatabase.getUsersInGroup(MY_GROUP).isEmpty());
+ }
+
+ public void testAddUserPersistedToFile() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertEquals(2, users.size());
+
+ _groupDatabase.addUserToGroup(USER3, MY_GROUP);
+ assertEquals(3, users.size());
+
+ FileGroupDatabase newGroupDatabase = new FileGroupDatabase();
+ newGroupDatabase.setGroupFile(_groupFile);
+
+ Set<String> newUsers = newGroupDatabase.getUsersInGroup(MY_GROUP);
+ assertEquals(users.size(), newUsers.size());
+ }
+
+ public void testRemoveUserPersistedToFile() throws Exception
+ {
+ writeAndSetGroupFile("myGroup.users", "user1,user2");
+
+ Set<String> users = _groupDatabase.getUsersInGroup(MY_GROUP);
+ assertEquals(2, users.size());
+
+ _groupDatabase.removeUserFromGroup(USER2, MY_GROUP);
+ assertEquals(1, users.size());
+
+ FileGroupDatabase newGroupDatabase = new FileGroupDatabase();
+ newGroupDatabase.setGroupFile(_groupFile);
+
+ Set<String> newUsers = newGroupDatabase.getUsersInGroup(MY_GROUP);
+ assertEquals(users.size(), newUsers.size());
+ }
+
+ public void testCreateGroupPersistedToFile() throws Exception
+ {
+ writeAndSetGroupFile();
+
+ Set<String> groups = _groupDatabase.getAllGroups();
+ assertEquals(0, groups.size());
+
+ _groupDatabase.createGroup(MY_GROUP);
+
+ groups = _groupDatabase.getAllGroups();
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP));
+
+ FileGroupDatabase newGroupDatabase = new FileGroupDatabase();
+ newGroupDatabase.setGroupFile(_groupFile);
+
+ Set<String> newGroups = newGroupDatabase.getAllGroups();
+ assertEquals(1, newGroups.size());
+ assertTrue(newGroups.contains(MY_GROUP));
+ }
+
+ public void testRemoveGroupPersistedToFile() throws Exception
+ {
+ writeAndSetGroupFile("myGroup1.users", "user1,user2",
+ "myGroup2.users", "user1,user2");
+
+ Set<String> groups = _groupDatabase.getAllGroups();
+ assertEquals(2, groups.size());
+
+ Set<String> groupsForUser1 = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(2, groupsForUser1.size());
+
+ _groupDatabase.removeGroup(MY_GROUP1);
+
+ groups = _groupDatabase.getAllGroups();
+ assertEquals(1, groups.size());
+ assertTrue(groups.contains(MY_GROUP2));
+
+ groupsForUser1 = _groupDatabase.getGroupsForUser(USER1);
+ assertEquals(1, groupsForUser1.size());
+
+ FileGroupDatabase newGroupDatabase = new FileGroupDatabase();
+ newGroupDatabase.setGroupFile(_groupFile);
+
+ Set<String> newGroups = newGroupDatabase.getAllGroups();
+ assertEquals(1, newGroups.size());
+ assertTrue(newGroups.contains(MY_GROUP2));
+
+ Set<String> newGroupsForUser1 = newGroupDatabase.getGroupsForUser(USER1);
+ assertEquals(1, newGroupsForUser1.size());
+ assertTrue(newGroupsForUser1.contains(MY_GROUP2));
+}
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _groupFile = createEmptyTestGroupFile();
+ }
+
+ private void writeAndSetGroupFile(String... groupAndUsers) throws Exception
+ {
+ writeGroupFile(groupAndUsers);
+ _groupDatabase.setGroupFile(_groupFile);
+ }
+
+ private void writeGroupFile(String... groupAndUsers) throws Exception
+ {
+ if (groupAndUsers.length % 2 != 0)
+ {
+ throw new IllegalArgumentException("Number of groupAndUsers must be even");
+ }
+
+ Properties props = new Properties();
+ for (int i = 0 ; i < groupAndUsers.length; i=i+2)
+ {
+ String group = groupAndUsers[i];
+ String users = groupAndUsers[i+1];
+ props.put(group, users);
+ }
+
+ props.store(new FileOutputStream(_groupFile), "test group file");
+ }
+
+ private String createEmptyTestGroupFile() throws IOException
+ {
+ File tmpGroupFile = File.createTempFile("groups", "grp");
+ tmpGroupFile.deleteOnExit();
+
+ return tmpGroupFile.getAbsolutePath();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_groupFile != null)
+ {
+ File groupFile = new File(_groupFile);
+ if (groupFile.exists())
+ {
+ groupFile.delete();
+ }
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java
new file mode 100644
index 0000000000..934c0082ea
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerFactoryTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.group;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+public class FileGroupManagerFactoryTest extends TestCase
+{
+
+ private FileGroupManagerFactory _factory = new FileGroupManagerFactory();
+ private Map<String, Object> _configuration = new HashMap<String, Object>();
+ private String _emptyButValidGroupFile = TestFileUtils.createTempFile(this).getAbsolutePath();
+
+ public void testInstanceCreated() throws Exception
+ {
+ _configuration.put(GroupProvider.TYPE, FileGroupManagerFactory.FILE_GROUP_MANAGER_TYPE);
+ _configuration.put(FileGroupManagerFactory.FILE, _emptyButValidGroupFile);
+
+ GroupManager manager = _factory.createInstance(_configuration);
+ assertNotNull(manager);
+ assertTrue(manager instanceof FileGroupManager);
+ }
+
+ public void testReturnsNullWhenNoConfig() throws Exception
+ {
+ GroupManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+ public void testReturnsNullWhenConfigNotForThisPlugin() throws Exception
+ {
+ _configuration.put(GroupProvider.TYPE, "other-group-manager");
+
+ GroupManager manager = _factory.createInstance(_configuration);
+ assertNull(manager);
+ }
+
+
+ public void testRejectsConfigThatIsMissingAttributeValue() throws Exception
+ {
+ _configuration.put(GroupProvider.TYPE, FileGroupManagerFactory.FILE_GROUP_MANAGER_TYPE);
+ _configuration.put(FileGroupManagerFactory.FILE, null);
+
+ try
+ {
+ _factory.createInstance(_configuration);
+ fail("Exception not thrown");
+ }
+ catch (RuntimeException re)
+ {
+ // PASS
+ }
+ }
+
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java
new file mode 100644
index 0000000000..b83d25b206
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/FileGroupManagerTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.group;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.security.Principal;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class FileGroupManagerTest extends QpidTestCase
+{
+ private static final String MYGROUP_USERS = "user1";
+ private static final String MY_GROUP = "myGroup.users";
+ private static final String MY_GROUP2 = "myGroup2.users";
+ private File _tmpGroupFile;
+ private FileGroupManager _manager;
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_tmpGroupFile != null)
+ {
+ if (_tmpGroupFile.exists())
+ {
+ _tmpGroupFile.delete();
+ }
+ }
+ }
+
+ public void testValidGroupFile() throws Exception
+ {
+ final String groupFileName = writeGroupFile();
+
+ _manager = new FileGroupManager(groupFileName);
+ assertNotNull(_manager);
+ }
+
+ public void testNonExistentGroupFile() throws Exception
+ {
+ final String filePath = "/does.not.exist/";
+
+ try
+ {
+ _manager = new FileGroupManager(filePath);
+ fail("expected exception was not thrown");
+ }
+ catch(IllegalConfigurationException ce)
+ {
+ assertNotNull(ce.getCause());
+ assertTrue(ce.getCause() instanceof FileNotFoundException);
+ }
+ }
+
+ public void testGetGroupPrincipalsForUser() throws Exception
+ {
+ final String groupFileName = writeGroupFile();
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getGroupPrincipalsForUser("user1");
+ assertEquals(1, principals.size());
+ assertTrue(principals.contains(new GroupPrincipal("myGroup")));
+ }
+
+ public void testGetUserPrincipalsForGroup() throws Exception
+ {
+ final String groupFileName = writeGroupFile();
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup");
+ assertEquals(1, principals.size());
+ assertTrue(principals.contains(new UsernamePrincipal("user1")));
+ }
+
+ public void testGetGroupPrincipals() throws Exception
+ {
+ final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS, MY_GROUP2, MYGROUP_USERS);
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getGroupPrincipals();
+ assertEquals(2, principals.size());
+ assertTrue(principals.contains(new GroupPrincipal("myGroup")));
+ assertTrue(principals.contains(new GroupPrincipal("myGroup2")));
+ }
+
+ public void testCreateGroup() throws Exception
+ {
+ final String groupFileName = writeGroupFile();
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getGroupPrincipals();
+ assertEquals(1, principals.size());
+
+ _manager.createGroup("myGroup2");
+
+ principals = _manager.getGroupPrincipals();
+ assertEquals(2, principals.size());
+ assertTrue(principals.contains(new GroupPrincipal("myGroup2")));
+ }
+
+ public void testRemoveGroup() throws Exception
+ {
+ final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS);
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getGroupPrincipals();
+ assertEquals(1, principals.size());
+
+ _manager.removeGroup("myGroup");
+
+ principals = _manager.getGroupPrincipals();
+ assertEquals(0, principals.size());
+ }
+
+ public void testAddUserToGroup() throws Exception
+ {
+ final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS);
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup");
+ assertEquals(1, principals.size());
+ assertFalse(principals.contains(new UsernamePrincipal("user2")));
+
+ _manager.addUserToGroup("user2", "myGroup");
+
+ principals = _manager.getUserPrincipalsForGroup("myGroup");
+ assertEquals(2, principals.size());
+ assertTrue(principals.contains(new UsernamePrincipal("user2")));
+ }
+
+ public void testRemoveUserInGroup() throws Exception
+ {
+ final String groupFileName = writeGroupFile(MY_GROUP, MYGROUP_USERS);
+ _manager = new FileGroupManager(groupFileName);
+
+ Set<Principal> principals = _manager.getUserPrincipalsForGroup("myGroup");
+ assertEquals(1, principals.size());
+ assertTrue(principals.contains(new UsernamePrincipal("user1")));
+
+ _manager.removeUserFromGroup("user1", "myGroup");
+
+ principals = _manager.getUserPrincipalsForGroup("myGroup");
+ assertEquals(0, principals.size());
+ }
+
+ private String writeGroupFile() throws Exception
+ {
+ return writeGroupFile(MY_GROUP, MYGROUP_USERS);
+ }
+
+ private String writeGroupFile(String... groupAndUsers) throws Exception
+ {
+ if (groupAndUsers.length % 2 != 0)
+ {
+ throw new IllegalArgumentException("Number of groupAndUsers must be even");
+ }
+
+ _tmpGroupFile = File.createTempFile("groups", "grp");
+ _tmpGroupFile.deleteOnExit();
+
+ Properties props = new Properties();
+ for (int i = 0 ; i < groupAndUsers.length; i=i+2)
+ {
+ String group = groupAndUsers[i];
+ String users = groupAndUsers[i+1];
+ props.put(group, users);
+ }
+
+ props.store(new FileOutputStream(_tmpGroupFile), "test group file");
+
+ return _tmpGroupFile.getCanonicalPath();
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.java
new file mode 100644
index 0000000000..e58a1a01f8
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalAccessorTest.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.security.group;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.server.model.GroupProvider;
+
+public class GroupPrincipalAccessorTest extends TestCase
+{
+ private static final String USERNAME = "username";
+
+ private GroupProvider _groupManager1 = mock(GroupProvider.class);
+ private GroupProvider _groupManager2 = mock(GroupProvider.class);
+
+ private Principal _group1 = mock(Principal.class);
+ private Principal _group2 = mock(Principal.class);
+
+ @Override
+ public void setUp()
+ {
+ when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1));
+ when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2));
+ }
+
+ public void testGetGroupPrincipals()
+ {
+ getAndAssertGroupPrincipals(_group1, _group2);
+ }
+
+ public void testGetGroupPrincipalsWhenAGroupManagerReturnsNull()
+ {
+ when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(null);
+
+ getAndAssertGroupPrincipals(_group2);
+ }
+
+ public void testGetGroupPrincipalsWhenAGroupManagerReturnsEmptySet()
+ {
+ when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(new HashSet<Principal>());
+
+ getAndAssertGroupPrincipals(_group1);
+ }
+
+ private void getAndAssertGroupPrincipals(Principal... expectedGroups)
+ {
+ GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(Arrays.asList(_groupManager1, _groupManager2));
+
+ Set<Principal> actualGroupPrincipals = groupPrincipalAccessor.getGroupPrincipals(USERNAME);
+
+ Set<Principal> expectedGroupPrincipals = new HashSet<Principal>(Arrays.asList(expectedGroups));
+
+ assertEquals(expectedGroupPrincipals, actualGroupPrincipals);
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalTest.java
index 076b7c9248..d285a0797a 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/security/group/GroupPrincipalTest.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,7 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.sasl;
+package org.apache.qpid.server.security.group;
+
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
import junit.framework.TestCase;
@@ -34,7 +36,7 @@ public class GroupPrincipalTest extends TestCase
{
final GroupPrincipal principal = new GroupPrincipal("group");
final UsernamePrincipal user = new UsernamePrincipal("name");
-
+
try
{
principal.addMember(user);
@@ -45,7 +47,7 @@ public class GroupPrincipalTest extends TestCase
// PASS
}
}
-
+
public void testEqualitySameName()
{
final String string = "string";
@@ -80,7 +82,7 @@ public class GroupPrincipalTest extends TestCase
assertFalse(principal.equals(null));
}
-
+
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java b/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java
deleted file mode 100644
index 23ee82eae6..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/signal/SignalHandlerTaskTest.java
+++ /dev/null
@@ -1,119 +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.signal;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.lang.management.ManagementFactory;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class SignalHandlerTaskTest extends QpidTestCase
-{
- private static final Logger LOGGER = Logger.getLogger(SignalHandlerTaskTest.class);
- private static final String SUN_MISC_SIGNAL_CLASS = "sun.misc.Signal";
- private static final String SUN_MISC_SIGNAL_HANDLER_CLASS = "sun.misc.SignalHandler";
-
- protected void setUp() throws Exception
- {
- super.setUp();
- }
-
- public void testSignalHandlerTask() throws Exception
- {
- final boolean expectedResult = classifyExpectedRegistrationResult();
- final int pid = getPID();
- final CountDownLatch latch = new CountDownLatch(1);
-
- SignalHandlerTask hupReparseTask = new SignalHandlerTask()
- {
- public void handle()
- {
- latch.countDown();
- LOGGER.info("Signal handled, latch decremented");
- }
- };
-
- assertEquals("Unexpected result trying to register Signal handler",
- expectedResult, hupReparseTask.register("HUP"));
- LOGGER.info("Signal handler was registered");
-
- assertEquals("unexpected count for the latch", 1, latch.getCount());
-
- if(expectedResult)
- {
- //registration succeeded as expected, so now
- //send SIGHUP and verify the handler was run
- String cmd = "/bin/kill -SIGHUP " + pid;
-
- LOGGER.info("Sending SIGHUP");
- Runtime.getRuntime().exec(cmd);
-
- assertTrue("HUP Signal was not handled in the allowed timeframe",
- latch.await(5, TimeUnit.SECONDS));
- }
- }
-
- public void testGetPlatformDescription() throws Exception
- {
- assertNotNull(SignalHandlerTask.getPlatformDescription());
- }
-
- private boolean classifyExpectedRegistrationResult()
- {
- String os = System.getProperty("os.name");
- if(String.valueOf(os).toLowerCase().contains("windows"))
- {
- //Windows does not support SIGHUP so registration will fail
- LOGGER.info("Running on windows, so we expect SIGHUP handler registration to fail");
- return false;
- }
-
- //otherwise, if the signal handler classes are present we would expect
- //registration to succeed
- boolean classesPresent = true;
- try
- {
- Class.forName(SUN_MISC_SIGNAL_CLASS);
- Class.forName(SUN_MISC_SIGNAL_HANDLER_CLASS);
- LOGGER.info("Signal handling classes were present so we expect SIGHUP handler registration to succeed");
- }
- catch (ClassNotFoundException cnfe)
- {
- classesPresent = false;
- }
-
- return classesPresent;
- }
-
- private int getPID()
- {
- String processName = ManagementFactory.getRuntimeMXBean().getName();
-
- int pid = Integer.parseInt(processName.substring(0,processName.indexOf('@')));
- LOGGER.info("PID was determined to be " + pid);
-
- return pid;
- }
-
-}
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 cd8d91d835..f0ecfb6407 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
@@ -51,10 +51,6 @@ import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.model.UUIDGenerator;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockStoredMessage;
-import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.MessageStoreRecoveryHandler;
-import org.apache.qpid.server.store.TransactionLogRecoveryHandler;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BindingRecoveryHandler;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.ExchangeRecoveryHandler;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler.QueueRecoveryHandler;
@@ -76,7 +72,6 @@ public class DurableConfigurationStoreTest extends QpidTestCase
private QueueRecoveryHandler _queueRecoveryHandler;
private ExchangeRecoveryHandler _exchangeRecoveryHandler;
private BindingRecoveryHandler _bindingRecoveryHandler;
- private ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler _linkRecoveryHandler;
private MessageStoreRecoveryHandler _messageStoreRecoveryHandler;
private StoredMessageRecoveryHandler _storedMessageRecoveryHandler;
private TransactionLogRecoveryHandler _logRecoveryHandler;
@@ -116,7 +111,6 @@ public class DurableConfigurationStoreTest extends QpidTestCase
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);
when(_exchange.getNameShortString()).thenReturn(AMQShortString.valueOf(EXCHANGE_NAME));
@@ -161,7 +155,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase
public void testBindQueue() throws Exception
{
AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false);
- Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue,
+ Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), ROUTING_KEY, queue,
_exchange, FieldTable.convertToMap(_bindingArgs));
_store.bindQueue(binding);
@@ -175,7 +169,7 @@ public class DurableConfigurationStoreTest extends QpidTestCase
public void testUnbindQueue() throws Exception
{
AMQQueue queue = createTestQueue(QUEUE_NAME, "queueOwner", false);
- Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), null, ROUTING_KEY, queue,
+ Binding binding = new Binding(UUIDGenerator.generateRandomUUID(), ROUTING_KEY, queue,
_exchange, FieldTable.convertToMap(_bindingArgs));
_store.bindQueue(binding);
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreCreatorTest.java
index fefdecb8d7..e74937dd1c 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreCreatorTest.java
@@ -18,27 +18,22 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.server.store;
-import java.util.List;
+import org.apache.qpid.server.store.derby.DerbyMessageStore;
+import org.apache.qpid.test.utils.QpidTestCase;
-public abstract class QMFObjectClass<T extends QMFObject, S extends QMFObject.Delegate> extends QMFClass
+public class MessageStoreCreatorTest extends QpidTestCase
{
- public QMFObjectClass(String name,
- byte[] schemaHash,
- List<QMFProperty> properties,
- List<QMFStatistic> statistics, List<QMFMethod> methods)
- {
- super(QMFClass.Type.OBJECT, name, schemaHash, properties, statistics, methods);
- }
+ private static final String[] STORE_TYPES = {MemoryMessageStore.TYPE, DerbyMessageStore.TYPE};
- public QMFObjectClass(String name, byte[] schemaHash)
+ public void testMessageStoreCreator()
{
- super(QMFClass.Type.OBJECT, name, schemaHash);
+ MessageStoreCreator messageStoreCreator = new MessageStoreCreator();
+ for (String type : STORE_TYPES)
+ {
+ MessageStore store = messageStoreCreator.createMessageStore(type);
+ assertNotNull("Store of type " + type + " is not created", store);
+ }
}
-
-
- public abstract T newInstance(S delegate);
-
-
}
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 a1536565ad..ffd777243b 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
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.store;
+
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.AMQException;
@@ -35,11 +36,12 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.exchange.TopicExchange;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.plugin.ExchangeType;
import org.apache.qpid.server.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -48,11 +50,11 @@ import org.apache.qpid.server.queue.ConflationQueue;
import org.apache.qpid.server.queue.IncomingMessage;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.queue.SimpleAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.util.FileUtils;
import java.io.File;
@@ -66,7 +68,7 @@ import java.util.Map;
* For persistent stores, it validates that Exchanges, Queues, Bindings and
* Messages are persisted and recovered correctly.
*/
-public class MessageStoreTest extends InternalBrokerBaseCase
+public class MessageStoreTest extends QpidTestCase
{
public static final int DEFAULT_PRIORTY_LEVEL = 5;
public static final String SELECTOR_VALUE = "Test = 'MST'";
@@ -93,11 +95,15 @@ public class MessageStoreTest extends InternalBrokerBaseCase
private AMQShortString queueOwner = new AMQShortString("MST");
- protected PropertiesConfiguration _config;
+ private PropertiesConfiguration _config;
+
+ private VirtualHost _virtualHost;
+ private Broker _broker;
public void setUp() throws Exception
{
super.setUp();
+ BrokerTestHelper.setUp();
String storePath = System.getProperty("QPID_WORK") + File.separator + getName();
@@ -107,9 +113,38 @@ public class MessageStoreTest extends InternalBrokerBaseCase
cleanup(new File(storePath));
+ _broker = BrokerTestHelper.createBrokerMock();
+
reloadVirtualHost();
}
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_virtualHost != null)
+ {
+ _virtualHost.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return _virtualHost;
+ }
+
+ public PropertiesConfiguration getConfig()
+ {
+ return _config;
+ }
+
protected void reloadVirtualHost()
{
VirtualHost original = getVirtualHost();
@@ -119,8 +154,6 @@ public class MessageStoreTest extends InternalBrokerBaseCase
try
{
getVirtualHost().close();
- getVirtualHost().getApplicationRegistry().
- getVirtualHostRegistry().unregisterVirtualHost(getVirtualHost());
}
catch (Exception e)
{
@@ -131,7 +164,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
try
{
- setVirtualHost(ApplicationRegistry.getInstance().createVirtualHost(new VirtualHostConfiguration(getClass().getName(), _config)));
+ _virtualHost = BrokerTestHelper.createVirtualHost(new VirtualHostConfiguration(getClass().getName(), _config, _broker));
}
catch (Exception e)
{
@@ -628,7 +661,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
{
//To change body of implemented methods use File | Settings | File Templates.
}
- }, 0L);
+ });
}
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java b/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
index 4aa023a25c..7c6891da71 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
@@ -27,6 +27,7 @@ import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
+import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.test.utils.QpidTestCase;
/**
@@ -86,10 +87,12 @@ public class ReferenceCountingTest extends QpidTestCase
AMQMessage message = new AMQMessage(storedMessage);
- message.incrementReference();
+ MessageReference ref = message.newReference();
assertEquals(1, _store.getMessageCount());
- message.decrementReference();
+
+ ref.release();
+
assertEquals(0, _store.getMessageCount());
}
@@ -142,13 +145,13 @@ public class ReferenceCountingTest extends QpidTestCase
AMQMessage message = new AMQMessage(storedMessage);
- message.incrementReference();
+ MessageReference ref = message.newReference();
// we call routing complete to set up the handle
// message.routingComplete(_store, _storeContext, new MessageHandleFactory());
assertEquals(1, _store.getMessageCount());
- message.incrementReference();
- message.decrementReference();
+ MessageReference ref2 = message.newReference();
+ ref.release();
assertEquals(1, _store.getMessageCount());
}
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 8c5d2684ff..a3552639d1 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
@@ -294,17 +294,12 @@ public class MockSubscription implements Subscription
private static class MockSessionModel implements AMQSessionModel
{
+ private final UUID _id = UUID.randomUUID();
@Override
- public int compareTo(AMQSessionModel o)
- {
- return 0;
- }
-
- @Override
- public UUID getQMFId()
+ public UUID getId()
{
- return null;
+ return _id;
}
@Override
@@ -409,6 +404,12 @@ public class MockSubscription implements Subscription
{
return 0;
}
+
+ @Override
+ public int compareTo(AMQSessionModel o)
+ {
+ return getId().compareTo(o.getId());
+ }
}
private static class MockConnectionModel implements AMQConnectionModel
diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java
index 3272bd5447..d35a90e3c8 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/subscription/QueueBrowserUsesNoAckTest.java
@@ -21,14 +21,75 @@
package org.apache.qpid.server.subscription;
import org.apache.qpid.AMQException;
+import org.apache.qpid.common.AMQPFilterTypes;
+import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import java.util.List;
-public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase
+public class QueueBrowserUsesNoAckTest extends QpidTestCase
{
+ private AMQChannel _channel;
+ private SimpleAMQQueue _queue;
+ private MessageStore _messageStore;
+ private String _queueName;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _channel = BrokerTestHelper.createChannel();
+ VirtualHost virtualHost = _channel.getVirtualHost();
+ _queueName = getTestName();
+ _queue = BrokerTestHelper.createQueue(_queueName, virtualHost);
+ _messageStore = virtualHost.getMessageStore();
+ Exchange defaultExchange = virtualHost.getExchangeRegistry().getDefaultExchange();
+ virtualHost.getBindingFactory().addBinding(_queueName, _queue, defaultExchange, null);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_channel != null)
+ {
+ _channel.getVirtualHost().close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
+ private AMQChannel getChannel()
+ {
+ return _channel;
+ }
+
+ private InternalTestProtocolSession getSession()
+ {
+ return (InternalTestProtocolSession)_channel.getProtocolSession();
+ }
+
+ private SimpleAMQQueue getQueue()
+ {
+ return _queue;
+ }
public void testQueueBrowserUsesNoAck() throws AMQException
{
@@ -39,7 +100,7 @@ public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase
checkStoreContents(0);
//Send required messsages to the queue
- publishMessages(getSession(), getChannel(), sendMessageCount);
+ BrokerTestHelper.publishMessages(getChannel(), sendMessageCount, _queueName, ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString());
//Ensure they are stored
checkStoreContents(sendMessageCount);
@@ -74,4 +135,16 @@ public class QueueBrowserUsesNoAckTest extends InternalBrokerBaseCase
.equals(Subscription.State.SUSPENDED));
}
+ private void checkStoreContents(int messageCount)
+ {
+ assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount());
+ }
+
+ private AMQShortString browse(AMQChannel channel, AMQQueue queue) throws AMQException
+ {
+ FieldTable filters = new FieldTable();
+ filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true);
+
+ return channel.subscribeToQueue(null, queue, true, filters, false, true);
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java b/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java
index 29f45bf7f4..89d434e95d 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionFactoryImplTest.java
@@ -23,20 +23,55 @@ package org.apache.qpid.server.subscription;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.flow.WindowCreditManager;
+import org.apache.qpid.server.logging.UnitTestMessageLogger;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.ProtocolEngine_0_10;
import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.server.transport.ServerSession;
import org.apache.qpid.server.transport.ServerSessionDelegate;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.transport.Binary;
import org.apache.qpid.transport.MessageAcceptMode;
import org.apache.qpid.transport.MessageAcquireMode;
import org.apache.qpid.transport.MessageFlowMode;
import org.apache.qpid.transport.TestNetworkConnection;
-public class SubscriptionFactoryImplTest extends InternalBrokerBaseCase
+public class SubscriptionFactoryImplTest extends QpidTestCase
{
+ private AMQChannel _channel;
+ private AMQProtocolSession _session;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ _channel = BrokerTestHelper.createChannel();
+ _session = _channel.getProtocolSession();
+ GenericActor.setDefaultMessageLogger(new UnitTestMessageLogger(false));
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_channel != null)
+ {
+ _channel.getVirtualHost().close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
+ }
+
/**
* Tests that while creating Subscriptions of various types, the
* ID numbers assigned are allocated from a common sequence
@@ -46,35 +81,34 @@ public class SubscriptionFactoryImplTest extends InternalBrokerBaseCase
{
//create a No-Ack subscription, get the first Subscription ID
long previousId = 0;
- Subscription noAckSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), false, null, false, getChannel().getCreditManager());
+ Subscription noAckSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), false, null, false, _channel.getCreditManager());
previousId = noAckSub.getSubscriptionID();
//create an ack subscription, verify the next Subscription ID is used
- Subscription ackSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), true, null, false, getChannel().getCreditManager());
+ Subscription ackSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), true, null, false, _channel.getCreditManager());
assertEquals("Unexpected Subscription ID allocated", previousId + 1, ackSub.getSubscriptionID());
previousId = ackSub.getSubscriptionID();
//create a browser subscription
FieldTable filters = new FieldTable();
filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true);
- Subscription browerSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, getSession(), new AMQShortString("1"), true, null, false, getChannel().getCreditManager());
+ Subscription browerSub = SubscriptionFactoryImpl.INSTANCE.createSubscription(1, _session, new AMQShortString("1"), true, null, false, _channel.getCreditManager());
assertEquals("Unexpected Subscription ID allocated", previousId + 1, browerSub.getSubscriptionID());
previousId = browerSub.getSubscriptionID();
//create an BasicGet NoAck subscription
- Subscription getNoAckSub = SubscriptionFactoryImpl.INSTANCE.createBasicGetNoAckSubscription(getChannel(), getSession(), new AMQShortString("1"), null, false,
- getChannel().getCreditManager(),getChannel().getClientDeliveryMethod(), getChannel().getRecordDeliveryMethod());
+ Subscription getNoAckSub = SubscriptionFactoryImpl.INSTANCE.createBasicGetNoAckSubscription(_channel, _session, new AMQShortString("1"), null, false,
+ _channel.getCreditManager(),_channel.getClientDeliveryMethod(), _channel.getRecordDeliveryMethod());
assertEquals("Unexpected Subscription ID allocated", previousId + 1, getNoAckSub.getSubscriptionID());
previousId = getNoAckSub.getSubscriptionID();
//create a 0-10 subscription
ServerConnection conn = new ServerConnection(1);
- ProtocolEngine_0_10 engine = new ProtocolEngine_0_10(conn, new TestNetworkConnection(), getRegistry());
- conn.setVirtualHost(getVirtualHost());
- conn.setConnectionConfig(engine);
+ ProtocolEngine_0_10 engine = new ProtocolEngine_0_10(conn, new TestNetworkConnection());
+ conn.setVirtualHost(_session.getVirtualHost());
ServerSessionDelegate sesDel = new ServerSessionDelegate();
Binary name = new Binary(new byte[]{new Byte("1")});
- ServerSession session = new ServerSession(conn, sesDel, name, 0, engine);
+ ServerSession session = new ServerSession(conn, sesDel, name, 0);
Subscription sub_0_10 = SubscriptionFactoryImpl.INSTANCE.createSubscription(session, "1", MessageAcceptMode.EXPLICIT,
MessageAcquireMode.PRE_ACQUIRED, MessageFlowMode.WINDOW, new WindowCreditManager(), null, null);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java b/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java
index d775b0f2f8..3389773ff8 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,19 +15,17 @@
* 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 java.util.UUID;
-
-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.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.transport.Binary;
-public class ServerSessionTest extends InternalBrokerBaseCase
+public class ServerSessionTest extends QpidTestCase
{
private VirtualHost _virtualHost;
@@ -37,31 +34,44 @@ public class ServerSessionTest extends InternalBrokerBaseCase
public void setUp() throws Exception
{
super.setUp();
- _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts().iterator().next();
+ BrokerTestHelper.setUp();
+ _virtualHost = BrokerTestHelper.createVirtualHost(getName());
+ GenericActor.setDefaultMessageLogger(CurrentActor.get().getRootMessageLogger());
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_virtualHost != null)
+ {
+ _virtualHost.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
}
public void testCompareTo() throws Exception
{
ServerConnection connection = new ServerConnection(1);
- connection.setConnectionConfig(createConnectionConfig());
+ connection.setVirtualHost(_virtualHost);
ServerSession session1 = new ServerSession(connection, new ServerSessionDelegate(),
- new Binary(getName().getBytes()), 0 , connection.getConfig());
+ new Binary(getName().getBytes()), 0);
// create a session with the same name but on a different connection
ServerConnection connection2 = new ServerConnection(2);
- connection2.setConnectionConfig(createConnectionConfig());
+ connection2.setVirtualHost(_virtualHost);
ServerSession session2 = new ServerSession(connection2, new ServerSessionDelegate(),
- new Binary(getName().getBytes()), 0 , connection2.getConfig());
+ new Binary(getName().getBytes()), 0);
assertFalse("Unexpected compare result", session1.compareTo(session2) == 0);
assertEquals("Unexpected compare result", 0, session1.compareTo(session1));
}
- private MockConnectionConfig createConnectionConfig()
- {
- return new MockConnectionConfig(UUID.randomUUID(), null, null,
- false, 1, _virtualHost, "address", Boolean.TRUE, Boolean.TRUE, Boolean.TRUE,
- "authid", "remoteProcessName", new Integer(1967), new Integer(1970), _virtualHost.getConfigStore(), Boolean.FALSE);
- }
}
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
index 1aa91fa98a..5c1012d50b 100644
--- 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
@@ -82,7 +82,7 @@ public class AsyncAutoCommitTransactionTest extends QpidTestCase
AsyncAutoCommitTransaction asyncAutoCommitTransaction =
new AsyncAutoCommitTransaction(_messageStore, _futureRecorder);
- asyncAutoCommitTransaction.enqueue(Collections.singletonList(_queue), _message, _postTransactionAction, System.currentTimeMillis());
+ asyncAutoCommitTransaction.enqueue(Collections.singletonList(_queue), _message, _postTransactionAction);
verify(_storeTransaction).enqueueMessage(_queue, _message);
verify(_futureRecorder).recordFuture(_future, _postTransactionAction);
diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
index cd3fe3c473..06b8539eb1 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/txn/AutoCommitTransactionTest.java
@@ -137,7 +137,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(false);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action, 0L);
+ _transaction.enqueue(_queues, _message, _action);
assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -157,7 +157,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action, 0L);
+ _transaction.enqueue(_queues, _message, _action);
assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -175,7 +175,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, true, false, true});
- _transaction.enqueue(_queues, _message, _action, 0L);
+ _transaction.enqueue(_queues, _message, _action);
assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.COMMITTED, _storeTransaction.getState());
@@ -198,7 +198,7 @@ public class AutoCommitTransactionTest extends QpidTestCase
try
{
- _transaction.enqueue(_queues, _message, _action, 0L);
+ _transaction.enqueue(_queues, _message, _action);
fail("Exception not thrown");
}
catch (RuntimeException re)
diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java b/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
index 5992829f37..4904cbc6fb 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/txn/LocalTransactionTest.java
@@ -140,7 +140,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(false);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action1, 0L);
+ _transaction.enqueue(_queues, _message, _action1);
assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -156,7 +156,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, false, false});
- _transaction.enqueue(_queues, _message, _action1, 0L);
+ _transaction.enqueue(_queues, _message, _action1);
assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
@@ -173,7 +173,7 @@ public class LocalTransactionTest extends QpidTestCase
_message = createTestMessage(true);
_queues = createTestBaseQueues(new boolean[] {false, true, false, true});
- _transaction.enqueue(_queues, _message, _action1, 0L);
+ _transaction.enqueue(_queues, _message, _action1);
assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages());
assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
@@ -196,7 +196,7 @@ public class LocalTransactionTest extends QpidTestCase
try
{
- _transaction.enqueue(_queues, _message, _action1, 0L);
+ _transaction.enqueue(_queues, _message, _action1);
fail("Exception not thrown");
}
catch (RuntimeException re)
@@ -217,7 +217,7 @@ public class LocalTransactionTest extends QpidTestCase
{
_message = createTestMessage(false);
_queue = createTestAMQQueue(false);
-
+
_transaction.dequeue(_queue, _message, _action1);
assertEquals("Dequeue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
@@ -465,7 +465,6 @@ public class LocalTransactionTest extends QpidTestCase
*/
public void testRollbackWorkWithAdditionalPostAction() throws Exception
{
-
_message = createTestMessage(true);
_queue = createTestAMQQueue(true);
@@ -482,6 +481,122 @@ public class LocalTransactionTest extends QpidTestCase
assertTrue("Rollback action2 must be fired", _action1.isRollbackActionFired());
}
+ public void testFirstEnqueueRecordsTransactionStartAndUpdateTime() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ long startTime = System.currentTimeMillis();
+ _transaction.enqueue(_queue, _message, _action1);
+
+ assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime);
+ assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime());
+ }
+
+ public void testSubsequentEnqueueAdvancesTransactionUpdateTimeOnly() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ _transaction.enqueue(_queue, _message, _action1);
+
+ final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime();
+ final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime();
+
+ Thread.sleep(1);
+ _transaction.enqueue(_queue, _message, _action2);
+
+ final long transactionStartTimeAfterSecondEnqueue = _transaction.getTransactionStartTime();
+ final long transactionUpdateTimeAfterSecondEnqueue = _transaction.getTransactionUpdateTime();
+
+ assertEquals("Transaction start time after second enqueue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterSecondEnqueue);
+ assertTrue("Transaction update time after second enqueue should be greater than first update time", transactionUpdateTimeAfterSecondEnqueue > transactionUpdateTimeAfterFirstEnqueue);
+ }
+
+ public void testFirstDequeueRecordsTransactionStartAndUpdateTime() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ long startTime = System.currentTimeMillis();
+ _transaction.dequeue(_queue, _message, _action1);
+
+ assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime);
+ assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime());
+ }
+
+ public void testMixedEnqueuesAndDequeuesAdvancesTransactionUpdateTimeOnly() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ _transaction.enqueue(_queue, _message, _action1);
+
+ final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime();
+ final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime();
+
+ Thread.sleep(1);
+ _transaction.dequeue(_queue, _message, _action2);
+
+ final long transactionStartTimeAfterFirstDequeue = _transaction.getTransactionStartTime();
+ final long transactionUpdateTimeAfterFirstDequeue = _transaction.getTransactionUpdateTime();
+
+ assertEquals("Transaction start time after first dequeue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterFirstDequeue);
+ assertTrue("Transaction update time after first dequeue should be greater than first update time", transactionUpdateTimeAfterFirstDequeue > transactionUpdateTimeAfterFirstEnqueue);
+ }
+
+ public void testCommitResetsTransactionStartAndUpdateTime() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ long startTime = System.currentTimeMillis();
+ _transaction.enqueue(_queue, _message, _action1);
+
+ assertTrue(_transaction.getTransactionStartTime() >= startTime);
+ assertTrue(_transaction.getTransactionUpdateTime() >= startTime);
+
+ _transaction.commit();
+
+ assertEquals("Transaction start time should be reset after commit", 0, _transaction.getTransactionStartTime());
+ assertEquals("Transaction update time should be reset after commit", 0, _transaction.getTransactionUpdateTime());
+ }
+
+ public void testRollbackResetsTransactionStartAndUpdateTime() throws Exception
+ {
+ assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
+ assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());
+
+ _message = createTestMessage(true);
+ _queue = createTestAMQQueue(true);
+
+ long startTime = System.currentTimeMillis();
+ _transaction.enqueue(_queue, _message, _action1);
+
+ assertTrue(_transaction.getTransactionStartTime() >= startTime);
+ assertTrue(_transaction.getTransactionUpdateTime() >= startTime);
+
+ _transaction.rollback();
+
+ assertEquals("Transaction start time should be reset after rollback", 0, _transaction.getTransactionStartTime());
+ assertEquals("Transaction update time should be reset after rollback", 0, _transaction.getTransactionUpdateTime());
+ }
+
private Collection<QueueEntry> createTestQueueEntries(boolean[] queueDurableFlags, boolean[] messagePersistentFlags)
{
Collection<QueueEntry> queueEntries = new ArrayList<QueueEntry>();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java b/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
index f3b6cab626..aa5b555b3b 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
@@ -22,7 +22,6 @@ package org.apache.qpid.server.txn;
import org.apache.commons.lang.NotImplementedException;
-import org.apache.qpid.server.configuration.SessionConfig;
import org.apache.qpid.server.message.AMQMessageHeader;
import org.apache.qpid.server.message.MessageReference;
import org.apache.qpid.server.message.ServerMessage;
@@ -68,11 +67,6 @@ class MockServerMessage implements ServerMessage
throw new NotImplementedException();
}
- public SessionConfig getSessionConfig()
- {
- throw new NotImplementedException();
- }
-
public String getRoutingKey()
{
throw new NotImplementedException();
diff --git a/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java
new file mode 100644
index 0000000000..3be8927224
--- /dev/null
+++ b/java/broker/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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.util;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.UUID;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+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.MessagePublishInfo;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore;
+import org.apache.qpid.server.exchange.DefaultExchangeFactory;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.SystemOutMessageLogger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.server.logging.actors.TestLogActor;
+import org.apache.qpid.server.model.Broker;
+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.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.SimpleAMQQueue;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostImpl;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+public class BrokerTestHelper
+{
+
+ protected static final String BROKER_STORE_CLASS_NAME_KEY = "brokerstore.class.name";
+ protected static final String JSON_BROKER_STORE_CLASS_NAME = JsonConfigurationEntryStore.class.getName();
+
+ public static Broker createBrokerMock()
+ {
+ SubjectCreator subjectCreator = mock(SubjectCreator.class);
+ when(subjectCreator.getMechanisms()).thenReturn("");
+ Broker broker = mock(Broker.class);
+ when(broker.getAttribute(Broker.SESSION_COUNT_LIMIT)).thenReturn(1);
+ when(broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).thenReturn(10000l);
+ when(broker.getId()).thenReturn(UUID.randomUUID());
+ when(broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator);
+ RootMessageLogger rootMessageLogger = CurrentActor.get().getRootMessageLogger();
+ when(broker.getRootMessageLogger()).thenReturn(rootMessageLogger);
+ when(broker.getVirtualHostRegistry()).thenReturn(new VirtualHostRegistry());
+ when(broker.getSecurityManager()).thenReturn(new SecurityManager(null));
+ GenericActor.setDefaultMessageLogger(rootMessageLogger);
+ return broker;
+ }
+
+ public static void setUp()
+ {
+ CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
+ }
+
+ public static void tearDown()
+ {
+ CurrentActor.remove();
+ }
+
+ public static VirtualHost createVirtualHost(VirtualHostConfiguration virtualHostConfiguration, VirtualHostRegistry virtualHostRegistry)
+ throws Exception
+ {
+ StatisticsGatherer statisticsGatherer = mock(StatisticsGatherer.class);
+ VirtualHost host = new VirtualHostImpl(virtualHostRegistry, statisticsGatherer, new SecurityManager(null), virtualHostConfiguration);
+ virtualHostRegistry.registerVirtualHost(host);
+ return host;
+ }
+
+ public static VirtualHost createVirtualHost(VirtualHostConfiguration virtualHostConfiguration) throws Exception
+ {
+ return new VirtualHostImpl(null, mock(StatisticsGatherer.class), new SecurityManager(null), virtualHostConfiguration);
+ }
+
+ public static VirtualHost createVirtualHost(String name, VirtualHostRegistry virtualHostRegistry) throws Exception
+ {
+ VirtualHostConfiguration vhostConfig = createVirtualHostConfiguration(name);
+ return createVirtualHost(vhostConfig, virtualHostRegistry);
+ }
+
+ public static VirtualHost createVirtualHost(String name) throws Exception
+ {
+ VirtualHostConfiguration configuration = createVirtualHostConfiguration(name);
+ return createVirtualHost(configuration);
+ }
+
+ private static VirtualHostConfiguration createVirtualHostConfiguration(String name) throws ConfigurationException
+ {
+ VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(name, new PropertiesConfiguration(), createBrokerMock());
+ vhostConfig.setMessageStoreClass(TestableMemoryMessageStore.class.getName());
+ return vhostConfig;
+ }
+
+ public static AMQChannel createChannel(int channelId, AMQProtocolSession session) throws AMQException
+ {
+ AMQChannel channel = new AMQChannel(session, channelId, session.getVirtualHost().getMessageStore());
+ session.addChannel(channel);
+ return channel;
+ }
+
+ public static AMQChannel createChannel(int channelId) throws Exception
+ {
+ InternalTestProtocolSession session = createSession();
+ return createChannel(channelId, session);
+ }
+
+ public static AMQChannel createChannel() throws Exception
+ {
+ return createChannel(1);
+ }
+
+ public static InternalTestProtocolSession createSession() throws Exception
+ {
+ return createSession("test");
+ }
+
+ public static InternalTestProtocolSession createSession(String hostName) throws Exception
+ {
+ VirtualHost virtualHost = createVirtualHost(hostName);
+ return new InternalTestProtocolSession(virtualHost, createBrokerMock());
+ }
+
+ public static Exchange createExchange(String hostName) throws Exception
+ {
+ SecurityManager securityManager = new SecurityManager(null);
+ VirtualHost virtualHost = mock(VirtualHost.class);
+ when(virtualHost.getName()).thenReturn(hostName);
+ when(virtualHost.getSecurityManager()).thenReturn(securityManager);
+ DefaultExchangeFactory factory = new DefaultExchangeFactory(virtualHost);
+ return factory.createExchange("amp.direct", "direct", false, false);
+ }
+
+ public static void publishMessages(AMQChannel channel, int numberOfMessages, String queueName, String exchangeName) throws AMQException
+ {
+ AMQShortString rouningKey = new AMQShortString(queueName);
+ AMQShortString exchangeNameAsShortString = new AMQShortString(exchangeName);
+ MessagePublishInfo info = mock(MessagePublishInfo.class);
+ when(info.getExchange()).thenReturn(exchangeNameAsShortString);
+ when(info.getRoutingKey()).thenReturn(rouningKey);
+
+ Exchange exchange = channel.getVirtualHost().getExchangeRegistry().getExchange(exchangeName);
+ for (int count = 0; count < numberOfMessages; count++)
+ {
+ channel.setPublishFrame(info, exchange);
+
+ // Set the body size
+ ContentHeaderBody _headerBody = new ContentHeaderBody();
+ _headerBody.setBodySize(0);
+
+ // Set Minimum properties
+ BasicContentHeaderProperties properties = new BasicContentHeaderProperties();
+
+ properties.setExpiration(0L);
+ properties.setTimestamp(System.currentTimeMillis());
+
+ // Make Message Persistent
+ properties.setDeliveryMode((byte) 2);
+
+ _headerBody.setProperties(properties);
+
+ channel.publishContentHeader(_headerBody);
+ }
+ channel.sync();
+ }
+
+ public static SimpleAMQQueue createQueue(String queueName, VirtualHost virtualHost) throws AMQException
+ {
+ SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), queueName, false, null,
+ false, false, virtualHost, Collections.<String, Object>emptyMap());
+ virtualHost.getQueueRegistry().registerQueue(queue);
+ return queue;
+ }
+
+
+}
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
deleted file mode 100644
index d7a9078412..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
+++ /dev/null
@@ -1,372 +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.util;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.common.AMQPFilterTypes;
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-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;
-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.virtualhost.VirtualHost;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-
-public class InternalBrokerBaseCase extends QpidTestCase
-{
- private IApplicationRegistry _registry;
- private MessageStore _messageStore;
- private AMQChannel _channel;
- private InternalTestProtocolSession _session;
- private VirtualHost _virtualHost;
- private AMQQueue _queue;
- private AMQShortString QUEUE_NAME;
- private ServerConfiguration _configuration;
- private XMLConfiguration _configXml = new XMLConfiguration();
- private boolean _started = false;
-
- public void setUp() throws Exception
- {
- super.setUp();
-
- _configXml.addProperty("virtualhosts.virtualhost.name", "test");
- _configXml.addProperty("virtualhosts.virtualhost.test.store.class", TestableMemoryMessageStore.class.getName());
-
- _configXml.addProperty("virtualhosts.virtualhost(-1).name", getName());
- _configXml.addProperty("virtualhosts.virtualhost(-1)."+getName()+".store.class", TestableMemoryMessageStore.class.getName());
-
- createBroker();
- }
-
- protected void createBroker() throws Exception
- {
- _started = true;
- CurrentActor.set(new TestLogActor(new SystemOutMessageLogger()));
-
- _configuration = new ServerConfiguration(_configXml);
-
- configure();
-
- _registry = createApplicationRegistry();
- ApplicationRegistry.initialise(_registry);
- _registry.getVirtualHostRegistry().setDefaultVirtualHostName(getName());
- _virtualHost = _registry.getVirtualHostRegistry().getVirtualHost(getName());
-
- 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(UUIDGenerator.generateRandomUUID(), QUEUE_NAME.asString(), false, "testowner",
- false, false, _virtualHost, null);
-
- Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
- _virtualHost.getBindingFactory().addBinding(QUEUE_NAME.toString(), _queue, defaultExchange, null);
-
- _virtualHost = _registry.getVirtualHostRegistry().getVirtualHost("test");
- _messageStore = _virtualHost.getMessageStore();
-
- _queue = AMQQueueFactory.createAMQQueueImpl(UUIDGenerator.generateRandomUUID(), getName(), false, "testowner",
- false, false, _virtualHost, null);
-
- _virtualHost.getQueueRegistry().registerQueue(_queue);
-
- defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
-
- _virtualHost.getBindingFactory().addBinding(getName(), _queue, defaultExchange, null);
-
- _session = new InternalTestProtocolSession(_virtualHost);
- CurrentActor.set(_session.getLogActor());
-
- _channel = new AMQChannel(_session, 1, _messageStore);
-
- _session.addChannel(_channel);
- }
-
- protected IApplicationRegistry createApplicationRegistry() throws ConfigurationException
- {
- return new TestApplicationRegistry(_configuration);
- }
-
- protected void configure()
- {
- // Allow other tests to override configuration
- }
-
- protected void stopBroker()
- {
- try
- {
- //Remove the ProtocolSession Actor added during createBroker
- CurrentActor.remove();
- }
- finally
- {
- ApplicationRegistry.remove();
- _started = false;
- }
- }
-
-
- public void tearDown() throws Exception
- {
- try
- {
- if (_started)
- {
- stopBroker();
- }
- }
- finally
- {
- super.tearDown();
- // Purge Any erroneously added actors
- CurrentActor.removeAll();
- }
- }
-
- protected void checkStoreContents(int messageCount)
- {
- assertEquals("Message header count incorrect in the MetaDataMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getMessageCount());
-
- //The above publish message is sufficiently small not to fit in the header so no Body is required.
- //assertEquals("Message body count incorrect in the ContentBodyMap", messageCount, ((TestableMemoryMessageStore) _messageStore).getContentBodyMap().size());
- }
-
- protected AMQShortString subscribe(InternalTestProtocolSession session, AMQChannel channel, AMQQueue queue)
- {
- try
- {
- return channel.subscribeToQueue(null, queue, true, null, false, true);
- }
- catch (AMQException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- //Keep the compiler happy
- return null;
- }
-
- protected AMQShortString browse(AMQChannel channel, AMQQueue queue)
- {
- try
- {
- FieldTable filters = new FieldTable();
- filters.put(AMQPFilterTypes.NO_CONSUME.getValue(), true);
-
- return channel.subscribeToQueue(null, queue, true, filters, false, true);
- }
- catch (AMQException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- //Keep the compiler happy
- return null;
- }
-
- public void publishMessages(InternalTestProtocolSession session, AMQChannel channel, int messages) throws AMQException
- {
- MessagePublishInfo info = new MessagePublishInfo()
- {
- public AMQShortString getExchange()
- {
- return ExchangeDefaults.DEFAULT_EXCHANGE_NAME;
- }
-
- public void setExchange(AMQShortString exchange)
- {
-
- }
-
- public boolean isImmediate()
- {
- return false;
- }
-
- public boolean isMandatory()
- {
- return false;
- }
-
- public AMQShortString getRoutingKey()
- {
- return new AMQShortString(getName());
- }
- };
-
- for (int count = 0; count < messages; count++)
- {
- channel.setPublishFrame(info, _virtualHost.getExchangeRegistry().getExchange(info.getExchange()));
-
- //Set the body size
- ContentHeaderBody _headerBody = new ContentHeaderBody();
- _headerBody.setBodySize(0);
-
- //Set Minimum properties
- BasicContentHeaderProperties properties = new BasicContentHeaderProperties();
-
- properties.setExpiration(0L);
- properties.setTimestamp(System.currentTimeMillis());
-
- //Make Message Persistent
- properties.setDeliveryMode((byte) 2);
-
- _headerBody.setProperties(properties);
-
- channel.publishContentHeader(_headerBody);
- }
- channel.sync();
- }
-
- public void acknowledge(AMQChannel channel, long deliveryTag)
- {
- try
- {
- channel.acknowledgeMessage(deliveryTag, false);
- }
- catch (AMQException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
- }
-
- public IApplicationRegistry getRegistry()
- {
- return _registry;
- }
-
- public void setRegistry(IApplicationRegistry registry)
- {
- _registry = registry;
- }
-
- public MessageStore getMessageStore()
- {
- return _messageStore;
- }
-
- public void setMessageStore(MessageStore messageStore)
- {
- _messageStore = messageStore;
- }
-
- public AMQChannel getChannel()
- {
- return _channel;
- }
-
- public void setChannel(AMQChannel channel)
- {
- _channel = channel;
- }
-
- public InternalTestProtocolSession getSession()
- {
- return _session;
- }
-
- public void setSession(InternalTestProtocolSession session)
- {
- _session = session;
- }
-
- public VirtualHost getVirtualHost()
- {
- return _virtualHost;
- }
-
- public void setVirtualHost(VirtualHost virtualHost)
- {
- _virtualHost = virtualHost;
- }
-
- public AMQQueue getQueue()
- {
- return _queue;
- }
-
- public void setQueue(AMQQueue queue)
- {
- _queue = queue;
- }
-
- public AMQShortString getQUEUE_NAME()
- {
- return QUEUE_NAME;
- }
-
- public void setQUEUE_NAME(AMQShortString QUEUE_NAME)
- {
- this.QUEUE_NAME = QUEUE_NAME;
- }
-
- public ServerConfiguration getConfiguration()
- {
- return _configuration;
- }
-
- public void setConfiguration(ServerConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- public XMLConfiguration getConfigXml()
- {
- return _configXml;
- }
-
- public void setConfigXml(XMLConfiguration configXml)
- {
- _configXml = configXml;
- }
-
- public boolean isStarted()
- {
- return _started;
- }
-
- public void setStarted(boolean started)
- {
- _started = started;
- }
-}
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
deleted file mode 100644
index a64ab620ab..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ /dev/null
@@ -1,121 +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.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;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-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;
-
-public class TestApplicationRegistry extends ApplicationRegistry
-{
-
- public TestApplicationRegistry(ServerConfiguration config) throws ConfigurationException
- {
- super(config);
- }
-
- @Override
- public void initialise() throws Exception
- {
- CurrentActor.setDefault(new BrokerActor(new NullRootMessageLogger()));
- GenericActor.setDefaultMessageLogger(new NullRootMessageLogger());
- super.initialise();
- }
-
- @Override
- protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(
- ServerConfiguration _configuration, PluginManager _pluginManager)
- throws ConfigurationException
- {
- final Properties users = new Properties();
- users.put("guest","guest");
- users.put("admin","admin");
-
- final PropertiesPrincipalDatabase ppd = new PropertiesPrincipalDatabase(users);
-
- final AuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager()
- {
-
- /**
- * @see org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin)
- */
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
- {
- // We don't pass configuration to this test instance.
- }
-
- @Override
- public void initialise()
- {
- setPrincipalDatabase(ppd);
-
- super.initialise();
- }
- };
- pdam.initialise();
-
- 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/MockVirtualHost.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
index 290c465785..1d99d99820 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
@@ -22,26 +22,18 @@ package org.apache.qpid.server.virtualhost;
import java.util.concurrent.ScheduledFuture;
import org.apache.qpid.server.binding.BindingFactory;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
-import org.apache.qpid.server.configuration.VirtualHostConfigType;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
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.protocol.v1_0.LinkRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
-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.stats.StatisticsCounter;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.txn.DtxRegistry;
-import java.util.Map;
import java.util.UUID;
public class MockVirtualHost implements VirtualHost
@@ -58,19 +50,8 @@ public class MockVirtualHost implements VirtualHost
}
- public void createBrokerConnection(String transport, String host, int port,
- String vhost, boolean durable, String authMechanism,
- String username, String password)
- {
-
- }
-
- public BrokerLink createBrokerConnection(final UUID id, final long createTime, final Map<String, String> arguments)
- {
- return null;
- }
-
- public IApplicationRegistry getApplicationRegistry()
+ @Override
+ public VirtualHostRegistry getVirtualHostRegistry()
{
return null;
}
@@ -85,16 +66,6 @@ public class MockVirtualHost implements VirtualHost
return null;
}
- public UUID getBrokerId()
- {
- return null;
- }
-
- public ConfigStore getConfigStore()
- {
- return null;
- }
-
public DtxRegistry getDtxRegistry()
{
return null;
@@ -160,12 +131,6 @@ public class MockVirtualHost implements VirtualHost
return null;
}
-
- public void removeBrokerConnection(BrokerLink brokerLink)
- {
-
- }
-
public LinkRegistry getLinkRegistry(String remoteContainerId)
{
return null;
@@ -186,25 +151,6 @@ public class MockVirtualHost implements VirtualHost
}
- public BrokerConfig getBroker()
- {
- return null;
- }
-
- public String getFederationTag()
- {
- return null;
- }
-
- public void setBroker(BrokerConfig brokerConfig)
- {
-
- }
-
- public VirtualHostConfigType getConfigType()
- {
- return null;
- }
public long getCreateTime()
{
@@ -216,17 +162,6 @@ public class MockVirtualHost implements VirtualHost
return null;
}
- @Override
- public UUID getQMFId()
- {
- return null;
- }
-
- public ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> getParent()
- {
- return null;
- }
-
public boolean isDurable()
{
return false;
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 b8ba76e43d..559a7f8aaf 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
@@ -20,15 +20,21 @@
*/
package org.apache.qpid.server.virtualhost;
+import static org.mockito.Mockito.mock;
+
+import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.store.MemoryMessageStore;
-import org.apache.qpid.server.util.TestApplicationRegistry;
+import org.apache.qpid.server.util.BrokerTestHelper;
import org.apache.qpid.test.utils.QpidTestCase;
import java.io.BufferedWriter;
@@ -38,15 +44,31 @@ import java.io.IOException;
public class VirtualHostImplTest extends QpidTestCase
{
- private ServerConfiguration _configuration;
- private ApplicationRegistry _registry;
+ private VirtualHostRegistry _virtualHostRegistry;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ BrokerTestHelper.setUp();
+ }
@Override
public void tearDown() throws Exception
{
- super.tearDown();
+ try
+ {
+ if (_virtualHostRegistry != null)
+ {
+ _virtualHostRegistry.close();
+ }
+ }
+ finally
+ {
+ BrokerTestHelper.tearDown();
+ super.tearDown();
+ }
- ApplicationRegistry.remove();
}
/**
@@ -74,17 +96,23 @@ public class VirtualHostImplTest extends QpidTestCase
*/
public void testSpecifyingCustomBindingForDefaultExchangeThrowsException() throws Exception
{
- File config = writeConfigFile(getName(), getName(), null, false, new String[]{"custom-binding"});
+ final String queueName = getName();
+ final String customBinding = "custom-binding";
+ File config = writeConfigFile(queueName, queueName, null, false, new String[]{customBinding});
try
{
- createVirtualHost(getName(), config);
+ createVirtualHost(queueName, config);
fail("virtualhost creation should have failed due to illegal configuration");
}
catch (RuntimeException e)
{
+ assertNotNull(e.getCause());
+
assertEquals(ConfigurationException.class, e.getCause().getClass());
- //expected
+
+ Throwable configException = e.getCause();
+ assertEquals("Illegal attempt to bind queue '" + queueName + "' to the default exchange with a key other than the queue name: " + customBinding, configException.getMessage());
}
}
@@ -96,6 +124,14 @@ public class VirtualHostImplTest extends QpidTestCase
assertEquals(State.ACTIVE, vhost.getState());
}
+ public void testVirtualHostHavingStoreSetAsTypeBecomesActive() throws Exception
+ {
+ String virtualHostName = getName();
+ VirtualHost host = createVirtualHostUsingStoreType(virtualHostName);
+ assertNotNull(host);
+ assertEquals(State.ACTIVE, host.getState());
+ }
+
public void testVirtualHostBecomesStoppedOnClose() throws Exception
{
File config = writeConfigFile(getName(), getName(), getName() +".direct", false, new String[0]);
@@ -107,22 +143,39 @@ public class VirtualHostImplTest extends QpidTestCase
assertEquals(0, vhost.getHouseKeepingActiveCount());
}
+ public void testVirtualHostHavingStoreSetAsTypeBecomesStoppedOnClose() throws Exception
+ {
+ String virtualHostName = getName();
+ VirtualHost host = createVirtualHostUsingStoreType(virtualHostName);
+ assertNotNull(host);
+ assertEquals(State.ACTIVE, host.getState());
+ host.close();
+ assertEquals(State.STOPPED, host.getState());
+ assertEquals(0, host.getHouseKeepingActiveCount());
+ }
+
/**
* Tests that specifying an unknown exchange to bind the queue to results in failure to create the vhost
*/
public void testSpecifyingUnknownExchangeThrowsException() throws Exception
{
- File config = writeConfigFile(getName(), getName(), "made-up-exchange", true, new String[0]);
+ final String queueName = getName();
+ final String exchangeName = "made-up-exchange";
+ File config = writeConfigFile(queueName, queueName, exchangeName, true, new String[0]);
try
{
- createVirtualHost(getName(), config);
+ createVirtualHost(queueName, config);
fail("virtualhost creation should have failed due to illegal configuration");
}
catch (RuntimeException e)
{
+ assertNotNull(e.getCause());
+
assertEquals(ConfigurationException.class, e.getCause().getClass());
- //expected
+
+ Throwable configException = e.getCause();
+ assertEquals("Attempt to bind queue '" + queueName + "' to unknown exchange:" + exchangeName, configException.getMessage());
}
}
@@ -154,12 +207,14 @@ public class VirtualHostImplTest extends QpidTestCase
private VirtualHost createVirtualHost(String vhostName, File config) throws Exception
{
- _configuration = new ServerConfiguration(new XMLConfiguration(config));
+ Broker broker = BrokerTestHelper.createBrokerMock();
+ _virtualHostRegistry = broker.getVirtualHostRegistry();
- _registry = new TestApplicationRegistry(_configuration);
- ApplicationRegistry.initialise(_registry);
+ VirtualHostConfiguration configuration = new VirtualHostConfiguration(vhostName, config, broker);
+ VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration);
+ _virtualHostRegistry.registerVirtualHost(host);
- return _registry.getVirtualHostRegistry().getVirtualHost(vhostName);
+ return host;
}
/**
@@ -184,7 +239,6 @@ public class VirtualHostImplTest extends QpidTestCase
BufferedWriter writer = new BufferedWriter(fstream);
//extra outer tag to please Commons Configuration
- writer.write("<configuration>");
writer.write("<virtualhosts>");
writer.write(" <default>" + vhostName + "</default>");
@@ -222,8 +276,6 @@ public class VirtualHostImplTest extends QpidTestCase
writer.write(" </virtualhost>");
writer.write("</virtualhosts>");
- writer.write("</configuration>");
-
writer.flush();
writer.close();
}
@@ -234,4 +286,17 @@ public class VirtualHostImplTest extends QpidTestCase
return tmpFile;
}
+
+ private VirtualHost createVirtualHostUsingStoreType(String virtualHostName) throws ConfigurationException, Exception
+ {
+ Broker broker = BrokerTestHelper.createBrokerMock();
+ _virtualHostRegistry = broker.getVirtualHostRegistry();
+
+ Configuration config = new PropertiesConfiguration();
+ config.setProperty("store.type", MemoryMessageStore.TYPE);
+ VirtualHostConfiguration configuration = new VirtualHostConfiguration(virtualHostName, config, broker);
+ VirtualHost host = new VirtualHostImpl(_virtualHostRegistry, mock(StatisticsGatherer.class), new SecurityManager(null), configuration);
+ _virtualHostRegistry.registerVirtualHost(host);
+ return host;
+ }
}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java
deleted file mode 100644
index e2375c579b..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionConfigurationTest.java
+++ /dev/null
@@ -1,347 +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.virtualhost.plugins;
-
-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.SlowConsumerDetectionConfiguration;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provide Unit Test coverage of the virtualhost SlowConsumer Configuration
- * This is what controls how often the plugin will execute
- */
-public class SlowConsumerDetectionConfigurationTest extends InternalBrokerBaseCase
-{
-
- /**
- * Default Testing:
- *
- * Provide a fully complete and valid configuration specifying 'delay' and
- * 'timeunit' and ensure that it is correctly processed.
- *
- * Ensure no exceptions are thrown and that we get the same values back that
- * were put into the configuration.
- */
- public void testConfigLoadingValidConfig()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- long DELAY=10;
- String TIMEUNIT=TimeUnit.MICROSECONDS.toString();
- xmlconfig.addProperty("delay", String.valueOf(DELAY));
- xmlconfig.addProperty("timeunit", TIMEUNIT);
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- }
- catch (ConfigurationException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- assertEquals("Delay not correctly returned.", DELAY, config.getDelay());
- assertEquals("TimeUnit not correctly returned.",
- TIMEUNIT, String.valueOf(config.getTimeUnit()));
- }
-
- /**
- * Default Testing:
- *
- * Test Missing TimeUnit value gets default.
- *
- * The TimeUnit value is optional and default to SECONDS.
- *
- * Test that if we do not specify a TimeUnit then we correctly get seconds.
- *
- * Also verify that relying on the default does not impact the setting of
- * the 'delay' value.
- *
- */
- public void testConfigLoadingMissingTimeUnitDefaults()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- long DELAY=10;
- xmlconfig.addProperty("delay", String.valueOf(DELAY));
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
- try
- {
- config.setConfiguration("", composite);
- }
- catch (ConfigurationException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- assertEquals("Delay not correctly returned.", DELAY, config.getDelay());
- assertEquals("Default TimeUnit incorrect", TimeUnit.SECONDS, config.getTimeUnit());
- }
-
- /**
- * Input Testing:
- *
- * TimeUnit parsing requires the String value be in UpperCase.
- * Ensure we can handle when the user doesn't know this.
- *
- * Same test as 'testConfigLoadingValidConfig' but checking that
- * the timeunit field is not case sensitive.
- * i.e. the toUpper is being correctly applied.
- */
- public void testConfigLoadingValidConfigStrangeTimeUnit()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- long DELAY=10;
-
- xmlconfig.addProperty("delay", DELAY);
- xmlconfig.addProperty("timeunit", "MiCrOsEcOnDs");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- }
- catch (ConfigurationException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- assertEquals("Delay not correctly returned.", DELAY, config.getDelay());
- assertEquals("TimeUnit not correctly returned.",
- TimeUnit.MICROSECONDS.toString(), String.valueOf(config.getTimeUnit()));
-
- }
-
- /**
- * Failure Testing:
- *
- * Test that delay must be long not a string value.
- * Provide a delay as a written value not a long. 'ten'.
- *
- * This should throw a configuration exception which is being trapped and
- * verified to be the right exception, a NumberFormatException.
- *
- */
- public void testConfigLoadingInValidDelayString()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("delay", "ten");
- xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString());
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("Configuration should fail to validate");
- }
- catch (ConfigurationException e)
- {
- Throwable cause = e.getCause();
-
- assertEquals("Cause not correct", NumberFormatException.class, cause.getClass());
- }
- }
-
- /**
- * Failure Testing:
- *
- * Test that negative delays are invalid.
- *
- * Delay must be a positive value as negative delay means doesn't make sense.
- *
- * Configuration exception with a useful message should be thrown here.
- *
- */
- public void testConfigLoadingInValidDelayNegative()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("delay", "-10");
- xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString());
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("Configuration should fail to validate");
- }
- catch (ConfigurationException e)
- {
- Throwable cause = e.getCause();
-
- assertNotNull("Configuration Exception must not be null.", cause);
- assertEquals("Cause not correct",
- ConfigurationException.class, cause.getClass());
- assertEquals("Incorrect message.",
- "SlowConsumerDetectionConfiguration: 'delay' must be a Positive Long value.",
- cause.getMessage());
- }
- }
-
- /**
- * Failure Testing:
- *
- * Test that delay cannot be 0.
- *
- * A zero delay means run constantly. This is not how VirtualHostTasks
- * are designed to be run so we dis-allow the use of 0 delay.
- *
- * Same test as 'testConfigLoadingInValidDelayNegative' but with a 0 value.
- *
- */
- public void testConfigLoadingInValidDelayZero()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("delay", "0");
- xmlconfig.addProperty("timeunit", TimeUnit.MICROSECONDS.toString());
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("Configuration should fail to validate");
- }
- catch (ConfigurationException e)
- {
- Throwable cause = e.getCause();
-
- assertNotNull("Configuration Exception must not be null.", cause);
- assertEquals("Cause not correct",
- ConfigurationException.class, cause.getClass());
- assertEquals("Incorrect message.",
- "SlowConsumerDetectionConfiguration: 'delay' must be a Positive Long value.",
- cause.getMessage());
- }
- }
-
- /**
- * Failure Testing:
- *
- * Test that missing delay fails.
- * If we have no delay then we do not pick a default. So a Configuration
- * Exception is thrown.
- *
- * */
- public void testConfigLoadingInValidMissingDelay()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("timeunit", TimeUnit.SECONDS.toString());
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
- try
- {
- config.setConfiguration("", composite);
- fail("Configuration should fail to validate");
- }
- catch (ConfigurationException e)
- {
- assertEquals("Incorrect message.", "SlowConsumerDetectionConfiguration: unable to configure invalid delay:null", e.getMessage());
- }
- }
-
- /**
- * Failure Testing:
- *
- * Test that erroneous TimeUnit fails.
- *
- * Valid TimeUnit values vary based on the JVM version i.e. 1.6 added HOURS/DAYS etc.
- *
- * We don't test the values for TimeUnit are accepted other than MILLISECONDS in the
- * positive testing at the start.
- *
- * Here we ensure that an erroneous for TimeUnit correctly throws an exception.
- *
- * We test with 'foo', which will never be a TimeUnit
- *
- */
- public void testConfigLoadingInValidTimeUnit()
- {
- SlowConsumerDetectionConfiguration config = new SlowConsumerDetectionConfiguration();
-
- String TIMEUNIT = "foo";
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("delay", "10");
- xmlconfig.addProperty("timeunit", TIMEUNIT);
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
- try
- {
- config.setConfiguration("", composite);
- fail("Configuration should fail to validate");
- }
- catch (ConfigurationException e)
- {
- assertEquals("Incorrect message.", "Unable to configure Slow Consumer Detection invalid TimeUnit:" + TIMEUNIT, e.getMessage());
- }
- }
-
-
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.java
deleted file mode 100644
index ea07632873..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionPolicyConfigurationTest.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.virtualhost.plugins;
-
-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.SlowConsumerDetectionPolicyConfiguration;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-/**
- * Test class to ensure that the policy configuration can be processed.
- */
-public class SlowConsumerDetectionPolicyConfigurationTest extends InternalBrokerBaseCase
-{
-
- /**
- * Input Testing:
- *
- * Test that a given String can be set and retrieved through the configuration
- *
- * No validation is being performed to ensure that the policy exists. Only
- * that a value can be set for the policy.
- *
- */
- public void testConfigLoadingValidConfig()
- {
- SlowConsumerDetectionPolicyConfiguration config = new SlowConsumerDetectionPolicyConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- String policyName = "TestPolicy";
- xmlconfig.addProperty("name", policyName);
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- }
- catch (ConfigurationException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
-
- assertEquals("Policy name not retrieved as expected.",
- policyName, config.getPolicyName());
- }
-
- /**
- * Failure Testing:
- *
- * Test that providing a configuration section without the 'name' field
- * causes an exception to be thrown.
- *
- * An empty configuration is provided and the thrown exception message
- * is checked to confirm the right reason.
- *
- */
- public void testConfigLoadingInValidConfig()
- {
- SlowConsumerDetectionPolicyConfiguration config = new SlowConsumerDetectionPolicyConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("Config is invalid so won't validate.");
- }
- catch (ConfigurationException e)
- {
- e.printStackTrace();
- assertEquals("Exception message not as expected.", "No Slow consumer policy defined.", e.getMessage());
- }
- }
-
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.java
deleted file mode 100644
index 96e524acf2..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetectionQueueConfigurationTest.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.virtualhost.plugins;
-
-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.SlowConsumerDetectionQueueConfiguration;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-/**
- * Unit test the QueueConfiguration processing.
- *
- * This is slightly awkward as the {@link SlowConsumerDetectionQueueConfiguration}
- * requries that a policy be available.
- * <p>
- * So all the Valid test much catch the ensuing {@link ConfigurationException} and
- * validate that the error is due to a lack of a valid policy.
- */
-public class SlowConsumerDetectionQueueConfigurationTest extends InternalBrokerBaseCase
-{
- /**
- * Test a fully loaded configuration file.
- *
- * It is not an error to have all control values specified.
- * <p>
- * Here we need to catch the {@link ConfigurationException} that ensues due to lack
- * of a policy plugin.
- */
- public void testConfigLoadingValidConfig()
- {
- SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("messageAge", "60000");
- xmlconfig.addProperty("depth", "1024");
- xmlconfig.addProperty("messageCount", "10");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("No Policies are avaialbe to load in a unit test");
- }
- catch (ConfigurationException e)
- {
- assertTrue("Exception message incorrect, was: " + e.getMessage(),
- e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:["));
- }
- }
-
- /**
- * When we do not specify any control value then a {@link ConfigurationException}
- * must be thrown to remind us.
- */
- public void testConfigLoadingMissingConfig()
- {
- SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("No Policies are avaialbe to load in a unit test");
- }
- catch (ConfigurationException e)
- {
-
- assertEquals("At least one configuration property('messageAge','depth'" +
- " or 'messageCount') must be specified.", e.getMessage());
- }
- }
-
- /**
- * Setting messageAge on its own is enough to have a valid configuration
- *
- * Here we need to catch the {@link ConfigurationException} that ensues due to lack
- * of a policy plugin.
- */
- public void testConfigLoadingMessageAgeOk()
- {
- SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("messageAge", "60000");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("No Policies are avaialbe to load in a unit test");
- }
- catch (ConfigurationException e)
- {
- assertTrue("Exception message incorrect, was: " + e.getMessage(),
- e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:["));
- }
- }
-
- /**
- * Setting depth on its own is enough to have a valid configuration.
- *
- * Here we need to catch the {@link ConfigurationException} that ensues due to lack
- * of a policy plugin.
- */
- public void testConfigLoadingDepthOk()
- {
- SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("depth", "1024");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("No Policies are avaialbe to load in a unit test");
- }
- catch (ConfigurationException e)
- {
- assertTrue("Exception message incorrect, was: " + e.getMessage(),
- e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:["));
- }
- }
-
- /**
- * Setting messageCount on its own is enough to have a valid configuration.
- *
- * Here we need to catch the {@link ConfigurationException} that ensues due to lack
- * of a policy plugin.
- */
- public void testConfigLoadingMessageCountOk()
- {
- SlowConsumerDetectionQueueConfiguration config = new SlowConsumerDetectionQueueConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("messageCount", "10");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("", composite);
- fail("No Policies are avaialbe to load in a unit test");
- }
- catch (ConfigurationException e)
- {
- assertTrue("Exception message incorrect, was: " + e.getMessage(),
- e.getMessage().startsWith("No Slow Consumer Policy specified. Known Policies:["));
- }
- }
-}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java
deleted file mode 100644
index f034d05c37..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfigurationTest.java
+++ /dev/null
@@ -1,89 +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.virtualhost.plugins.policies;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-/**
- * Test to ensure TopicDelete Policy configuration can be loaded.
- */
-public class TopicDeletePolicyConfigurationTest extends InternalBrokerBaseCase
-{
- /**
- * Test without any configuration being provided that the
- * deletePersistent option is disabled.
- */
- public void testNoConfigNoDeletePersistent()
- {
- TopicDeletePolicyConfiguration config = new TopicDeletePolicyConfiguration();
-
- assertFalse("TopicDelete Configuration with no config should not delete persistent queues.",
- config.deletePersistent());
- }
-
- /**
- * Test that with the correct configuration the deletePersistent option can
- * be enabled.
- *
- * Test creates a new Configuration object and passes in the xml snippet
- * that the ConfigurationPlugin would receive during normal execution.
- * This is the XML that would be matched for this plugin:
- * <topicdelete>
- * <delete-persistent>
- * <topicdelete>
- *
- * So it would be subset and passed in as just:
- * <delete-persistent>
- *
- *
- * The property should therefore be enabled.
- *
- */
- public void testConfigDeletePersistent()
- {
- TopicDeletePolicyConfiguration config = new TopicDeletePolicyConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
-
- xmlconfig.addProperty("delete-persistent","");
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
-
- try
- {
- config.setConfiguration("",composite);
- }
- catch (ConfigurationException e)
- {
- fail(e.getMessage());
- }
-
- assertTrue("A configured TopicDelete should delete persistent queues.",
- config.deletePersistent());
- }
-
-}
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
deleted file mode 100644
index aa8448b99d..0000000000
--- a/java/broker/src/test/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyTest.java
+++ /dev/null
@@ -1,294 +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.virtualhost.plugins.policies;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.binding.Binding;
-import org.apache.qpid.server.exchange.DirectExchange;
-import org.apache.qpid.server.exchange.TopicExchange;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.protocol.InternalTestProtocolSession;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.MockAMQQueue;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-public class TopicDeletePolicyTest extends InternalBrokerBaseCase
-{
-
- private TopicDeletePolicyConfiguration _config;
-
- private VirtualHost _defaultVhost;
- private InternalTestProtocolSession _connection;
-
- public void setUp() throws Exception
- {
- super.setUp();
-
- _defaultVhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getDefaultVirtualHost();
-
- _connection = new InternalTestProtocolSession(_defaultVhost);
-
- _config = new TopicDeletePolicyConfiguration();
-
- XMLConfiguration config = new XMLConfiguration();
-
- _config.setConfiguration("", config);
- }
-
- private MockAMQQueue createOwnedQueue()
- {
- MockAMQQueue queue = new MockAMQQueue("testQueue");
-
- _defaultVhost.getQueueRegistry().registerQueue(queue);
-
- try
- {
- AMQChannel channel = new AMQChannel(_connection, 0, null);
- _connection.addChannel(channel);
-
- queue.setExclusiveOwningSession(channel);
- }
- catch (AMQException e)
- {
- fail("Unable to create Channel:" + e.getMessage());
- }
-
- return queue;
- }
-
- private void setQueueToAutoDelete(final AMQQueue queue)
- {
- ((MockAMQQueue) queue).setAutoDelete(true);
-
- queue.setDeleteOnNoConsumers(true);
- final AMQProtocolSession.Task deleteQueueTask =
- new AMQProtocolSession.Task()
- {
- public void doTask(AMQProtocolSession session) throws AMQException
- {
- queue.delete();
- }
- };
-
- ((AMQChannel) queue.getExclusiveOwningSession()).getProtocolSession().addSessionCloseTask(deleteQueueTask);
- }
-
- /** Check that a null queue passed in does not upset the policy. */
- public void testNullQueueParameter() throws ConfigurationException
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- try
- {
- policy.performPolicy(null);
- }
- catch (Exception e)
- {
- fail("Exception should not be thrown:" + e.getMessage());
- }
-
- }
-
- /**
- * Set a owning Session to null which means this is not an exclusive queue
- * so the queue should not be deleted
- */
- public void testNonExclusiveQueue()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.setExclusiveOwningSession(null);
-
- policy.performPolicy(queue);
-
- assertFalse("Queue should not be deleted", queue.isDeleted());
- assertFalse("Connection should not be closed", _connection.isClosed());
- }
-
- /**
- * Test that exclusive JMS Queues are not deleted.
- * Bind the queue to the direct exchange (so it is a JMS Queue).
- *
- * JMS Queues are not to be processed so this should not delete the queue.
- */
- public void testQueuesAreNotProcessed()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new DirectExchange(), null));
-
- policy.performPolicy(queue);
-
- assertFalse("Queue should not be deleted", queue.isDeleted());
- assertFalse("Connection should not be closed", _connection.isClosed());
- }
-
- /**
- * Give a non auto-delete queue is bound to the topic exchange the
- * TopicDeletePolicy will close the connection and delete the queue,
- */
- public void testNonAutoDeleteTopicIsNotClosed()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
-
- queue.setAutoDelete(false);
-
- policy.performPolicy(queue);
-
- assertFalse("Queue should not be deleted", queue.isDeleted());
- assertTrue("Connection should be closed", _connection.isClosed());
- }
-
- /**
- * Give a auto-delete queue bound to the topic exchange the TopicDeletePolicy will
- * close the connection and delete the queue
- */
- public void testTopicIsClosed()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- final MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
-
- setQueueToAutoDelete(queue);
-
- policy.performPolicy(queue);
-
- assertTrue("Queue should be deleted", queue.isDeleted());
- assertTrue("Connection should be closed", _connection.isClosed());
- }
-
- /**
- * Give a queue bound to the topic exchange the TopicDeletePolicy will
- * close the connection and NOT delete the queue
- */
- public void testNonAutoDeleteTopicIsClosedNotDeleted()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
-
- policy.performPolicy(queue);
-
- assertFalse("Queue should not be deleted", queue.isDeleted());
- assertTrue("Connection should be closed", _connection.isClosed());
- }
-
- /**
- * Give a queue bound to the topic exchange the TopicDeletePolicy suitably
- * configured with the delete-persistent tag will close the connection
- * and delete the queue
- */
- public void testPersistentTopicIsClosedAndDeleted()
- {
- //Set the config to delete persistent queues
- _config.getConfig().addProperty("delete-persistent", "");
-
- TopicDeletePolicy policy = new TopicDeletePolicy();
- policy.configure(_config);
-
- assertTrue("Config was not updated to delete Persistent topics",
- _config.deletePersistent());
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
-
- policy.performPolicy(queue);
-
- assertTrue("Queue should be deleted", queue.isDeleted());
- assertTrue("Connection should be closed", _connection.isClosed());
- }
-
- /**
- * Give a queue bound to the topic exchange the TopicDeletePolicy not
- * configured to close a persistent queue
- */
- public void testPersistentTopicIsClosedAndDeletedNullConfig()
- {
- TopicDeletePolicy policy = new TopicDeletePolicy();
- // Explicity say we are not configuring the policy.
- policy.configure(null);
-
- MockAMQQueue queue = createOwnedQueue();
-
- queue.addBinding(new Binding(null, null, "bindingKey", queue, new TopicExchange(), null));
-
- policy.performPolicy(queue);
-
- assertFalse("Queue should not be deleted", queue.isDeleted());
- assertTrue("Connection should be closed", _connection.isClosed());
- }
-
- public void testNonExclusiveQueueNullConfig()
- {
- _config = null;
- testNonExclusiveQueue();
- }
-
- public void testQueuesAreNotProcessedNullConfig()
- {
- _config = null;
- testQueuesAreNotProcessed();
- }
-
- public void testNonAutoDeleteTopicIsNotClosedNullConfig()
- {
- _config = null;
- testNonAutoDeleteTopicIsNotClosed();
- }
-
- public void testTopicIsClosedNullConfig()
- {
- _config = null;
- testTopicIsClosed();
- }
-
- public void testNonAutoDeleteTopicIsClosedNotDeletedNullConfig() throws AMQException
- {
- _config = null;
- testNonAutoDeleteTopicIsClosedNotDeleted();
- }
-
-}
diff --git a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
index 02bf155c44..cddfcfb581 100644
--- a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
+++ b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm
@@ -23,8 +23,8 @@ package ${package};
import static org.apache.qpid.server.logging.AbstractRootMessageLogger.DEFAULT_LOG_HIERARCHY_PREFIX;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.logging.LogMessage;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import java.text.MessageFormat;
import java.util.Locale;
@@ -44,7 +44,7 @@ import java.util.ResourceBundle;
public class ${type.name}Messages
{
private static ResourceBundle _messages;
- private static Locale _currentLocale;
+ private static Locale _currentLocale = BrokerProperties.getLocale();
public static final String ${type.name.toUpperCase()}_LOG_HIERARCHY = DEFAULT_LOG_HIERARCHY_PREFIX + "${type.name.toLowerCase()}";
#foreach( $message in ${type.list} )
@@ -58,24 +58,9 @@ public class ${type.name}Messages
Logger.getLogger(${message.methodName.toUpperCase()}_LOG_HIERARCHY);
#end
- reload();
- }
-
- public static void reload()
- {
- if (ApplicationRegistry.isConfigured())
- {
- _currentLocale = ApplicationRegistry.getInstance().getConfiguration().getLocale();
- }
- else
- {
- _currentLocale = Locale.getDefault();
- }
-
_messages = ResourceBundle.getBundle("${resource}", _currentLocale);
}
-
##
## The list stored under key 'list' in the 'type' HashMap contains all the
## log messages that this class should contain. So for each entry in the list
diff --git a/java/build.deps b/java/build.deps
index 4742ec1a8c..f60ffd8ff8 100644
--- a/java/build.deps
+++ b/java/build.deps
@@ -59,10 +59,6 @@ servlet-api=${geronimo-servlet}
dojo=lib/required/dojo-war-1.7.2.war
-felix-main=lib/required/org.apache.felix.main-2.0.5.jar
-
-felix.libs=${felix-main}
-
jackson-core=lib/required/jackson-core-asl-1.9.0.jar
jackson-mapper=lib/required/jackson-mapper-asl-1.9.0.jar
@@ -72,19 +68,20 @@ commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \
common.libs=${slf4j-api}
client.libs=${geronimo-jms}
amqp-1-0-common.libs=
-amqp-1-0-client.libs=${commons-cli}
+amqp-1-0-client.libs=
+amqp-1-0-client-example.libs=${commons-cli}
amqp-1-0-client-jms.libs=${geronimo-jms}
tools.libs=${commons-configuration.libs} ${log4j}
broker.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \
- ${xalan} ${felix.libs} ${derby-db} ${commons-configuration.libs} \
+ ${xalan} ${derby-db} ${commons-configuration.libs} \
${jackson-core} ${jackson-mapper} ${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jetty-websocket}
broker-plugins-management-http.libs=${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jackson-core} ${jackson-mapper}
-broker-plugins.libs=${felix.libs} ${log4j} ${commons-configuration.libs}
+broker-plugins.libs=${log4j} ${commons-configuration.libs}
test.libs=${slf4j-log4j} ${log4j} ${junit} ${slf4j-api} ${mockito-all}
-perftests.libs=${geronimo-jms} ${slf4j-api} ${log4j} ${slf4j-log4j} ${commons-logging} ${commons-collections} ${commons-beanutils-core} ${commons-lang} ${gson-all}
+perftests.libs=${geronimo-jms} ${slf4j-api} ${log4j} ${slf4j-log4j} ${commons-logging} ${commons-collections} ${commons-beanutils-core} ${commons-lang} ${gson-all} ${derby-db}
management-common.libs=
@@ -93,11 +90,12 @@ broker.test.libs=${test.libs}
client.test.libs=${test.libs}
client-example.test.libs=${test.libs}
tools.test.libs=
-testkit.test.libs=${test.libs}
systests.libs=${test.libs}
perftests.test.libs=${test.libs}
-broker-plugins.test.libs=${test.libs}
+broker-plugins-access-control.test.libs=${test.libs}
+broker-plugins-management-http.test.libs=${test.libs}
+broker-plugins-management-jmx.test.libs=${test.libs}
management-common.test.libs=${test.libs}
@@ -117,10 +115,12 @@ bdbstore-jmx.test.libs=${test.libs}
jfreechart.jar=lib/jfree/jfreechart-1.0.13.jar
jcommon.jar=lib/jfree/jcommon-1.0.16.jar
csvjdbc.jar=lib/csvjdbc/csvjdbc-1.0.8.jar
-perftests-visualisation-jfc.libs=${jfreechart.jar} ${jcommon.jar} ${csvjdbc.jar}
+perftests-visualisation-jfc.libs=${jfreechart.jar} ${jcommon.jar} ${csvjdbc.jar} ${derby-db}
perftests-visualisation-jfc.test.libs=${test.libs}
# Libraries used only within the build
bnd=lib/required/bnd-0.0.384.jar
jython=lib/required/jython-standalone-2.5.2.jar
maven-ant-tasks=lib/required/maven-ant-tasks-2.1.1.jar
+velocity.jar=lib/required/velocity-1.4.jar
+velocity-dep.jar=lib/required/velocity-dep-1.4.jar
diff --git a/java/build.xml b/java/build.xml
index 7f51cb64c0..e3726d1c3c 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -32,7 +32,7 @@
</condition>
<property name="modules.core" value="common management/common amqp-1-0-common broker client amqp-1-0-client amqp-1-0-client-jms tools"/>
- <property name="modules.examples" value="client/example management/example"/>
+ <property name="modules.examples" value="client/example management/example amqp-1-0-client/example amqp-1-0-client-jms/example"/>
<property name="modules.tests" value="systests perftests"/>
<property name="modules.plugin" value="${broker-plugins} ${client-plugins}"/>
<property name="modules.jca" value="jca"/>
@@ -77,6 +77,10 @@
<iterate target="release-mvn"/>
</target>
+ <target name="deploy-snapshot" description="deploy snapshot artifacts to nexus">
+ <iterate target="deploy-snapshot"/>
+ </target>
+
<target name="compile" description="compile sources">
<iterate target="compile"/>
</target>
diff --git a/java/client/build.xml b/java/client/build.xml
index a02500d8e4..707bfda024 100644
--- a/java/client/build.xml
+++ b/java/client/build.xml
@@ -21,7 +21,7 @@
<project name="AMQ Client" default="build">
<property name="module.depends" value="common"/>
- <property name="module.test.depends" value="common/test" />
+ <property name="module.test.depends" value="common/tests" />
<property name="module.genpom" value="true"/>
<property name="module.genpom.args" value="-Sgeronimo-jms_1.1_spec=provided"/>
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/Drain.java b/java/client/example/src/main/java/org/apache/qpid/example/Drain.java
index 28e1d5a87e..f0eb83ad24 100644
--- a/java/client/example/src/main/java/org/apache/qpid/example/Drain.java
+++ b/java/client/example/src/main/java/org/apache/qpid/example/Drain.java
@@ -88,7 +88,7 @@ public class Drain extends OptionParser
}
}
}
-
+ consumer.close();
ssn.close();
con.close();
}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/ListReceiver.java b/java/client/example/src/main/java/org/apache/qpid/example/ListReceiver.java
new file mode 100644
index 0000000000..b12cfab9de
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/ListReceiver.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.example;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.MapMessage;
+import javax.jms.StreamMessage;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.jms.MessageEOFException;
+
+import org.apache.qpid.client.AMQAnyDestination;
+import org.apache.qpid.client.AMQConnection;
+
+import org.apache.qpid.jms.ListMessage;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+public class ListReceiver {
+
+ public static void main(String[] args) throws Exception
+ {
+ if (args.length != 1) {
+ System.out.println("Usage: java org.apache.qpid.example.ListReceiver <-l | -m | -s>");
+ System.out.println("where:");
+ System.out.println("\t-l\tAccept ListMessage and print it");
+ System.out.println("\t-m\tAccept ListMessage as a MapMessage");
+ System.out.println("\t-s\tAccept ListMessage as a StreamMessage");
+ return;
+ }
+
+ Connection connection =
+ new AMQConnection("amqp://guest:guest@test/?brokerlist='tcp://localhost:5672'");
+
+ connection.start();
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Destination queue = new AMQAnyDestination("ADDR:message_queue; {create: always}");
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ if (args[0].equals("-l")) {
+ System.out.println("Receiving as ListMessage");
+ ListMessage m = (ListMessage)consumer.receive();
+ System.out.println(m);
+ System.out.println("==========================================");
+ System.out.println("Printing list contents:");
+ Iterator i = m.iterator();
+ while(i.hasNext())
+ System.out.println(i.next());
+ }
+ else if (args[0].equals("-m")) {
+ System.out.println("Receiving as MapMessage");
+ MapMessage m = (MapMessage)consumer.receive();
+ System.out.println(m);
+ System.out.println("==========================================");
+ System.out.println("Printing map contents:");
+ Enumeration keys = m.getMapNames();
+ while(keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ System.out.println(key + " => " + m.getObject(key));
+ }
+ }
+ else if (args[0].equals("-s")) {
+ System.out.println("Receiving as StreamMessage");
+ StreamMessage m = (StreamMessage)consumer.receive();
+ System.out.println(m);
+ System.out.println("==========================================");
+ System.out.println("Printing stream contents:");
+ try {
+ while(true)
+ System.out.println(m.readObject());
+ }
+ catch (MessageEOFException e) {
+ // DONE
+ }
+ }
+
+ connection.close();
+ }
+}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/ListSender.java b/java/client/example/src/main/java/org/apache/qpid/example/ListSender.java
new file mode 100644
index 0000000000..fe2c1ec472
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/ListSender.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.example;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.apache.qpid.client.AMQAnyDestination;
+import org.apache.qpid.client.AMQConnection;
+
+import org.apache.qpid.jms.ListMessage;
+
+
+public class ListSender {
+
+ public static void main(String[] args) throws Exception
+ {
+ Connection connection =
+ new AMQConnection("amqp://guest:guest@test/?brokerlist='tcp://localhost:5672'");
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Destination queue = new AMQAnyDestination("ADDR:message_queue; {create: always}");
+ MessageProducer producer = session.createProducer(queue);
+
+ ListMessage m = ((org.apache.qpid.jms.Session)session).createListMessage();
+ m.setIntProperty("Id", 987654321);
+ m.setStringProperty("name", "Widget");
+ m.setDoubleProperty("price", 0.99);
+
+ List<String> colors = new ArrayList<String>();
+ colors.add("red");
+ colors.add("green");
+ colors.add("white");
+ m.add(colors);
+
+ Map<String,Double> dimensions = new HashMap<String,Double>();
+ dimensions.put("length",10.2);
+ dimensions.put("width",5.1);
+ dimensions.put("depth",2.0);
+ m.add(dimensions);
+
+ List<List<Integer>> parts = new ArrayList<List<Integer>>();
+ parts.add(Arrays.asList(new Integer[] {1,2,5}));
+ parts.add(Arrays.asList(new Integer[] {8,2,5}));
+ m.add(parts);
+
+ Map<String,Object> specs = new HashMap<String,Object>();
+ specs.put("colours", colors);
+ specs.put("dimensions", dimensions);
+ specs.put("parts", parts);
+ m.add(specs);
+
+ producer.send((Message)m);
+ System.out.println("Sent: " + m);
+ connection.close();
+ }
+
+}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/Spout.java b/java/client/example/src/main/java/org/apache/qpid/example/Spout.java
index 61ff2dfc19..09e813f8c1 100644
--- a/java/client/example/src/main/java/org/apache/qpid/example/Spout.java
+++ b/java/client/example/src/main/java/org/apache/qpid/example/Spout.java
@@ -100,6 +100,7 @@ public class Spout extends OptionParser
System.out.println(msg);
System.out.println("-------------------------------\n");
}
+ producer.close();
ssn.close();
con.close();
}
diff --git a/java/client/src/main/java/client.bnd b/java/client/src/main/java/client.bnd
index 4b9b191520..0a47b30c72 100755
--- a/java/client/src/main/java/client.bnd
+++ b/java/client/src/main/java/client.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.19.0
+ver: 0.21.0
Bundle-SymbolicName: qpid-client
Bundle-Version: ${ver}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
index 89273599b9..597096db57 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
@@ -344,7 +344,14 @@ public class AMQBrokerDetails implements BrokerDetails
optionsURL.append("='");
- optionsURL.append(_options.get(key));
+ if (OPTIONS_TRUST_STORE_PASSWORD.equals(key) || OPTIONS_KEY_STORE_PASSWORD.equals(key))
+ {
+ optionsURL.append("********");
+ }
+ else
+ {
+ optionsURL.append(_options.get(key));
+ }
optionsURL.append("'");
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index d80858a7a1..9612417266 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -179,6 +179,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// new amqp-0-10 encoded format.
private boolean _useLegacyMapMessageFormat;
+ // Indicates whether to use the old stream message format or the
+ // new amqp-0-10 list encoded format.
+ private boolean _useLegacyStreamMessageFormat;
+
+ // When sending to a Queue destination for the first time, check that the queue is bound
+ private final boolean _validateQueueOnSend;
+
//used to track the last failover time for
//Address resolution purposes
private volatile long _lastFailoverTime = 0;
@@ -294,6 +301,30 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
_useLegacyMapMessageFormat = Boolean.getBoolean(ClientProperties.USE_LEGACY_MAP_MESSAGE_FORMAT);
}
+ if (connectionURL.getOption(ConnectionURL.OPTIONS_USE_LEGACY_STREAM_MESSAGE_FORMAT) != null)
+ {
+ _useLegacyStreamMessageFormat = Boolean.parseBoolean(
+ connectionURL.getOption(ConnectionURL.OPTIONS_USE_LEGACY_STREAM_MESSAGE_FORMAT));
+ }
+ else
+ {
+ // use the default value set for all connections
+ _useLegacyStreamMessageFormat = System.getProperty(ClientProperties.USE_LEGACY_STREAM_MESSAGE_FORMAT) == null ?
+ true : Boolean.getBoolean(ClientProperties.USE_LEGACY_STREAM_MESSAGE_FORMAT);
+ }
+
+ if(connectionURL.getOption(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND) != null)
+ {
+ _validateQueueOnSend = Boolean.parseBoolean(
+ connectionURL.getOption(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND));
+ }
+ else
+ {
+ _validateQueueOnSend =
+ Boolean.parseBoolean(System.getProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "false"));
+ }
+
+
String amqpVersion = System.getProperty((ClientProperties.AMQP_VERSION), "0-10");
if (_logger.isDebugEnabled())
{
@@ -1080,7 +1111,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return _started;
}
- protected final boolean isConnected()
+ public final boolean isConnected()
{
return _connected;
}
@@ -1425,7 +1456,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _delegate.getProtocolVersion();
}
-
+
public String getBrokerUUID()
{
if(getProtocolVersion().equals(ProtocolVersion.v0_10))
@@ -1498,6 +1529,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return _useLegacyMapMessageFormat;
}
+ public boolean isUseLegacyStreamMessageFormat()
+ {
+ return _useLegacyStreamMessageFormat;
+ }
+
private void verifyClientID() throws AMQException
{
if (Boolean.getBoolean(ClientProperties.QPID_VERIFY_CLIENT_ID))
@@ -1539,4 +1575,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
+ localAddress + " to " + remoteAddress);
}
}
+
+ void setHeartbeatListener(HeartbeatListener listener)
+ {
+ _delegate.setHeartbeatListener(listener);
+ }
+
+ public boolean validateQueueOnSend()
+ {
+ return _validateQueueOnSend;
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
index b6f25a2cef..a8fdaeb65c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
@@ -78,4 +78,6 @@ public interface AMQConnectionDelegate
* @return true if the feature is supported by the server
*/
boolean isSupportedServerFeature(final String featureName);
+
+ void setHeartbeatListener(HeartbeatListener listener);
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
index 51e7e4153d..69e79d42a0 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
@@ -33,6 +33,7 @@ import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ChannelLimitReachedException;
+import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.Session;
import org.apache.qpid.properties.ConnectionStartProperties;
import org.apache.qpid.protocol.AMQConstant;
@@ -214,7 +215,8 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
+ "********");
}
- ConnectionSettings conSettings = retriveConnectionSettings(brokerDetail);
+ ConnectionSettings conSettings = retrieveConnectionSettings(brokerDetail);
+
_qpidConnection.setConnectionDelegate(new ClientConnectionDelegate(conSettings, _conn.getConnectionURL()));
_qpidConnection.connect(conSettings);
@@ -420,7 +422,13 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
return featureSupported;
}
- private ConnectionSettings retriveConnectionSettings(BrokerDetails brokerDetail)
+ @Override
+ public void setHeartbeatListener(HeartbeatListener listener)
+ {
+ ((ClientConnectionDelegate)(_qpidConnection.getConnectionDelegate())).setHeartbeatListener(listener);
+ }
+
+ private ConnectionSettings retrieveConnectionSettings(BrokerDetails brokerDetail)
{
ConnectionSettings conSettings = brokerDetail.buildConnectionSettings();
@@ -442,6 +450,24 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
conSettings.setHeartbeatInterval(getHeartbeatInterval(brokerDetail));
+ //Check connection-level ssl override setting
+ String connectionSslOption = _conn.getConnectionURL().getOption(ConnectionURL.OPTIONS_SSL);
+ if(connectionSslOption != null)
+ {
+ boolean connUseSsl = Boolean.parseBoolean(connectionSslOption);
+ boolean brokerlistUseSsl = conSettings.isUseSSL();
+
+ if( connUseSsl != brokerlistUseSsl)
+ {
+ conSettings.setUseSSL(connUseSsl);
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Applied connection ssl option override, setting UseSsl to: " + connUseSsl );
+ }
+ }
+ }
+
return conSettings;
}
@@ -464,10 +490,14 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
heartbeat = Integer.getInteger(ClientProperties.IDLE_TIMEOUT_PROP_NAME)/1000;
_logger.warn("JVM arg -Didle_timeout=<mili_secs> is deprecated, please use -Dqpid.heartbeat=<secs>");
}
- else
+ else if(Integer.getInteger(ClientProperties.HEARTBEAT) != null)
{
heartbeat = Integer.getInteger(ClientProperties.HEARTBEAT,ClientProperties.HEARTBEAT_DEFAULT);
}
+ else
+ {
+ heartbeat = Integer.getInteger("amqj.heartbeat.delay", ClientProperties.HEARTBEAT_DEFAULT);
+ }
return heartbeat;
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index e1bf007e83..67d7c2a78c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -40,6 +40,7 @@ import org.apache.qpid.framing.TxSelectBody;
import org.apache.qpid.framing.TxSelectOkBody;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ChannelLimitReachedException;
+import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.ssl.SSLContextFactory;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.network.NetworkConnection;
@@ -90,42 +91,43 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws AMQException, IOException
{
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Connecting to broker:" + brokerDetail);
+ }
final Set<AMQState> openOrClosedStates =
EnumSet.of(AMQState.CONNECTION_OPEN, AMQState.CONNECTION_CLOSED);
-
- StateWaiter waiter = _conn.getProtocolHandler().createWaiter(openOrClosedStates);
-
ConnectionSettings settings = brokerDetail.buildConnectionSettings();
settings.setProtocol(brokerDetail.getTransport());
- SSLContext sslContext = null;
- if (settings.isUseSSL())
+ //Check connection-level ssl override setting
+ String connectionSslOption = _conn.getConnectionURL().getOption(ConnectionURL.OPTIONS_SSL);
+ if(connectionSslOption != null)
{
- try
- {
- sslContext = SSLContextFactory.buildClientContext(
- settings.getTrustStorePath(),
- settings.getTrustStorePassword(),
- settings.getTrustStoreType(),
- settings.getTrustManagerFactoryAlgorithm(),
- settings.getKeyStorePath(),
- settings.getKeyStorePassword(),
- settings.getKeyStoreType(),
- settings.getKeyManagerFactoryAlgorithm(),
- settings.getCertAlias());
- }
- catch (GeneralSecurityException e)
+ boolean connUseSsl = Boolean.parseBoolean(connectionSslOption);
+ boolean brokerlistUseSsl = settings.isUseSSL();
+
+ if( connUseSsl != brokerlistUseSsl)
{
- throw new AMQException("Unable to create SSLContext: " + e.getMessage(), e);
+ settings.setUseSSL(connUseSsl);
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Applied connection ssl option override, setting UseSsl to: " + connUseSsl );
+ }
}
}
SecurityLayer securityLayer = SecurityLayerFactory.newInstance(settings);
OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(getProtocolVersion());
- NetworkConnection network = transport.connect(settings, securityLayer.receiver(_conn.getProtocolHandler()), sslContext);
+
+ NetworkConnection network = transport.connect(settings, securityLayer.receiver(_conn.getProtocolHandler()),
+ _conn.getProtocolHandler());
_conn.getProtocolHandler().setNetworkConnection(network, securityLayer.sender(network.getSender()));
+
+ StateWaiter waiter = _conn.getProtocolHandler().createWaiter(openOrClosedStates);
_conn.getProtocolHandler().getProtocolSession().init();
// this blocks until the connection has been set up or when an error
// has prevented the connection being set up
@@ -376,4 +378,10 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
// we just hardcode JMS selectors as supported.
return ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR.equals(featureName);
}
+
+ @Override
+ public void setHeartbeatListener(HeartbeatListener listener)
+ {
+ _conn.getProtocolHandler().setHeartbeatListener(listener);
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java
index 8bc815d98e..a2d4b5ee17 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionFactory.java
@@ -140,7 +140,7 @@ public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionF
{
try
{
- ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.toString());
+ ConnectionURL connectionDetails = new AMQConnectionURL(_connectionDetails.getURL());
connectionDetails.setUsername(userName);
connectionDetails.setPassword(password);
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index 530186b1f9..f14b6d810b 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -52,6 +52,12 @@ public abstract class AMQDestination implements Destination, Referenceable
private AMQShortString _exchangeClass;
+ private boolean _exchangeAutoDelete;
+
+ private boolean _exchangeDurable;
+
+ private boolean _exchangeInternal;
+
private boolean _isDurable;
private boolean _isExclusive;
@@ -106,16 +112,6 @@ public abstract class AMQDestination implements Destination, Referenceable
_name = name;
}
- protected Link getTargetLink()
- {
- return _targetLink;
- }
-
- protected void setTargetLink(Link targetLink)
- {
- _targetLink = targetLink;
- }
-
// ----- Fields required to support new address syntax -------
public enum DestSyntax {
@@ -180,10 +176,9 @@ public abstract class AMQDestination implements Destination, Referenceable
private AddressOption _assert = AddressOption.NEVER;
private AddressOption _delete = AddressOption.NEVER;
- private Node _targetNode;
- private Node _sourceNode;
- private Link _targetLink;
+ private Node _node;
private Link _link;
+
// ----- / Fields required to support new address syntax -------
@@ -280,6 +275,9 @@ public abstract class AMQDestination implements Destination, Referenceable
{
_exchangeName = binding.getExchangeName();
_exchangeClass = binding.getExchangeClass();
+ _exchangeDurable = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCHANGE_DURABLE));
+ _exchangeAutoDelete = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCHANGE_AUTODELETE));
+ _exchangeInternal = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCHANGE_INTERNAL));
_isExclusive = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCLUSIVE));
_isAutoDelete = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_AUTODELETE));
@@ -358,6 +356,10 @@ public abstract class AMQDestination implements Destination, Referenceable
_destSyntax = DestSyntax.BURL;
_browseOnly = browseOnly;
_rejectBehaviour = null;
+ _exchangeAutoDelete = false;
+ _exchangeDurable = false;
+ _exchangeInternal = false;
+
if (_logger.isDebugEnabled())
{
_logger.debug("Based on " + toString() + " the selected destination syntax is " + _destSyntax);
@@ -412,6 +414,21 @@ public abstract class AMQDestination implements Destination, Referenceable
return _exchangeClass;
}
+ public boolean isExchangeDurable()
+ {
+ return _exchangeDurable;
+ }
+
+ public boolean isExchangeAutoDelete()
+ {
+ return _exchangeAutoDelete;
+ }
+
+ public boolean isExchangeInternal()
+ {
+ return _exchangeInternal;
+ }
+
public boolean isTopic()
{
return ExchangeDefaults.TOPIC_EXCHANGE_CLASS.equals(_exchangeClass);
@@ -579,6 +596,27 @@ public abstract class AMQDestination implements Destination, Referenceable
sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR);
}
+ if (_exchangeDurable)
+ {
+ sb.append(BindingURL.OPTION_EXCHANGE_DURABLE);
+ sb.append("='true'");
+ sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR);
+ }
+
+ if (_exchangeAutoDelete)
+ {
+ sb.append(BindingURL.OPTION_EXCHANGE_AUTODELETE);
+ sb.append("='true'");
+ sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR);
+ }
+
+ if (_exchangeInternal)
+ {
+ sb.append(BindingURL.OPTION_EXCHANGE_INTERNAL);
+ sb.append("='true'");
+ sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR);
+ }
+
//removeKey the last char '?' if there is no options , ',' if there are.
sb.deleteCharAt(sb.length() - 1);
url = sb.toString();
@@ -773,24 +811,14 @@ public abstract class AMQDestination implements Destination, Referenceable
_delete = option;
}
- public Node getTargetNode()
+ public Node getNode()
{
- return _targetNode;
+ return _node;
}
- public void setTargetNode(Node node)
+ public void setNode(Node node)
{
- _targetNode = node;
- }
-
- public Node getSourceNode()
- {
- return _sourceNode;
- }
-
- public void setSourceNode(Node node)
- {
- _sourceNode = node;
+ _node = node;
}
public Link getLink()
@@ -851,21 +879,11 @@ public abstract class AMQDestination implements Destination, Referenceable
_browseOnly = _addrHelper.isBrowseOnly();
- _addressType = _addrHelper.getTargetNodeType();
- _targetNode = _addrHelper.getTargetNode(_addressType);
- _sourceNode = _addrHelper.getSourceNode(_addressType);
+ _addressType = _addrHelper.getNodeType();
+ _node = _addrHelper.getNode();
_link = _addrHelper.getLink();
}
- // This method is needed if we didn't know the node type at the beginning.
- // Therefore we have to query the broker to figure out the type.
- // Once the type is known we look for the necessary properties.
- public void rebuildTargetAndSourceNodes(int addressType)
- {
- _targetNode = _addrHelper.getTargetNode(addressType);
- _sourceNode = _addrHelper.getSourceNode(addressType);
- }
-
// ----- / new address syntax -----------
public boolean isBrowseOnly()
@@ -900,8 +918,7 @@ public abstract class AMQDestination implements Destination, Referenceable
dest.setDelete(_delete);
dest.setBrowseOnly(_browseOnly);
dest.setAddressType(_addressType);
- dest.setTargetNode(_targetNode);
- dest.setSourceNode(_sourceNode);
+ dest.setNode(_node);
dest.setLink(_link);
dest.setAddressResolved(_addressResolved.get());
return dest;
@@ -935,6 +952,4 @@ public abstract class AMQDestination implements Destination, Referenceable
{
return _rejectBehaviour;
}
-
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 1468e90c4e..91a6389214 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -20,11 +20,6 @@
*/
package org.apache.qpid.client;
-import static org.apache.qpid.configuration.ClientProperties.DEFAULT_FLOW_CONTROL_WAIT_FAILURE;
-import static org.apache.qpid.configuration.ClientProperties.DEFAULT_FLOW_CONTROL_WAIT_NOTIFY_PERIOD;
-import static org.apache.qpid.configuration.ClientProperties.QPID_FLOW_CONTROL_WAIT_FAILURE;
-import static org.apache.qpid.configuration.ClientProperties.QPID_FLOW_CONTROL_WAIT_NOTIFY_PERIOD;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,6 +35,7 @@ import org.apache.qpid.client.failover.FailoverProtectedOperation;
import org.apache.qpid.client.failover.FailoverRetrySupport;
import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.AMQPEncodedMapMessage;
+import org.apache.qpid.client.message.AMQPEncodedListMessage;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.CloseConsumerMessage;
import org.apache.qpid.client.message.JMSBytesMessage;
@@ -49,14 +45,13 @@ import org.apache.qpid.client.message.JMSStreamMessage;
import org.apache.qpid.client.message.JMSTextMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.util.FlowControllingBlockingQueue;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.jms.Session;
+import org.apache.qpid.jms.ListMessage;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.SessionException;
@@ -122,27 +117,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/** Immediate message prefetch default. */
public static final String IMMEDIATE_PREFETCH_DEFAULT = "false";
- /**
- * The period to wait while flow controlled before sending a log message confirming that the session is still
- * waiting on flow control being revoked
- */
- private final long _flowControlWaitPeriod = Long.getLong(QPID_FLOW_CONTROL_WAIT_NOTIFY_PERIOD,
- DEFAULT_FLOW_CONTROL_WAIT_NOTIFY_PERIOD);
-
- /**
- * The period to wait while flow controlled before declaring a failure
- */
- private final long _flowControlWaitFailure = Long.getLong(QPID_FLOW_CONTROL_WAIT_FAILURE,
- DEFAULT_FLOW_CONTROL_WAIT_FAILURE);
-
private final boolean _delareQueues =
- Boolean.parseBoolean(System.getProperty("qpid.declare_queues", "true"));
+ Boolean.parseBoolean(System.getProperty(ClientProperties.QPID_DECLARE_QUEUES_PROP_NAME, "true"));
private final boolean _declareExchanges =
- Boolean.parseBoolean(System.getProperty("qpid.declare_exchanges", "true"));
+ Boolean.parseBoolean(System.getProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "true"));
private final boolean _useAMQPEncodedMapMessage;
+ private final boolean _useAMQPEncodedStreamMessage;
+
/**
* Flag indicating to start dispatcher as a daemon thread
*/
@@ -265,11 +249,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/** Has failover occured on this session with outstanding actions to commit? */
private boolean _failedOverDirty;
- /** Flow control */
- private FlowControlIndicator _flowControl = new FlowControlIndicator();
-
-
-
/** Holds the highest received delivery tag. */
protected AtomicLong getHighestDeliveryTag()
{
@@ -408,22 +387,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
}
- private static final class FlowControlIndicator
- {
- private volatile boolean _flowControl = true;
-
- public synchronized void setFlowControl(boolean flowControl)
- {
- _flowControl = flowControl;
- notify();
- }
-
- public boolean getFlowControl()
- {
- return _flowControl;
- }
- }
-
/**
* Creates a new session on a connection.
*
@@ -439,6 +402,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark)
{
_useAMQPEncodedMapMessage = con == null ? true : !con.isUseLegacyMapMessageFormat();
+ _useAMQPEncodedStreamMessage = con == null ? false : !con.isUseLegacyStreamMessageFormat();
_strictAMQP = Boolean.parseBoolean(System.getProperties().getProperty(STRICT_AMQP, STRICT_AMQP_DEFAULT));
_strictAMQPFATAL =
Boolean.parseBoolean(System.getProperties().getProperty(STRICT_AMQP_FATAL, STRICT_AMQP_FATAL_DEFAULT));
@@ -649,12 +613,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*/
public abstract void acknowledgeMessage(long deliveryTag, boolean multiple);
- public MethodRegistry getMethodRegistry()
- {
- MethodRegistry methodRegistry = getProtocolHandler().getMethodRegistry();
- return methodRegistry;
- }
-
/**
* Binds the named queue, with the specified routing key, to the named exchange.
*
@@ -1041,12 +999,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
try
{
- handleAddressBasedDestination(dest,false,noLocal,true);
+ resolveAddress(dest,false,noLocal);
if (dest.getAddressType() != AMQDestination.TOPIC_TYPE)
{
throw new JMSException("Durable subscribers can only be created for Topics");
}
- dest.getSourceNode().setDurable(true);
}
catch(AMQException e)
{
@@ -1158,6 +1115,14 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
}
+ public ListMessage createListMessage() throws JMSException
+ {
+ checkNotClosed();
+ AMQPEncodedListMessage msg = new AMQPEncodedListMessage(getMessageDelegateFactory());
+ msg.setAMQSession(this);
+ return msg;
+ }
+
public MapMessage createMapMessage() throws JMSException
{
checkNotClosed();
@@ -1400,17 +1365,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public StreamMessage createStreamMessage() throws JMSException
{
- // This method needs to be improved. Throwables only arrive here from the mina : exceptionRecived
- // calls through connection.closeAllSessions which is also called by the public connection.close()
- // with a null cause
- // When we are closing the Session due to a protocol session error we simply create a new AMQException
- // with the correct error code and text this is cleary WRONG as the instanceof check below will fail.
- // We need to determin here if the connection should be
-
- synchronized (getFailoverMutex())
+ checkNotClosed();
+ if (_useAMQPEncodedStreamMessage)
+ {
+ AMQPEncodedListMessage msg = new AMQPEncodedListMessage(getMessageDelegateFactory());
+ msg.setAMQSession(this);
+ return msg;
+ }
+ else
{
- checkNotClosed();
-
JMSStreamMessage msg = new JMSStreamMessage(getMessageDelegateFactory());
msg.setAMQSession(this);
return msg;
@@ -1550,7 +1513,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public void declareExchange(AMQShortString name, AMQShortString type, boolean nowait) throws AMQException
{
- declareExchange(name, type, getProtocolHandler(), nowait);
+ declareExchange(name, type, nowait, false, false, false);
}
abstract public void sync() throws AMQException;
@@ -1690,8 +1653,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
throws
AMQException
{
- AMQProtocolHandler protocolHandler = getProtocolHandler();
- declareExchange(amqd, protocolHandler, false);
+ declareExchange(amqd, false);
AMQShortString queueName = declareQueue(amqd, false);
bindQueue(queueName, amqd.getRoutingKey(), new FieldTable(), amqd.getExchangeName(), amqd);
}
@@ -2582,11 +2544,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/**
* Register to consume from the queue.
- *
* @param queueName
*/
- private void consumeFromQueue(C consumer, AMQShortString queueName,
- AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException, FailoverException
+ private void consumeFromQueue(C consumer, AMQShortString queueName, boolean nowait) throws AMQException, FailoverException
{
int tagId = _nextTag++;
@@ -2603,7 +2563,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
try
{
- sendConsume(consumer, queueName, protocolHandler, nowait, tagId);
+ sendConsume(consumer, queueName, nowait, tagId);
}
catch (AMQException e)
{
@@ -2614,7 +2574,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
public abstract void sendConsume(C consumer, AMQShortString queueName,
- AMQProtocolHandler protocolHandler, boolean nowait, int tag) throws AMQException, FailoverException;
+ boolean nowait, int tag) throws AMQException, FailoverException;
private P createProducerImpl(final Destination destination, final Boolean mandatory, final Boolean immediate)
throws JMSException
@@ -2648,9 +2608,10 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public abstract P createMessageProducer(final Destination destination, final Boolean mandatory,
final Boolean immediate, final long producerId) throws JMSException;
- private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException
+ private void declareExchange(AMQDestination amqd, boolean nowait) throws AMQException
{
- declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), protocolHandler, nowait);
+ declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), nowait, amqd.isExchangeDurable(),
+ amqd.isExchangeAutoDelete(), amqd.isExchangeInternal());
}
/**
@@ -2707,33 +2668,29 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
*
* @param name The name of the exchange to declare.
* @param type The type of the exchange to declare.
- * @param protocolHandler The protocol handler to process the communication through.
* @param nowait
- *
+ * @param durable
+ * @param autoDelete
+ * @param internal
* @throws AMQException If the exchange cannot be declared for any reason.
* @todo Be aware of possible changes to parameter order as versions change.
*/
private void declareExchange(final AMQShortString name, final AMQShortString type,
- final AMQProtocolHandler protocolHandler, final boolean nowait) throws AMQException
+ final boolean nowait, final boolean durable,
+ final boolean autoDelete, final boolean internal) throws AMQException
{
new FailoverNoopSupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>()
{
public Object execute() throws AMQException, FailoverException
{
- sendExchangeDeclare(name, type, protocolHandler, nowait);
+ sendExchangeDeclare(name, type, nowait, durable, autoDelete, internal);
return null;
}
}, _connection).execute();
}
- public abstract void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final AMQProtocolHandler protocolHandler,
- final boolean nowait) throws AMQException, FailoverException;
-
-
- void declareQueuePassive(AMQDestination queue) throws AMQException
- {
- declareQueue(queue,false,false,true);
- }
+ public abstract void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final boolean nowait,
+ boolean durable, boolean autoDelete, boolean internal) throws AMQException, FailoverException;
/**
* Declares a queue for a JMS destination.
@@ -2768,31 +2725,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return declareQueue(amqd, noLocal, nowait, false);
}
- protected AMQShortString declareQueue(final AMQDestination amqd,
- final boolean noLocal, final boolean nowait, final boolean passive)
- throws AMQException
- {
- final AMQProtocolHandler protocolHandler = getProtocolHandler();
- return new FailoverNoopSupport<AMQShortString, AMQException>(
- new FailoverProtectedOperation<AMQShortString, AMQException>()
- {
- public AMQShortString execute() throws AMQException, FailoverException
- {
- // Generate the queue name if the destination indicates that a client generated name is to be used.
- if (amqd.isNameRequired())
- {
- amqd.setQueueName(protocolHandler.generateQueueName());
- }
-
- sendQueueDeclare(amqd, protocolHandler, nowait, passive);
-
- return amqd.getAMQQueueName();
- }
- }, _connection).execute();
- }
-
- public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean nowait, boolean passive) throws AMQException, FailoverException;
+ protected abstract AMQShortString declareQueue(final AMQDestination amqd,
+ final boolean noLocal, final boolean nowait, final boolean passive) throws AMQException;
/**
* Undeclares the specified queue.
@@ -2845,21 +2779,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
return ++_nextProducerId;
}
- protected AMQProtocolHandler getProtocolHandler()
- {
- return _connection.getProtocolHandler();
- }
-
- public byte getProtocolMajorVersion()
- {
- return getProtocolHandler().getProtocolMajorVersion();
- }
-
- public byte getProtocolMinorVersion()
- {
- return getProtocolHandler().getProtocolMinorVersion();
- }
-
protected boolean hasMessageListeners()
{
return _hasMessageListeners;
@@ -2918,17 +2837,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
AMQDestination amqd = consumer.getDestination();
- AMQProtocolHandler protocolHandler = getProtocolHandler();
-
if (amqd.getDestSyntax() == DestSyntax.ADDR)
{
- handleAddressBasedDestination(amqd,true,consumer.isNoLocal(),nowait);
+ resolveAddress(amqd,true,consumer.isNoLocal());
}
else
{
if (_declareExchanges)
{
- declareExchange(amqd, protocolHandler, nowait);
+ declareExchange(amqd, nowait);
}
if (_delareQueues || amqd.isNameRequired())
@@ -2973,7 +2890,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
try
{
- consumeFromQueue(consumer, queueName, protocolHandler, nowait);
+ consumeFromQueue(consumer, queueName, nowait);
}
catch (FailoverException e)
{
@@ -2981,10 +2898,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
}
- public abstract void handleAddressBasedDestination(AMQDestination dest,
+ public abstract void resolveAddress(AMQDestination dest,
boolean isConsumer,
- boolean noLocal,
- boolean noWait) throws AMQException;
+ boolean noLocal) throws AMQException;
private void registerProducer(long producerId, MessageProducer producer)
{
@@ -3141,47 +3057,14 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
_ticket = ticket;
}
- public boolean isFlowBlocked()
- {
- synchronized (_flowControl)
- {
- return !_flowControl.getFlowControl();
- }
- }
-
- public void setFlowControl(final boolean active)
- {
- _flowControl.setFlowControl(active);
- if (_logger.isInfoEnabled())
- {
- _logger.info("Broker enforced flow control " + (active ? "no longer in effect" : "has been enforced"));
- }
- }
-
- public void checkFlowControl() throws InterruptedException, JMSException
- {
- long expiryTime = 0L;
- synchronized (_flowControl)
- {
- while (!_flowControl.getFlowControl() &&
- (expiryTime == 0L ? (expiryTime = System.currentTimeMillis() + _flowControlWaitFailure)
- : expiryTime) >= System.currentTimeMillis() )
- {
-
- _flowControl.wait(_flowControlWaitPeriod);
- if (_logger.isInfoEnabled())
- {
- _logger.info("Message send delayed by " + (System.currentTimeMillis() + _flowControlWaitFailure - expiryTime)/1000 + "s due to broker enforced flow control");
- }
- }
- if(!_flowControl.getFlowControl())
- {
- _logger.error("Message send failed due to timeout waiting on broker enforced flow control");
- throw new JMSException("Unable to send message for " + _flowControlWaitFailure /1000 + " seconds due to broker enforced flow control");
- }
- }
+ /**
+ * Tests whether flow to this session is blocked.
+ *
+ * @return true if flow is blocked or false otherwise.
+ */
+ public abstract boolean isFlowBlocked();
- }
+ public abstract void setFlowControl(final boolean active);
public interface Dispatchable
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
index 8a7c6b1a01..8490a724bf 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java
@@ -17,6 +17,11 @@
*/
package org.apache.qpid.client;
+import static org.apache.qpid.transport.Option.BATCH;
+import static org.apache.qpid.transport.Option.NONE;
+import static org.apache.qpid.transport.Option.SYNC;
+import static org.apache.qpid.transport.Option.UNRELIABLE;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
@@ -29,8 +34,10 @@ import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
+
import javax.jms.Destination;
import javax.jms.JMSException;
+
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.Binding;
@@ -44,18 +51,32 @@ import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_10;
import org.apache.qpid.client.messaging.address.AddressHelper;
import org.apache.qpid.client.messaging.address.Link;
-import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.messaging.address.Link.SubscriptionQueue;
+import org.apache.qpid.client.messaging.address.Node;
+import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.transport.*;
-import static org.apache.qpid.transport.Option.BATCH;
-import static org.apache.qpid.transport.Option.NONE;
-import static org.apache.qpid.transport.Option.SYNC;
-import static org.apache.qpid.transport.Option.UNRELIABLE;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ExchangeBoundResult;
+import org.apache.qpid.transport.ExchangeQueryResult;
+import org.apache.qpid.transport.ExecutionErrorCode;
+import org.apache.qpid.transport.ExecutionException;
+import org.apache.qpid.transport.MessageAcceptMode;
+import org.apache.qpid.transport.MessageAcquireMode;
+import org.apache.qpid.transport.MessageCreditUnit;
+import org.apache.qpid.transport.MessageFlowMode;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Option;
+import org.apache.qpid.transport.QueueQueryResult;
+import org.apache.qpid.transport.Range;
+import org.apache.qpid.transport.RangeSet;
+import org.apache.qpid.transport.RangeSetFactory;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionException;
+import org.apache.qpid.transport.SessionListener;
+import org.apache.qpid.transport.TransportException;
import org.apache.qpid.util.Serial;
import org.apache.qpid.util.Strings;
import org.slf4j.Logger;
@@ -347,15 +368,22 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
else
{
+ // Leaving this here to ensure the public method bindQueue in AMQSession.java works as expected.
List<Binding> bindings = new ArrayList<Binding>();
- bindings.addAll(destination.getSourceNode().getBindings());
- bindings.addAll(destination.getTargetNode().getBindings());
+ bindings.addAll(destination.getNode().getBindings());
String defaultExchange = destination.getAddressType() == AMQDestination.TOPIC_TYPE ?
destination.getAddressName(): "amq.topic";
for (Binding binding: bindings)
{
+ // Currently there is a bug (QPID-3317) with setting up and tearing down x-bindings for link.
+ // The null check below is a way to side step that issue while fixing QPID-4146
+ // Note this issue only affects producers.
+ if (binding.getQueue() == null && queueName == null)
+ {
+ continue;
+ }
String queue = binding.getQueue() == null?
queueName.asString(): binding.getQueue();
@@ -523,11 +551,9 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
final FieldTable rawSelector, final boolean noConsume,
final boolean autoClose) throws JMSException
{
-
- final AMQProtocolHandler protocolHandler = getProtocolHandler();
return new BasicMessageConsumer_0_10(getChannelId(), getAMQConnection(), destination, messageSelector, noLocal,
- getMessageFactoryRegistry(), this, protocolHandler, rawSelector, prefetchHigh,
- prefetchLow, exclusive, getAcknowledgeMode(), noConsume, autoClose);
+ getMessageFactoryRegistry(), this, rawSelector, prefetchHigh, prefetchLow,
+ exclusive, getAcknowledgeMode(), noConsume, autoClose);
}
/**
@@ -558,7 +584,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
rk = routingKey.toString();
}
- return isQueueBound(exchangeName.toString(),queueName.toString(),rk,null);
+ return isQueueBound(exchangeName == null ? null : exchangeName.toString(),queueName == null ? null : queueName.toString(),rk,null);
}
public boolean isQueueBound(final String exchangeName, final String queueName, final String bindingKey,Map<String,Object> args)
@@ -591,10 +617,22 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* This method is invoked when a consumer is created
* Registers the consumer with the broker
*/
- public void sendConsume(BasicMessageConsumer_0_10 consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler,
+ public void sendConsume(BasicMessageConsumer_0_10 consumer, AMQShortString queueName,
boolean nowait, int tag)
throws AMQException, FailoverException
- {
+ {
+ if (AMQDestination.DestSyntax.ADDR == consumer.getDestination().getDestSyntax())
+ {
+ if (AMQDestination.TOPIC_TYPE == consumer.getDestination().getAddressType())
+ {
+ String selector = consumer.getMessageSelectorFilter() == null? null : consumer.getMessageSelectorFilter().getSelector();
+
+ createSubscriptionQueue(consumer.getDestination(), consumer.isNoLocal(), selector);
+ queueName = consumer.getDestination().getAMQQueueName();
+ consumer.setQueuename(queueName);
+ }
+ handleLinkCreation(consumer.getDestination());
+ }
boolean preAcquire = consumer.isPreAcquire();
AMQDestination destination = consumer.getDestination();
@@ -637,11 +675,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
capacity,
Option.UNRELIABLE);
}
-
- if (!nowait)
- {
- sync();
- }
+ sync();
}
/**
@@ -653,7 +687,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
try
{
return new BasicMessageProducer_0_10(getAMQConnection(), (AMQDestination) destination, isTransacted(), getChannelId(), this,
- getProtocolHandler(), producerId, immediate, mandatory);
+ producerId, immediate, mandatory);
}
catch (AMQException e)
{
@@ -673,26 +707,25 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
/**
* creates an exchange if it does not already exist
*/
- public void sendExchangeDeclare(final AMQShortString name,
- final AMQShortString type,
- final AMQProtocolHandler protocolHandler, final boolean nowait)
- throws AMQException, FailoverException
+ public void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final boolean nowait,
+ boolean durable, boolean autoDelete, boolean internal) throws AMQException, FailoverException
{
- sendExchangeDeclare(name.asString(), type.asString(), null, null,
- nowait);
+ //The 'internal' parameter is ignored on the 0-10 path, the protocol does not support it
+ sendExchangeDeclare(name.asString(), type.asString(), null, null, nowait, durable, autoDelete);
}
public void sendExchangeDeclare(final String name, final String type,
final String alternateExchange, final Map<String, Object> args,
- final boolean nowait) throws AMQException
+ final boolean nowait, boolean durable, boolean autoDelete) throws AMQException
{
getQpidSession().exchangeDeclare(
name,
type,
alternateExchange,
args,
- name.toString().startsWith("amq.") ? Option.PASSIVE
- : Option.NONE);
+ name.toString().startsWith("amq.") ? Option.PASSIVE : Option.NONE,
+ durable ? Option.DURABLE : Option.NONE,
+ autoDelete ? Option.AUTO_DELETE : Option.NONE);
// We need to sync so that we get notify of an error.
if (!nowait)
{
@@ -717,18 +750,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
/**
* Declare a queue with the given queueName
*/
- public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean nowait, boolean passive)
- throws AMQException, FailoverException
- {
- // do nothing this is only used by 0_8
- }
-
- /**
- * Declare a queue with the given queueName
- */
- public AMQShortString send0_10QueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean noLocal, final boolean nowait, boolean passive)
+ public AMQShortString send0_10QueueDeclare(final AMQDestination amqd, final boolean noLocal,
+ final boolean nowait, boolean passive)
throws AMQException
{
AMQShortString queueName;
@@ -759,7 +782,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
else
{
- QueueNode node = (QueueNode)amqd.getSourceNode();
+ // This code is here to ensure address based destination work with the declareQueue public method in AMQSession.java
+ Node node = amqd.getNode();
Map<String,Object> arguments = new HashMap<String,Object>();
arguments.putAll((Map<? extends String, ? extends Object>) node.getDeclareArgs());
if (arguments == null || arguments.get(AddressHelper.NO_LOCAL) == null)
@@ -925,12 +949,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return getCurrentException();
}
+ @Override
protected AMQShortString declareQueue(final AMQDestination amqd,
final boolean noLocal, final boolean nowait, final boolean passive)
throws AMQException
{
- final AMQProtocolHandler protocolHandler = getProtocolHandler();
-
return new FailoverNoopSupport<AMQShortString, AMQException>(
new FailoverProtectedOperation<AMQShortString, AMQException>()
{
@@ -947,7 +970,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
amqd.setQueueName(new AMQShortString( binddingKey + "@"
+ amqd.getExchangeName().toString() + "_" + UUID.randomUUID()));
}
- return send0_10QueueDeclare(amqd, protocolHandler, noLocal, nowait, passive);
+ return send0_10QueueDeclare(amqd, noLocal, nowait, passive);
}
}, getAMQConnection()).execute();
}
@@ -1072,11 +1095,12 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return AMQMessageDelegateFactory.FACTORY_0_10;
}
- public boolean isExchangeExist(AMQDestination dest,ExchangeNode node,boolean assertNode)
+ public boolean isExchangeExist(AMQDestination dest,boolean assertNode) throws AMQException
{
boolean match = true;
ExchangeQueryResult result = getQpidSession().exchangeQuery(dest.getAddressName(), Option.NONE).get();
match = !result.getNotFound();
+ Node node = dest.getNode();
if (match)
{
@@ -1086,16 +1110,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
(node.getExchangeType() != null &&
node.getExchangeType().equals(result.getType())) &&
(matchProps(result.getArguments(),node.getDeclareArgs()));
- }
- else if (node.getExchangeType() != null)
- {
- // even if assert is false, better to verify this
- match = node.getExchangeType().equals(result.getType());
- if (!match)
- {
- _logger.debug("Exchange type doesn't match. Expected : " + node.getExchangeType() +
- " actual " + result.getType());
- }
}
else
{
@@ -1104,18 +1118,27 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
dest.setExchangeClass(new AMQShortString(result.getType()));
}
}
-
+
+ if (assertNode)
+ {
+ if (!match)
+ {
+ throw new AMQException("Assert failed for address : " + dest +", Result was : " + result);
+ }
+ }
+
return match;
}
- public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode) throws AMQException
+ public boolean isQueueExist(AMQDestination dest, boolean assertNode) throws AMQException
{
boolean match = true;
try
{
QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
match = dest.getAddressName().equals(result.getQueue());
-
+ Node node = dest.getNode();
+
if (match && assertNode)
{
match = (result.getDurable() == node.isDurable()) &&
@@ -1123,9 +1146,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
(result.getExclusive() == node.isExclusive()) &&
(matchProps(result.getArguments(),node.getDeclareArgs()));
}
- else if (match)
+
+ if (assertNode)
{
- // should I use the queried details to update the local data structure.
+ if (!match)
+ {
+ throw new AMQException("Assert failed for address : " + dest +", Result was : " + result);
+ }
}
}
catch(SessionException e)
@@ -1140,7 +1167,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
"Error querying queue",e);
}
}
-
return match;
}
@@ -1179,17 +1205,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
@SuppressWarnings("deprecation")
- public void handleAddressBasedDestination(AMQDestination dest,
+ public void resolveAddress(AMQDestination dest,
boolean isConsumer,
- boolean noLocal,
- boolean noWait) throws AMQException
+ boolean noLocal) throws AMQException
{
if (dest.isAddressResolved() && dest.isResolvedAfter(getAMQConnection().getLastFailoverTime()))
{
- if (isConsumer && AMQDestination.TOPIC_TYPE == dest.getAddressType())
- {
- createSubscriptionQueue(dest,noLocal);
- }
+ return;
}
else
{
@@ -1209,46 +1231,32 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
case AMQDestination.QUEUE_TYPE:
{
- if (isQueueExist(dest,(QueueNode)dest.getSourceNode(),assertNode))
+ if(createNode)
{
- setLegacyFiledsForQueueType(dest);
+ setLegacyFieldsForQueueType(dest);
+ handleQueueNodeCreation(dest,noLocal);
break;
}
- else if(createNode)
+ else if (isQueueExist(dest,assertNode))
{
- setLegacyFiledsForQueueType(dest);
- send0_10QueueDeclare(dest,null,noLocal,noWait, false);
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
+ setLegacyFieldsForQueueType(dest);
break;
- }
+ }
}
case AMQDestination.TOPIC_TYPE:
{
- if (isExchangeExist(dest,(ExchangeNode)dest.getTargetNode(),assertNode))
+ if(createNode)
{
setLegacyFiledsForTopicType(dest);
verifySubject(dest);
- if (isConsumer && !isQueueExist(dest,(QueueNode)dest.getSourceNode(),true))
- {
- createSubscriptionQueue(dest, noLocal);
- }
+ handleExchangeNodeCreation(dest);
break;
}
- else if(createNode)
+ else if (isExchangeExist(dest,assertNode))
{
setLegacyFiledsForTopicType(dest);
verifySubject(dest);
- sendExchangeDeclare(dest.getAddressName(),
- dest.getExchangeClass().asString(),
- dest.getTargetNode().getAlternateExchange(),
- dest.getTargetNode().getDeclareArgs(),
- false);
- if (isConsumer && !isQueueExist(dest,(QueueNode)dest.getSourceNode(),true))
- {
- createSubscriptionQueue(dest,noLocal);
- }
break;
}
}
@@ -1287,7 +1295,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
throw new AMQException("Ambiguous address, please specify queue or topic as node type");
}
dest.setAddressType(type);
- dest.rebuildTargetAndSourceNodes(type);
return type;
}
}
@@ -1309,30 +1316,45 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
}
}
}
-
- private void createSubscriptionQueue(AMQDestination dest, boolean noLocal) throws AMQException
+
+ void createSubscriptionQueue(AMQDestination dest, boolean noLocal, String messageSelector) throws AMQException
{
- QueueNode node = (QueueNode)dest.getSourceNode(); // source node is never null
-
- if (dest.getQueueName() == null)
+ Link link = dest.getLink();
+ String queueName = dest.getQueueName();
+
+ if (queueName == null)
{
- if (dest.getLink() != null && dest.getLink().getName() != null)
- {
- dest.setQueueName(new AMQShortString(dest.getLink().getName()));
- }
+ queueName = link.getName() == null ? "TempQueue" + UUID.randomUUID() : link.getName();
+ dest.setQueueName(new AMQShortString(queueName));
+ }
+
+ SubscriptionQueue queueProps = link.getSubscriptionQueue();
+ Map<String,Object> arguments = queueProps.getDeclareArgs();
+ if (!arguments.containsKey((AddressHelper.NO_LOCAL)))
+ {
+ arguments.put(AddressHelper.NO_LOCAL, noLocal);
+ }
+
+ if (link.isDurable() && queueName.startsWith("TempQueue"))
+ {
+ throw new AMQException("You cannot mark a subscription queue as durable without providing a name for the link.");
}
- node.setExclusive(true);
- node.setAutoDelete(!node.isDurable());
- send0_10QueueDeclare(dest,null,noLocal,true, false);
- getQpidSession().exchangeBind(dest.getQueueName(),
- dest.getAddressName(),
- dest.getSubject(),
- Collections.<String,Object>emptyMap());
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
+
+ getQpidSession().queueDeclare(queueName,
+ queueProps.getAlternateExchange(), arguments,
+ queueProps.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE,
+ link.isDurable() ? Option.DURABLE : Option.NONE,
+ queueProps.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
+
+ Map<String,Object> bindingArguments = new HashMap<String, Object>();
+ bindingArguments.put(AMQPFilterTypes.JMS_SELECTOR.getValue().toString(), messageSelector == null ? "" : messageSelector);
+ getQpidSession().exchangeBind(queueName,
+ dest.getAddressName(),
+ dest.getSubject(),
+ bindingArguments);
}
-
- public void setLegacyFiledsForQueueType(AMQDestination dest)
+
+ public void setLegacyFieldsForQueueType(AMQDestination dest)
{
// legacy support
dest.setQueueName(new AMQShortString(dest.getAddressName()));
@@ -1345,7 +1367,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
// legacy support
dest.setExchangeName(new AMQShortString(dest.getAddressName()));
- ExchangeNode node = (ExchangeNode)dest.getTargetNode();
+ Node node = dest.getNode();
dest.setExchangeClass(node.getExchangeType() == null?
ExchangeDefaults.TOPIC_EXCHANGE_CLASS:
new AMQShortString(node.getExchangeType()));
@@ -1424,6 +1446,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return _qpidSession.isFlowBlocked();
}
+ @Override
+ public void setFlowControl(boolean active)
+ {
+ // Supported by 0-8..0-9-1 only
+ throw new UnsupportedOperationException("Operation not supported by this protocol");
+ }
+
private void cancelTimerTask()
{
if (flushTask != null)
@@ -1432,5 +1461,148 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
flushTask = null;
}
}
-}
+ private void handleQueueNodeCreation(AMQDestination dest, boolean noLocal) throws AMQException
+ {
+ Node node = dest.getNode();
+ Map<String,Object> arguments = node.getDeclareArgs();
+ if (!arguments.containsKey((AddressHelper.NO_LOCAL)))
+ {
+ arguments.put(AddressHelper.NO_LOCAL, noLocal);
+ }
+ getQpidSession().queueDeclare(dest.getAddressName(),
+ node.getAlternateExchange(), arguments,
+ node.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE,
+ node.isDurable() ? Option.DURABLE : Option.NONE,
+ node.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
+
+ createBindings(dest, dest.getNode().getBindings());
+ sync();
+ }
+
+ void handleExchangeNodeCreation(AMQDestination dest) throws AMQException
+ {
+ Node node = dest.getNode();
+ sendExchangeDeclare(dest.getAddressName(),
+ node.getExchangeType(),
+ node.getAlternateExchange(),
+ node.getDeclareArgs(),
+ false,
+ node.isDurable(),
+ node.isAutoDelete());
+
+ // If bindings are specified without a queue name and is called by the producer,
+ // the broker will send an exception as expected.
+ createBindings(dest, dest.getNode().getBindings());
+ sync();
+ }
+
+ void handleLinkCreation(AMQDestination dest) throws AMQException
+ {
+ createBindings(dest, dest.getLink().getBindings());
+ }
+
+ void createBindings(AMQDestination dest, List<Binding> bindings)
+ {
+ String defaultExchangeForBinding = dest.getAddressType() == AMQDestination.TOPIC_TYPE ? dest
+ .getAddressName() : "amq.topic";
+
+ String defaultQueueName = null;
+ if (AMQDestination.QUEUE_TYPE == dest.getAddressType())
+ {
+ defaultQueueName = dest.getQueueName();
+ }
+ else
+ {
+ defaultQueueName = dest.getLink().getName() != null ? dest.getLink().getName() : dest.getQueueName();
+ }
+
+ for (Binding binding: bindings)
+ {
+ String queue = binding.getQueue() == null?
+ defaultQueueName: binding.getQueue();
+
+ String exchange = binding.getExchange() == null ?
+ defaultExchangeForBinding :
+ binding.getExchange();
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Binding queue : " + queue +
+ " exchange: " + exchange +
+ " using binding key " + binding.getBindingKey() +
+ " with args " + Strings.printMap(binding.getArgs()));
+ }
+ getQpidSession().exchangeBind(queue,
+ exchange,
+ binding.getBindingKey(),
+ binding.getArgs());
+ }
+ }
+
+ void handleLinkDelete(AMQDestination dest) throws AMQException
+ {
+ // We need to destroy link bindings
+ String defaultExchangeForBinding = dest.getAddressType() == AMQDestination.TOPIC_TYPE ? dest
+ .getAddressName() : "amq.topic";
+
+ String defaultQueueName = null;
+ if (AMQDestination.QUEUE_TYPE == dest.getAddressType())
+ {
+ defaultQueueName = dest.getQueueName();
+ }
+ else
+ {
+ defaultQueueName = dest.getLink().getName() != null ? dest.getLink().getName() : dest.getQueueName();
+ }
+
+ for (Binding binding: dest.getLink().getBindings())
+ {
+ String queue = binding.getQueue() == null?
+ defaultQueueName: binding.getQueue();
+
+ String exchange = binding.getExchange() == null ?
+ defaultExchangeForBinding :
+ binding.getExchange();
+
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Unbinding queue : " + queue +
+ " exchange: " + exchange +
+ " using binding key " + binding.getBindingKey() +
+ " with args " + Strings.printMap(binding.getArgs()));
+ }
+ getQpidSession().exchangeUnbind(queue, exchange,
+ binding.getBindingKey());
+ }
+ }
+
+ void deleteSubscriptionQueue(AMQDestination dest) throws AMQException
+ {
+ // We need to delete the subscription queue.
+ if (dest.getAddressType() == AMQDestination.TOPIC_TYPE &&
+ dest.getLink().getSubscriptionQueue().isExclusive() &&
+ isQueueExist(dest, false))
+ {
+ getQpidSession().queueDelete(dest.getQueueName());
+ }
+ }
+
+ void handleNodeDelete(AMQDestination dest) throws AMQException
+ {
+ if (AMQDestination.TOPIC_TYPE == dest.getAddressType())
+ {
+ if (isExchangeExist(dest,false))
+ {
+ getQpidSession().exchangeDelete(dest.getAddressName());
+ }
+ }
+ else
+ {
+ if (isQueueExist(dest,false))
+ {
+ getQpidSession().queueDelete(dest.getAddressName());
+ }
+ }
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
index 8ab23a240e..3097b33da3 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java
@@ -21,12 +21,18 @@
package org.apache.qpid.client;
+import static org.apache.qpid.configuration.ClientProperties.DEFAULT_FLOW_CONTROL_WAIT_FAILURE;
+import static org.apache.qpid.configuration.ClientProperties.DEFAULT_FLOW_CONTROL_WAIT_NOTIFY_PERIOD;
+import static org.apache.qpid.configuration.ClientProperties.QPID_FLOW_CONTROL_WAIT_FAILURE;
+import static org.apache.qpid.configuration.ClientProperties.QPID_FLOW_CONTROL_WAIT_NOTIFY_PERIOD;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUndeliveredException;
import org.apache.qpid.client.failover.FailoverException;
+import org.apache.qpid.client.failover.FailoverNoopSupport;
import org.apache.qpid.client.failover.FailoverProtectedOperation;
import org.apache.qpid.client.failover.FailoverRetrySupport;
import org.apache.qpid.client.message.AMQMessageDelegateFactory;
@@ -58,6 +64,27 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
/** Used for debugging. */
private static final Logger _logger = LoggerFactory.getLogger(AMQSession.class);
+ public static final String QPID_SYNC_AFTER_CLIENT_ACK = "qpid.sync_after_client.ack";
+
+ private final boolean _syncAfterClientAck =
+ Boolean.parseBoolean(System.getProperty(QPID_SYNC_AFTER_CLIENT_ACK, "true"));
+
+ /**
+ * The period to wait while flow controlled before sending a log message confirming that the session is still
+ * waiting on flow control being revoked
+ */
+ private final long _flowControlWaitPeriod = Long.getLong(QPID_FLOW_CONTROL_WAIT_NOTIFY_PERIOD,
+ DEFAULT_FLOW_CONTROL_WAIT_NOTIFY_PERIOD);
+
+ /**
+ * The period to wait while flow controlled before declaring a failure
+ */
+ private final long _flowControlWaitFailure = Long.getLong(QPID_FLOW_CONTROL_WAIT_FAILURE,
+ DEFAULT_FLOW_CONTROL_WAIT_FAILURE);
+
+ /** Flow control */
+ private FlowControlIndicator _flowControl = new FlowControlIndicator();
+
/**
* Creates a new session on a connection.
*
@@ -98,8 +125,9 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
return getProtocolHandler().getProtocolVersion();
}
- protected void acknowledgeImpl()
+ protected void acknowledgeImpl() throws JMSException
{
+ boolean syncRequired = false;
while (true)
{
Long tag = getUnacknowledgedMessageTags().poll();
@@ -109,6 +137,19 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
acknowledgeMessage(tag, false);
+ syncRequired = true;
+ }
+
+ try
+ {
+ if (syncRequired && _syncAfterClientAck)
+ {
+ sync();
+ }
+ }
+ catch (AMQException a)
+ {
+ throw new JMSAMQException("Failed to sync after acknowledge", a);
}
}
@@ -359,9 +400,9 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
}
- @Override public void sendConsume(BasicMessageConsumer_0_8 consumer,
+ @Override
+ public void sendConsume(BasicMessageConsumer_0_8 consumer,
AMQShortString queueName,
- AMQProtocolHandler protocolHandler,
boolean nowait,
int tag) throws AMQException, FailoverException
{
@@ -380,27 +421,29 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
if (nowait)
{
- protocolHandler.writeFrame(jmsConsume);
+ getProtocolHandler().writeFrame(jmsConsume);
}
else
{
- protocolHandler.syncWrite(jmsConsume, BasicConsumeOkBody.class);
+ getProtocolHandler().syncWrite(jmsConsume, BasicConsumeOkBody.class);
}
}
- public void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final AMQProtocolHandler protocolHandler,
- final boolean nowait) throws AMQException, FailoverException
+ @Override
+ public void sendExchangeDeclare(final AMQShortString name, final AMQShortString type, final boolean nowait,
+ boolean durable, boolean autoDelete, boolean internal) throws AMQException, FailoverException
{
+ //The 'noWait' parameter is only used on the 0-10 path, it is ignored on the 0-8/0-9/0-9-1 path
+
ExchangeDeclareBody body = getMethodRegistry().createExchangeDeclareBody(getTicket(),name,type,
name.toString().startsWith("amq."),
- false,false,false,false,null);
+ durable, autoDelete, internal, false, null);
AMQFrame exchangeDeclare = body.generateFrame(getChannelId());
- protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class);
+ getProtocolHandler().syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class);
}
- public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean nowait, boolean passive) throws AMQException, FailoverException
+ private void sendQueueDeclare(final AMQDestination amqd, boolean passive) throws AMQException, FailoverException
{
QueueDeclareBody body =
getMethodRegistry().createQueueDeclareBody(getTicket(),
@@ -414,7 +457,32 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
AMQFrame queueDeclare = body.generateFrame(getChannelId());
- protocolHandler.syncWrite(queueDeclare, QueueDeclareOkBody.class);
+ getProtocolHandler().syncWrite(queueDeclare, QueueDeclareOkBody.class);
+ }
+
+ @Override
+ protected AMQShortString declareQueue(final AMQDestination amqd, final boolean noLocal,
+ final boolean nowait, final boolean passive) throws AMQException
+ {
+ //The 'noWait' parameter is only used on the 0-10 path, it is ignored on the 0-8/0-9/0-9-1 path
+
+ final AMQProtocolHandler protocolHandler = getProtocolHandler();
+ return new FailoverNoopSupport<AMQShortString, AMQException>(
+ new FailoverProtectedOperation<AMQShortString, AMQException>()
+ {
+ public AMQShortString execute() throws AMQException, FailoverException
+ {
+ // Generate the queue name if the destination indicates that a client generated name is to be used.
+ if (amqd.isNameRequired())
+ {
+ amqd.setQueueName(protocolHandler.generateQueueName());
+ }
+
+ sendQueueDeclare(amqd, passive);
+
+ return amqd.getAMQQueueName();
+ }
+ }, getAMQConnection()).execute();
}
public void sendQueueDelete(final AMQShortString queueName) throws AMQException, FailoverException
@@ -440,10 +508,8 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
final int prefetchLow, final boolean noLocal, final boolean exclusive, String messageSelector, final FieldTable arguments,
final boolean noConsume, final boolean autoClose) throws JMSException
{
-
- final AMQProtocolHandler protocolHandler = getProtocolHandler();
return new BasicMessageConsumer_0_8(getChannelId(), getAMQConnection(), destination, messageSelector, noLocal,
- getMessageFactoryRegistry(),this, protocolHandler, arguments, prefetchHigh, prefetchLow,
+ getMessageFactoryRegistry(),this, arguments, prefetchHigh, prefetchLow,
exclusive, getAcknowledgeMode(), noConsume, autoClose);
}
@@ -629,12 +695,11 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
declareExchange(new AMQShortString("amq.direct"), new AMQShortString("direct"), false);
}
- public void handleAddressBasedDestination(AMQDestination dest,
+ public void resolveAddress(AMQDestination dest,
boolean isConsumer,
- boolean noLocal,
- boolean noWait) throws AMQException
+ boolean noLocal) throws AMQException
{
- throw new UnsupportedOperationException("The new addressing based sytanx is "
+ throw new UnsupportedOperationException("The new addressing based syntax is "
+ "not supported for AMQP 0-8/0-9 versions");
}
@@ -662,14 +727,23 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
queueName == null ? null : new AMQShortString(queueName),
bindingKey == null ? null : new AMQShortString(bindingKey));
}
-
+
+ private AMQProtocolHandler getProtocolHandler()
+ {
+ return getAMQConnection().getProtocolHandler();
+ }
+
+ public MethodRegistry getMethodRegistry()
+ {
+ MethodRegistry methodRegistry = getProtocolHandler().getMethodRegistry();
+ return methodRegistry;
+ }
public AMQException getLastException()
{
// if the Connection has closed then we should throw any exception that
// has occurred that we were not waiting for
- AMQStateManager manager = getAMQConnection().getProtocolHandler()
- .getStateManager();
+ AMQStateManager manager = getProtocolHandler().getStateManager();
Exception e = manager.getLastException();
if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED)
@@ -693,6 +767,49 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
}
+ public boolean isFlowBlocked()
+ {
+ synchronized (_flowControl)
+ {
+ return !_flowControl.getFlowControl();
+ }
+ }
+
+ public void setFlowControl(final boolean active)
+ {
+ _flowControl.setFlowControl(active);
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Broker enforced flow control " + (active ? "no longer in effect" : "has been enforced"));
+ }
+ }
+
+ void checkFlowControl() throws InterruptedException, JMSException
+ {
+ long expiryTime = 0L;
+ synchronized (_flowControl)
+ {
+ while (!_flowControl.getFlowControl() &&
+ (expiryTime == 0L ? (expiryTime = System.currentTimeMillis() + _flowControlWaitFailure)
+ : expiryTime) >= System.currentTimeMillis() )
+ {
+
+ _flowControl.wait(_flowControlWaitPeriod);
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Message send delayed by " + (System.currentTimeMillis() + _flowControlWaitFailure - expiryTime)/1000 + "s due to broker enforced flow control");
+ }
+ }
+ if(!_flowControl.getFlowControl())
+ {
+ _logger.error("Message send failed due to timeout waiting on broker enforced flow control");
+ throw new JMSException("Unable to send message for " + _flowControlWaitFailure /1000 + " seconds due to broker enforced flow control");
+ }
+ }
+ }
+
+
+
public abstract static class DestinationCache<T extends AMQDestination>
{
private final Map<AMQShortString, Map<AMQShortString, T>> cache = new HashMap<AMQShortString, Map<AMQShortString, T>>();
@@ -740,6 +857,22 @@ public class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
}
+ private static final class FlowControlIndicator
+ {
+ private volatile boolean _flowControl = true;
+
+ public synchronized void setFlowControl(boolean flowControl)
+ {
+ _flowControl = flowControl;
+ notify();
+ }
+
+ public boolean getFlowControl()
+ {
+ return _flowControl;
+ }
+ }
+
private final TopicDestinationCache _topicDestinationCache = new TopicDestinationCache();
private final QueueDestinationCache _queueDestinationCache = new QueueDestinationCache();
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
index f09ef5e01d..51b6c7e478 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
@@ -114,8 +114,8 @@ public class AMQTopic extends AMQDestination implements Topic
AMQShortString queueName = getDurableTopicQueueName(subscriptionName, connection);
// link is never null if dest was created using an address string.
t.getLink().setName(queueName.asString());
- t.getSourceNode().setAutoDelete(false);
- t.getSourceNode().setDurable(true);
+ t.getLink().getSubscriptionQueue().setAutoDelete(false);
+ t.getLink().setDurable(true);
// The legacy fields are also populated just in case.
t.setQueueName(queueName);
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
index 0f8b5717d6..b5e008da5a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
@@ -31,7 +31,6 @@ import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.CloseConsumerMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.client.filter.JMSSelectorFilter;
import org.apache.qpid.framing.AMQShortString;
@@ -87,8 +86,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
private final AMQSession _session;
- private final AMQProtocolHandler _protocolHandler;
-
/**
* We need to store the "raw" field table so that we can resubscribe in the event of failover being required
*/
@@ -140,9 +137,9 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
protected BasicMessageConsumer(int channelId, AMQConnection connection, AMQDestination destination,
String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory,
- AMQSession session, AMQProtocolHandler protocolHandler,
- FieldTable rawSelector, int prefetchHigh, int prefetchLow,
- boolean exclusive, int acknowledgeMode, boolean browseOnly, boolean autoClose) throws JMSException
+ AMQSession session, FieldTable rawSelector,
+ int prefetchHigh, int prefetchLow, boolean exclusive,
+ int acknowledgeMode, boolean browseOnly, boolean autoClose) throws JMSException
{
_channelId = channelId;
_connection = connection;
@@ -150,7 +147,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
_destination = destination;
_messageFactory = messageFactory;
_session = session;
- _protocolHandler = protocolHandler;
_prefetchHigh = prefetchHigh;
_prefetchLow = prefetchLow;
_exclusive = exclusive;
@@ -597,7 +593,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
{
sendCancel();
}
- cleanupQueue();
}
}
catch (AMQException e)
@@ -635,8 +630,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
abstract void sendCancel() throws AMQException, FailoverException;
-
- abstract void cleanupQueue() throws AMQException, FailoverException;
/**
* Called when you need to invalidate a consumer. Used for example when failover has occurred and the client has
@@ -1042,10 +1035,4 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
{
return _messageFactory;
}
-
- protected AMQProtocolHandler getProtocolHandler()
- {
- return _protocolHandler;
- }
-
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
index 26bb51b821..ef7b8cc217 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java
@@ -28,7 +28,6 @@ import org.apache.qpid.client.message.AMQMessageDelegate_0_10;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_10;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.common.ServerPropertyNames;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.jms.Session;
@@ -82,13 +81,13 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
protected BasicMessageConsumer_0_10(int channelId, AMQConnection connection, AMQDestination destination,
String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory,
- AMQSession<?,?> session, AMQProtocolHandler protocolHandler,
- FieldTable rawSelector, int prefetchHigh, int prefetchLow,
- boolean exclusive, int acknowledgeMode, boolean browseOnly, boolean autoClose)
+ AMQSession<?,?> session, FieldTable rawSelector,
+ int prefetchHigh, int prefetchLow, boolean exclusive,
+ int acknowledgeMode, boolean browseOnly, boolean autoClose)
throws JMSException
{
- super(channelId, connection, destination, messageSelector, noLocal, messageFactory, session, protocolHandler,
- rawSelector, prefetchHigh, prefetchLow, exclusive, acknowledgeMode, browseOnly, autoClose);
+ super(channelId, connection, destination, messageSelector, noLocal, messageFactory, session, rawSelector,
+ prefetchHigh, prefetchLow, exclusive, acknowledgeMode, browseOnly, autoClose);
_0_10session = (AMQSession_0_10) session;
_serverJmsSelectorSupport = connection.isSupportedServerFeature(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR);
@@ -96,6 +95,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
_capacity = evaluateCapacity(destination);
+ // This is due to the Destination carrying the temporary subscription name which is incorrect.
if (destination.isAddressResolved() && AMQDestination.TOPIC_TYPE == destination.getAddressType())
{
boolean namedQueue = destination.getLink() != null && destination.getLink().getName() != null ;
@@ -164,6 +164,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
@Override void sendCancel() throws AMQException
{
_0_10session.getQpidSession().messageCancel(getConsumerTagString());
+ postSubscription();
try
{
_0_10session.getQpidSession().sync();
@@ -500,7 +501,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
}
- void cleanupQueue() throws AMQException, FailoverException
+ void postSubscription() throws AMQException
{
AMQDestination dest = this.getDestination();
if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
@@ -508,9 +509,11 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
if (dest.getDelete() == AddressOption.ALWAYS ||
dest.getDelete() == AddressOption.RECEIVER )
{
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- this.getDestination().getQueueName());
+ ((AMQSession_0_10) getSession()).handleNodeDelete(dest);
+ ((AMQSession_0_10) getSession()).deleteSubscriptionQueue(dest);
}
+ // Subscription queue is handled as part of linkDelete method.
+ ((AMQSession_0_10) getSession()).handleLinkDelete(dest);
}
}
@@ -560,4 +563,4 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return capacity;
}
-}
+} \ No newline at end of file
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
index b00f9dd98a..f733e6bbca 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java
@@ -29,7 +29,6 @@ import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_8;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.framing.AMQFrame;
@@ -52,12 +51,12 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
protected BasicMessageConsumer_0_8(int channelId, AMQConnection connection, AMQDestination destination,
String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession_0_8 session,
- AMQProtocolHandler protocolHandler, FieldTable rawSelector, int prefetchHigh, int prefetchLow,
- boolean exclusive, int acknowledgeMode, boolean browseOnly, boolean autoClose) throws JMSException
+ FieldTable rawSelector, int prefetchHigh, int prefetchLow, boolean exclusive,
+ int acknowledgeMode, boolean browseOnly, boolean autoClose) throws JMSException
{
super(channelId, connection, destination,messageSelector,noLocal,messageFactory,session,
- protocolHandler, rawSelector, prefetchHigh, prefetchLow, exclusive,
- acknowledgeMode, browseOnly, autoClose);
+ rawSelector, prefetchHigh, prefetchLow, exclusive, acknowledgeMode,
+ browseOnly, autoClose);
final FieldTable consumerArguments = getArguments();
if (isAutoClose())
{
@@ -93,13 +92,19 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
}
}
+ @Override
+ public AMQSession_0_8 getSession()
+ {
+ return (AMQSession_0_8) super.getSession();
+ }
+
void sendCancel() throws AMQException, FailoverException
{
BasicCancelBody body = getSession().getMethodRegistry().createBasicCancelBody(new AMQShortString(String.valueOf(getConsumerTag())), false);
final AMQFrame cancelFrame = body.generateFrame(getChannelId());
- getProtocolHandler().syncWrite(cancelFrame, BasicCancelOkBody.class);
+ getConnection().getProtocolHandler().syncWrite(cancelFrame, BasicCancelOkBody.class);
if (_logger.isDebugEnabled())
{
@@ -122,11 +127,6 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
return receive();
}
- void cleanupQueue() throws AMQException, FailoverException
- {
-
- }
-
public RejectBehaviour getRejectBehaviour()
{
return _rejectBehaviour;
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
index 9b3b2ce0e9..98fa6de675 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.client;
-import java.io.UnsupportedEncodingException;
import java.util.UUID;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
@@ -36,15 +35,15 @@ import javax.jms.Topic;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.MessageConverter;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.transport.TransportException;
import org.apache.qpid.util.UUIDGen;
import org.apache.qpid.util.UUIDs;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public abstract class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer
{
+
+
enum PublishMode { ASYNC_PUBLISH_ALL, SYNC_PUBLISH_PERSISTENT, SYNC_PUBLISH_ALL };
private final Logger _logger ;
@@ -71,18 +70,6 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
private AMQDestination _destination;
/**
- * Default encoding used for messages produced by this producer.
- */
- private String _encoding;
-
- /**
- * Default encoding used for message produced by this producer.
- */
- private String _mimeType;
-
- private AMQProtocolHandler _protocolHandler;
-
- /**
* True if this producer was created from a transacted session
*/
private boolean _transacted;
@@ -135,14 +122,12 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
private PublishMode publishMode = PublishMode.ASYNC_PUBLISH_ALL;
protected BasicMessageProducer(Logger logger,AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
- AMQSession session, AMQProtocolHandler protocolHandler, long producerId,
- Boolean immediate, Boolean mandatory) throws AMQException
+ AMQSession session, long producerId, Boolean immediate, Boolean mandatory) throws AMQException
{
_logger = logger;
_connection = connection;
_destination = destination;
_transacted = transacted;
- _protocolHandler = protocolHandler;
_channelId = channelId;
_session = session;
_producerId = producerId;
@@ -163,6 +148,11 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
setPublishMode();
}
+ protected AMQConnection getConnection()
+ {
+ return _connection;
+ }
+
void setPublishMode()
{
// Publish mode could be configured at destination level as well.
@@ -303,7 +293,6 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
checkPreConditions();
checkInitialDestination();
-
synchronized (_connection.getFailoverMutex())
{
sendImpl(_destination, message, _deliveryMode, _messagePriority, _timeToLive, _mandatory, _immediate);
@@ -467,7 +456,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
JMSException ex = new JMSException("Error validating destination");
ex.initCause(e);
ex.setLinkedException(e);
-
+
throw ex;
}
amqDestination.setExchangeExistsChecked(true);
@@ -558,19 +547,7 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
}
}
- public void setMimeType(String mimeType) throws JMSException
- {
- checkNotClosed();
- _mimeType = mimeType;
- }
-
- public void setEncoding(String encoding) throws JMSException, UnsupportedEncodingException
- {
- checkNotClosed();
- _encoding = encoding;
- }
-
- private void checkPreConditions() throws javax.jms.IllegalStateException, JMSException
+ private void checkPreConditions() throws JMSException
{
checkNotClosed();
@@ -584,15 +561,16 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
}
}
- private void checkInitialDestination()
+ private void checkInitialDestination() throws JMSException
{
if (_destination == null)
{
throw new UnsupportedOperationException("Destination is null");
}
+ checkValidQueue();
}
- private void checkDestination(Destination suppliedDestination) throws InvalidDestinationException
+ private void checkDestination(Destination suppliedDestination) throws JMSException
{
if ((_destination != null) && (suppliedDestination != null))
{
@@ -600,6 +578,11 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
"This message producer was created with a Destination, therefore you cannot use an unidentified Destination");
}
+ if(suppliedDestination instanceof AMQQueue)
+ {
+ AMQQueue destination = (AMQQueue) suppliedDestination;
+ checkValidQueue(destination);
+ }
if (suppliedDestination == null)
{
throw new InvalidDestinationException("Supplied Destination was invalid");
@@ -607,6 +590,43 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
}
+ private void checkValidQueue() throws JMSException
+ {
+ if(_destination instanceof AMQQueue)
+ {
+ checkValidQueue((AMQQueue) _destination);
+ }
+ }
+
+ private void checkValidQueue(AMQQueue destination) throws JMSException
+ {
+ if (!destination.isCheckedForQueueBinding() && validateQueueOnSend())
+ {
+ if (getSession().isStrictAMQP())
+ {
+ getLogger().warn("AMQP does not support destination validation before publish");
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ if (isBound(destination))
+ {
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ throw new InvalidDestinationException("Queue: " + destination.getQueueName()
+ + " is not a valid destination (no binding on server)");
+ }
+ }
+ }
+ }
+
+ private boolean validateQueueOnSend()
+ {
+ return _connection.validateQueueOnSend();
+ }
+
/**
* The session used to create this producer
*/
@@ -645,16 +665,6 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
_destination = destination;
}
- protected AMQProtocolHandler getProtocolHandler()
- {
- return _protocolHandler;
- }
-
- protected void setProtocolHandler(AMQProtocolHandler protocolHandler)
- {
- _protocolHandler = protocolHandler;
- }
-
protected int getChannelId()
{
return _channelId;
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
index a3a1e9c28b..f717ca4655 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
@@ -27,7 +27,6 @@ import org.apache.qpid.client.message.AMQMessageDelegate_0_10;
import org.apache.qpid.client.message.AbstractJMSMessage;
import org.apache.qpid.client.message.QpidMessageProperties;
import org.apache.qpid.client.messaging.address.Link.Reliability;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
import org.apache.qpid.transport.MessageAcceptMode;
@@ -60,10 +59,9 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
private byte[] userIDBytes;
BasicMessageProducer_0_10(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
- AMQSession session, AMQProtocolHandler protocolHandler, long producerId,
- Boolean immediate, Boolean mandatory) throws AMQException
+ AMQSession session, long producerId, Boolean immediate, Boolean mandatory) throws AMQException
{
- super(_logger, connection, destination, transacted, channelId, session, protocolHandler, producerId, immediate, mandatory);
+ super(_logger, connection, destination, transacted, channelId, session, producerId, immediate, mandatory);
userIDBytes = Strings.toUTF8(getUserID());
}
@@ -79,14 +77,18 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
(name,
destination.getExchangeClass().toString(),
null, null,
- name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
+ name.startsWith("amq.") ? Option.PASSIVE : Option.NONE,
+ destination.isExchangeDurable() ? Option.DURABLE : Option.NONE,
+ destination.isExchangeAutoDelete() ? Option.AUTO_DELETE : Option.NONE);
}
}
else
{
try
{
- getSession().handleAddressBasedDestination(destination,false,false,false);
+ getSession().resolveAddress(destination,false,false);
+ ((AMQSession_0_10)getSession()).handleLinkCreation(destination);
+ ((AMQSession_0_10)getSession()).sync();
}
catch(Exception e)
{
@@ -251,25 +253,35 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
return getSession().isQueueBound(destination);
}
+ // We should have a close and closed method to distinguish between normal close
+ // and a close due to session or connection error.
@Override
public void close() throws JMSException
{
super.close();
AMQDestination dest = getAMQDestination();
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
+ AMQSession_0_10 ssn = (AMQSession_0_10) getSession();
+ if (!ssn.isClosed() && dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
{
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.SENDER )
+ try
{
- try
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- getAMQDestination().getQueueName());
- }
- catch(TransportException e)
+ if (dest.getDelete() == AddressOption.ALWAYS ||
+ dest.getDelete() == AddressOption.SENDER )
{
- throw getSession().toJMSException("Exception while closing producer:" + e.getMessage(), e);
+ ssn.handleNodeDelete(dest);
}
+ ssn.handleLinkDelete(dest);
+ }
+ catch(TransportException e)
+ {
+ throw getSession().toJMSException("Exception while closing producer:" + e.getMessage(), e);
+ }
+ catch (AMQException e)
+ {
+ JMSException ex = new JMSException("Exception while closing producer:" + e.getMessage());
+ ex.setLinkedException(e);
+ ex.initCause(e);
+ throw ex;
}
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
index 21ff6c877a..bb270b0878 100644
--- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
+++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_8.java
@@ -50,29 +50,28 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
BasicMessageProducer_0_8(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
AMQSession session, AMQProtocolHandler protocolHandler, long producerId, Boolean immediate, Boolean mandatory) throws AMQException
{
- super(_logger,connection, destination,transacted,channelId,session, protocolHandler, producerId, immediate, mandatory);
+ super(_logger,connection, destination,transacted,channelId,session, producerId, immediate, mandatory);
}
void declareDestination(AMQDestination destination)
{
-
- final MethodRegistry methodRegistry = getSession().getMethodRegistry();
- ExchangeDeclareBody body =
+ if(getSession().isDeclareExchanges())
+ {
+ final MethodRegistry methodRegistry = getSession().getMethodRegistry();
+ ExchangeDeclareBody body =
methodRegistry.createExchangeDeclareBody(getSession().getTicket(),
destination.getExchangeName(),
destination.getExchangeClass(),
destination.getExchangeName().toString().startsWith("amq."),
- false,
- false,
- false,
+ destination.isExchangeDurable(),
+ destination.isExchangeAutoDelete(),
+ destination.isExchangeInternal(),
true,
null);
- // Declare the exchange
- // Note that the durable and internal arguments are ignored since passive is set to false
-
- AMQFrame declare = body.generateFrame(getChannelId());
+ AMQFrame declare = body.generateFrame(getChannelId());
- getProtocolHandler().writeFrame(declare);
+ getConnection().getProtocolHandler().writeFrame(declare);
+ }
}
void sendMessage(AMQDestination destination, Message origMessage, AbstractJMSMessage message,
@@ -172,7 +171,7 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
throw jmse;
}
- getProtocolHandler().writeFrame(compositeFrame);
+ getConnection().getProtocolHandler().writeFrame(compositeFrame);
}
/**
@@ -234,4 +233,9 @@ public class BasicMessageProducer_0_8 extends BasicMessageProducer
return frameCount;
}
+ @Override
+ public AMQSession_0_8 getSession()
+ {
+ return (AMQSession_0_8) super.getSession();
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/HeartbeatListener.java b/java/client/src/main/java/org/apache/qpid/client/HeartbeatListener.java
new file mode 100644
index 0000000000..32a7cb0b73
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/HeartbeatListener.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.client;
+
+public interface HeartbeatListener
+{
+ void heartbeatReceived();
+
+ void heartbeatSent();
+
+ static final HeartbeatListener DEFAULT = new HeartbeatListener()
+ {
+ public void heartbeatReceived()
+ {
+ }
+
+ public void heartbeatSent()
+ {
+ }
+ };
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java b/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
index 05bd121bbd..e01ec8578d 100644
--- a/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
+++ b/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
@@ -88,7 +88,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic
*/
public void createSession()
{
- _qpidDtxSession = getQpidConnection().createSession(0);
+ _qpidDtxSession = getQpidConnection().createSession(0,true);
_qpidDtxSession.setSessionListener(this);
_qpidDtxSession.dtxSelect();
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java
index 2cf7b089eb..f038fc6e4f 100644
--- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.client.handler;
+import java.nio.ByteBuffer;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,6 +35,8 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ConnectionCloseBody;
import org.apache.qpid.framing.ConnectionCloseOkBody;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.TransportException;
public class ConnectionCloseMethodHandler implements StateAwareMethodListener<ConnectionCloseBody>
{
@@ -91,18 +95,24 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co
}
finally
{
+ Sender<ByteBuffer> sender = session.getSender();
if (error != null)
{
session.notifyError(error);
- }
-
- // Close the protocol Session, including any open TCP connections
- session.closeProtocolSession();
+ }
- // Closing the session should not introduce a race condition as this thread will continue to propgate any
- // exception in to the exceptionCaught method of the SessionHandler.
- // Any sessionClosed event should occur after this.
+ // Close the open TCP connection
+ try
+ {
+ sender.close();
+ }
+ catch(TransportException e)
+ {
+ //Ignore, they are already logged by the Sender and this
+ //is a connection-close being processed by the IoReceiver
+ //which will as it closes initiate failover if necessary.
+ }
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
index a0c3914127..94b835dd1a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
@@ -91,6 +91,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
private MessageProperties _messageProps;
private DeliveryProperties _deliveryProps;
+ private String _messageID;
protected AMQMessageDelegate_0_10()
{
@@ -171,8 +172,12 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
public String getJMSMessageID() throws JMSException
{
- UUID id = _messageProps.getMessageId();
- return id == null ? null : "ID:" + id;
+ if (_messageID == null && _messageProps.getMessageId() != null)
+ {
+ UUID id = _messageProps.getMessageId();
+ _messageID = "ID:" + id;
+ }
+ return _messageID;
}
public void setJMSMessageID(String messageId) throws JMSException
@@ -185,14 +190,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
if(messageId.startsWith("ID:"))
{
- try
- {
- _messageProps.setMessageId(UUID.fromString(messageId.substring(3)));
- }
- catch(IllegalArgumentException ex)
- {
- throw new JMSException("MessageId '"+messageId+"' is not of the correct format, it must be ID: followed by a UUID");
- }
+ _messageID = messageId;
}
else
{
@@ -201,6 +199,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
}
}
+ /* Used by the internal implementation */
public void setJMSMessageID(UUID messageId) throws JMSException
{
if(messageId == null)
@@ -344,7 +343,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
int type = ((AMQSession_0_10)getAMQSession()).resolveAddressType(amqd);
if (type == AMQDestination.QUEUE_TYPE)
{
- ((AMQSession_0_10)getAMQSession()).setLegacyFiledsForQueueType(amqd);
+ ((AMQSession_0_10)getAMQSession()).setLegacyFieldsForQueueType(amqd);
}
else
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessage.java
new file mode 100644
index 0000000000..1d2cb43322
--- /dev/null
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessage.java
@@ -0,0 +1,935 @@
+/*
+ * 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.client.message;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.AMQException;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.MessageEOFException;
+import java.lang.NumberFormatException;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class AMQPEncodedListMessage extends JMSStreamMessage implements
+ org.apache.qpid.jms.ListMessage, javax.jms.MapMessage
+{
+ private static final Logger _logger = LoggerFactory
+ .getLogger(AMQPEncodedListMessage.class);
+
+ public static final String MIME_TYPE = "amqp/list";
+
+ private List<Object> _list = new ArrayList<Object>();
+
+ public AMQPEncodedListMessage(AMQMessageDelegateFactory delegateFactory) throws JMSException
+ {
+ super(delegateFactory);
+ currentIndex = 0;
+ }
+
+ AMQPEncodedListMessage(AMQMessageDelegate delegate, ByteBuffer data)
+ throws AMQException
+ {
+ super(delegate, data);
+ if (data != null)
+ {
+ try
+ {
+ populateListFromData(data);
+ }
+ catch (JMSException je)
+ {
+ throw new AMQException(null,
+ "Error populating ListMessage from ByteBuffer", je);
+ }
+ }
+ currentIndex = 0;
+ }
+
+ public String toBodyString() throws JMSException
+ {
+ return _list == null ? "" : _list.toString();
+ }
+
+ protected String getMimeType()
+ {
+ return MIME_TYPE;
+ }
+
+ /* ListMessage Implementation. */
+ public boolean add(Object a) throws JMSException
+ {
+ checkWritable();
+ checkAllowedValue(a);
+ try
+ {
+ return _list.add(a);
+ }
+ catch (Exception e)
+ {
+ MessageFormatException ex = new MessageFormatException("Error adding to ListMessage");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+
+ }
+ }
+
+ public void add(int index, Object element) throws JMSException
+ {
+ checkWritable();
+ checkAllowedValue(element);
+ try
+ {
+ _list.add(index, element);
+ }
+ catch (Exception e)
+ {
+ MessageFormatException ex = new MessageFormatException("Error adding to ListMessage at "
+ + index);
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ }
+
+ public boolean contains(Object o) throws JMSException
+ {
+ try
+ {
+ return _list.contains(o);
+ }
+ catch (Exception e)
+ {
+ JMSException ex = new JMSException("Error when looking up object");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ }
+
+ public Object get(int index) throws JMSException
+ {
+ try
+ {
+ return _list.get(index);
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ MessageFormatException ex = new MessageFormatException(
+ "Error getting ListMessage element at " + index);
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ }
+
+ public int indexOf(Object o)
+ {
+ return _list.indexOf(o);
+ }
+
+ public Iterator iterator()
+ {
+ return _list.iterator();
+ }
+
+ public Object remove(int index) throws JMSException
+ {
+ checkWritable();
+ try
+ {
+ return _list.remove(index);
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ MessageFormatException ex = new MessageFormatException(
+ "Error removing ListMessage element at " + index);
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ }
+
+ public boolean remove(Object o) throws JMSException
+ {
+ checkWritable();
+ return _list.remove(o);
+ }
+
+ public Object set(int index, Object element) throws JMSException
+ {
+ checkWritable();
+ checkAllowedValue(element);
+ try
+ {
+ return _list.set(index, element);
+ }
+ catch (Exception e)
+ {
+ MessageFormatException ex = new MessageFormatException(
+ "Error setting ListMessage element at " + index);
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ }
+
+ public int size()
+ {
+ return _list.size();
+ }
+
+ public Object[] toArray()
+ {
+ return _list.toArray();
+ }
+
+ /* MapMessage Implementation */
+ private boolean isValidIndex(int index)
+ {
+ if (index >= 0 && index < size())
+ return true;
+
+ return false;
+ }
+
+ private int getValidIndex(String indexStr) throws JMSException
+ {
+ if ((indexStr == null) || indexStr.equals(""))
+ {
+ throw new IllegalArgumentException(
+ "Property name cannot be null, or the empty String.");
+ }
+
+ int index = 0;
+ try
+ {
+ index = Integer.parseInt(indexStr);
+ }
+ catch (NumberFormatException e)
+ {
+ JMSException ex = new JMSException("Invalid index string");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+ if (isValidIndex(index))
+ return index;
+
+ throw new MessageFormatException("Property " + indexStr
+ + " should be a valid index into the list of size " + size());
+ }
+
+ private void setGenericForMap(String propName, Object o)
+ throws JMSException
+ {
+ checkWritable();
+ int index = 0;
+ try
+ {
+ index = Integer.parseInt(propName);
+ }
+ catch (NumberFormatException e)
+ {
+ JMSException ex = new JMSException("The property name should be a valid index");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
+ }
+
+ if (isValidIndex(index))
+ remove(index);
+ add(index, o);
+ }
+
+ public boolean getBoolean(String propName) throws JMSException
+ {
+ return getBooleanImpl(getValidIndex(propName));
+ }
+
+ public byte getByte(String propName) throws JMSException
+ {
+ return getByteImpl(getValidIndex(propName));
+ }
+
+ public short getShort(String propName) throws JMSException
+ {
+ return getShortImpl(getValidIndex(propName));
+ }
+
+ public int getInt(String propName) throws JMSException
+ {
+ return getIntImpl(getValidIndex(propName));
+ }
+
+ public long getLong(String propName) throws JMSException
+ {
+ return getLongImpl(getValidIndex(propName));
+ }
+
+ public char getChar(String propName) throws JMSException
+ {
+ return getCharImpl(getValidIndex(propName));
+
+ }
+
+ public float getFloat(String propName) throws JMSException
+ {
+ return getFloatImpl(getValidIndex(propName));
+ }
+
+ public double getDouble(String propName) throws JMSException
+ {
+ return getDoubleImpl(getValidIndex(propName));
+ }
+
+ public String getString(String propName) throws JMSException
+ {
+ return getStringImpl(getValidIndex(propName));
+ }
+
+ public byte[] getBytes(String propName) throws JMSException
+ {
+ return getBytesImpl(getValidIndex(propName));
+ }
+
+ public Object getObject(String propName) throws JMSException
+ {
+ return get(getValidIndex(propName));
+ }
+
+ public Enumeration getMapNames() throws JMSException
+ {
+ List<String> names = new ArrayList<String>();
+ int i = 0;
+
+ while (i < size())
+ names.add(Integer.toString(i++));
+
+ return Collections.enumeration(names);
+ }
+
+ public void setBoolean(String propName, boolean b) throws JMSException
+ {
+ setGenericForMap(propName, b);
+ }
+
+ public void setByte(String propName, byte b) throws JMSException
+ {
+ setGenericForMap(propName, b);
+ }
+
+ public void setShort(String propName, short i) throws JMSException
+ {
+ setGenericForMap(propName, i);
+ }
+
+ public void setChar(String propName, char c) throws JMSException
+ {
+ setGenericForMap(propName, c);
+ }
+
+ public void setInt(String propName, int i) throws JMSException
+ {
+ setGenericForMap(propName, i);
+ }
+
+ public void setLong(String propName, long l) throws JMSException
+ {
+ setGenericForMap(propName, l);
+ }
+
+ public void setFloat(String propName, float v) throws JMSException
+ {
+ setGenericForMap(propName, v);
+ }
+
+ public void setDouble(String propName, double v) throws JMSException
+ {
+ setGenericForMap(propName, v);
+ }
+
+ public void setString(String propName, String string1) throws JMSException
+ {
+ setGenericForMap(propName, string1);
+ }
+
+ public void setBytes(String propName, byte[] bytes) throws JMSException
+ {
+ setGenericForMap(propName, bytes);
+ }
+
+ public void setBytes(String propName, byte[] bytes, int offset, int length)
+ throws JMSException
+ {
+ if ((offset == 0) && (length == bytes.length))
+ {
+ setBytes(propName, bytes);
+ }
+ else
+ {
+ byte[] newBytes = new byte[length];
+ System.arraycopy(bytes, offset, newBytes, 0, length);
+ setBytes(propName, newBytes);
+ }
+ }
+
+ public void setObject(String propName, Object value) throws JMSException
+ {
+ checkAllowedValue(value);
+ setGenericForMap(propName, value);
+ }
+
+ public boolean itemExists(String propName) throws JMSException
+ {
+ return isValidIndex(Integer.parseInt(propName));
+ }
+
+ // StreamMessage methods
+
+ private int currentIndex;
+
+ private static final String MESSAGE_EOF_EXCEPTION = "End of Stream (ListMessage) at index: ";
+
+ private void setGenericForStream(Object o) throws JMSException
+ {
+ checkWritable();
+ add(o);
+ currentIndex++;
+ }
+
+ @Override
+ public boolean readBoolean() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getBooleanImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public byte readByte() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getByteImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public int readBytes(byte[] value) throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ {
+ ByteBuffer res = ByteBuffer.wrap(getBytesImpl(currentIndex++));
+ res.get(value);
+ return value.length;
+ }
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public char readChar() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getCharImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public double readDouble() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getDoubleImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public float readFloat() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getFloatImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public int readInt() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getIntImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public long readLong() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getLongImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public Object readObject() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return get(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public short readShort() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getShortImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public String readString() throws JMSException
+ {
+ checkReadable();
+ if (isValidIndex(currentIndex))
+ return getStringImpl(currentIndex++);
+
+ throw new MessageEOFException(MESSAGE_EOF_EXCEPTION + currentIndex);
+ }
+
+ @Override
+ public void writeBoolean(boolean value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeByte(byte value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeBytes(byte[] value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeBytes(byte[] value, int offset, int length)
+ throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeChar(char value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeDouble(double value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeFloat(float value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeInt(int value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeLong(long value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeObject(Object value) throws JMSException
+ {
+ checkAllowedValue(value);
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeShort(short value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ @Override
+ public void writeString(String value) throws JMSException
+ {
+ setGenericForStream(value);
+ }
+
+ // Common methods
+
+ private void checkAllowedValue(Object value) throws MessageFormatException
+ {
+ if (((value instanceof Boolean) || (value instanceof Byte)
+ || (value instanceof Short) || (value instanceof Integer)
+ || (value instanceof Long) || (value instanceof Character)
+ || (value instanceof Float) || (value instanceof Double)
+ || (value instanceof String) || (value instanceof byte[])
+ || (value instanceof List) || (value instanceof Map)
+ || (value instanceof UUID) || (value == null)) == false)
+ {
+ throw new MessageFormatException("Invalid value " + value
+ + "of type " + value.getClass().getName() + ".");
+ }
+ }
+
+ @Override
+ public void reset()
+ {
+ currentIndex = 0;
+ setReadable(true);
+ }
+
+ @Override
+ public void clearBody() throws JMSException
+ {
+ super.clearBody();
+ _list.clear();
+ currentIndex = 0;
+ setReadable(false);
+ }
+
+ private boolean getBooleanImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Boolean)
+ {
+ return ((Boolean) value).booleanValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Boolean.valueOf((String) value);
+ }
+ catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName()
+ + " cannot be converted to boolean.");
+ }
+
+ private byte getByteImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Byte)
+ {
+ return ((Byte) value).byteValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Byte.valueOf((String) value).byteValue();
+ } catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName() + " cannot be converted to byte.");
+ }
+
+ private short getShortImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Short)
+ {
+ return ((Short) value).shortValue();
+ }
+ else if (value instanceof Byte)
+ {
+ return ((Byte) value).shortValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Short.valueOf((String) value).shortValue();
+ } catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName() + " cannot be converted to short.");
+ }
+
+ private int getIntImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Integer)
+ {
+ return ((Integer) value).intValue();
+ }
+
+ if (value instanceof Short)
+ {
+ return ((Short) value).intValue();
+ }
+
+ if (value instanceof Byte)
+ {
+ return ((Byte) value).intValue();
+ }
+
+ if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Integer.valueOf((String) value).intValue();
+ }
+ catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName() + " cannot be converted to int.");
+ }
+
+ private long getLongImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Long)
+ {
+ return ((Long) value).longValue();
+ } else if (value instanceof Integer)
+ {
+ return ((Integer) value).longValue();
+ }
+
+ if (value instanceof Short)
+ {
+ return ((Short) value).longValue();
+ }
+
+ if (value instanceof Byte)
+ {
+ return ((Byte) value).longValue();
+ } else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Long.valueOf((String) value).longValue();
+ } catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName() + " cannot be converted to long.");
+ }
+
+ private char getCharImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Character)
+ {
+ return ((Character) value).charValue();
+ } else if (value == null)
+ {
+ throw new NullPointerException("Property at " + index
+ + " has null value and therefore cannot "
+ + "be converted to char.");
+ } else
+ {
+ throw new MessageFormatException("Property at " + index
+ + " of type " + value.getClass().getName()
+ + " cannot be converted to a char.");
+ }
+ }
+
+ private float getFloatImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Float)
+ {
+ return ((Float) value).floatValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Float.valueOf((String) value).floatValue();
+ }
+ catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName() + " cannot be converted to float.");
+ }
+
+ private double getDoubleImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if (value instanceof Double)
+ {
+ return ((Double) value).doubleValue();
+ }
+ else if (value instanceof Float)
+ {
+ return ((Float) value).doubleValue();
+ }
+ else if ((value instanceof String) || (value == null))
+ {
+ try
+ {
+ return Double.valueOf((String) value).doubleValue();
+ }
+ catch (NumberFormatException e)
+ {
+ // FALLTHROUGH to exception
+ }
+ }
+
+ throw new MessageFormatException("Property at " + index + " of type "
+ + value.getClass().getName()
+ + " cannot be converted to double.");
+ }
+
+ private String getStringImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if ((value instanceof String) || (value == null))
+ {
+ return (String) value;
+ } else if (value instanceof byte[])
+ {
+ throw new MessageFormatException("Property at " + index
+ + " of type byte[] " + "cannot be converted to String.");
+ } else
+ {
+ return value.toString();
+ }
+ }
+
+ private byte[] getBytesImpl(int index) throws JMSException
+ {
+ Object value = get(index);
+
+ if ((value instanceof byte[]) || (value == null))
+ {
+ return (byte[]) value;
+ }
+ else
+ {
+ throw new MessageFormatException("Property at " + index
+ + " of type " + value.getClass().getName()
+ + " cannot be converted to byte[].");
+ }
+ }
+
+ protected void populateListFromData(ByteBuffer data) throws JMSException
+ {
+ if (data != null)
+ {
+ data.rewind();
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(data);
+ _list = decoder.readList();
+ }
+ else
+ {
+ _list.clear();
+ }
+ }
+
+ public ByteBuffer getData() throws JMSException
+ {
+ BBEncoder encoder = new BBEncoder(1024);
+ encoder.writeList(_list);
+ return encoder.segment();
+ }
+
+ public void setList(List<Object> l)
+ {
+ _list = l;
+ }
+
+ public List<Object> asList()
+ {
+ return _list;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessageFactory.java
index 8fef642eff..b503dccb91 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedListMessageFactory.java
@@ -1,3 +1,4 @@
+package org.apache.qpid.client.message;
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,37 +20,25 @@
*
*/
-package org.apache.qpid.server.configuration;
import org.apache.qpid.AMQException;
-public interface SessionConfig extends ConfiguredObject<SessionConfigType, SessionConfig>
-{
- VirtualHostConfig getVirtualHost();
-
- String getSessionName();
-
- int getChannel();
-
- ConnectionConfig getConnectionConfig();
-
- boolean isAttached();
-
- long getDetachedLifespan();
+import javax.jms.JMSException;
+import java.nio.ByteBuffer;
- Long getExpiryTime();
-
- Long getMaxClientRate();
-
- Long getTxnStarts();
-
- Long getTxnCommits();
-
- Long getTxnRejects();
-
- Long getTxnCount();
-
- boolean isTransactional();
-
- void mgmtClose() throws AMQException;
-} \ No newline at end of file
+public class AMQPEncodedListMessageFactory extends AbstractJMSMessageFactory
+{
+ @Override
+ protected AbstractJMSMessage createMessage(AMQMessageDelegate delegate,
+ ByteBuffer data) throws AMQException
+ {
+ return new AMQPEncodedListMessage(delegate,data);
+ }
+
+
+ public AbstractJMSMessage createMessage(
+ AMQMessageDelegateFactory delegateFactory) throws JMSException
+ {
+ return new AMQPEncodedListMessage(delegateFactory);
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
index 509fc9f7f1..c2a919c1c5 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java
@@ -196,7 +196,14 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
if (data != null && data.hasRemaining())
{
ClassLoadingAwareObjectInputStream in = new ClassLoadingAwareObjectInputStream(new ByteBufferInputStream(data));
- result = (Serializable) in.readObject();
+ try
+ {
+ result = (Serializable) in.readObject();
+ }
+ finally
+ {
+ in.close();
+ }
}
return result;
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java
index b958d89515..b1af262580 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSStreamMessage.java
@@ -44,7 +44,12 @@ public class JMSStreamMessage extends AbstractBytesTypedMessage implements Strea
}
+ JMSStreamMessage(AMQMessageDelegateFactory delegateFactory, ByteBuffer data) throws AMQException
+ {
+ super(delegateFactory, data!=null);
+ _typedBytesContentWriter = new TypedBytesContentWriter();
+ }
JMSStreamMessage(AMQMessageDelegate delegate, ByteBuffer data) throws AMQException
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
index fa39b4c93c..4154003b23 100644
--- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
+++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java
@@ -66,6 +66,7 @@ public class MessageFactoryRegistry
mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory());
mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory());
mf.registerFactory(AMQPEncodedMapMessage.MIME_TYPE, new AMQPEncodedMapMessageFactory());
+ mf.registerFactory(AMQPEncodedListMessage.MIME_TYPE, new AMQPEncodedListMessageFactory());
mf.registerFactory(null, mf._default);
return mf;
diff --git a/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java b/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
index 318fe32d36..72fc74e19c 100644
--- a/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
+++ b/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
@@ -20,21 +20,20 @@
*/
package org.apache.qpid.client.messaging.address;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQDestination.Binding;
import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.messaging.address.Link.Subscription;
-import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
+import org.apache.qpid.client.messaging.address.Link.SubscriptionQueue;
import org.apache.qpid.configuration.Accessor;
import org.apache.qpid.configuration.Accessor.MapAccessor;
import org.apache.qpid.messaging.Address;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
/**
* Utility class for extracting information from the address class
*/
@@ -68,58 +67,56 @@ public class AddressHelper
public static final String ARGUMENTS = "arguments";
public static final String RELIABILITY = "reliability";
- private Address address;
- private Accessor addressProps;
- private Accessor nodeProps;
- private Accessor linkProps;
+ private Address _address;
+ private Accessor _addressPropAccess;
+ private Accessor _nodePropAccess;
+ private Accessor _linkPropAccess;
+ private Map _addressPropMap;
+ private Map _nodePropMap;
+ private Map _linkPropMap;
public AddressHelper(Address address)
{
- this.address = address;
- addressProps = new MapAccessor(address.getOptions());
- Map node_props = address.getOptions() == null
+ this._address = address;
+ this._addressPropMap = address.getOptions();
+ this._addressPropAccess = new MapAccessor(_addressPropMap);
+ this._nodePropMap = address.getOptions() == null
|| address.getOptions().get(NODE) == null ? null
: (Map) address.getOptions().get(NODE);
- if (node_props != null)
+ if (_nodePropMap != null)
{
- nodeProps = new MapAccessor(node_props);
+ _nodePropAccess = new MapAccessor(_nodePropMap);
}
- Map link_props = address.getOptions() == null
+ this._linkPropMap = address.getOptions() == null
|| address.getOptions().get(LINK) == null ? null
: (Map) address.getOptions().get(LINK);
- if (link_props != null)
+ if (_linkPropMap != null)
{
- linkProps = new MapAccessor(link_props);
+ _linkPropAccess = new MapAccessor(_linkPropMap);
}
}
public String getCreate()
{
- return addressProps.getString(CREATE);
+ return _addressPropAccess.getString(CREATE);
}
public String getAssert()
{
- return addressProps.getString(ASSERT);
+ return _addressPropAccess.getString(ASSERT);
}
public String getDelete()
{
- return addressProps.getString(DELETE);
- }
-
- public boolean isNoLocal()
- {
- Boolean b = nodeProps.getBoolean(NO_LOCAL);
- return b == null ? false : b;
+ return _addressPropAccess.getString(DELETE);
}
public boolean isBrowseOnly()
{
- String mode = addressProps.getString(MODE);
+ String mode = _addressPropAccess.getString(MODE);
return mode != null && mode.equals(BROWSE) ? true : false;
}
@@ -127,7 +124,7 @@ public class AddressHelper
public List<Binding> getBindings(Map props)
{
List<Binding> bindings = new ArrayList<Binding>();
- List<Map> bindingList = (List<Map>) props.get(X_BINDINGS);
+ List<Map> bindingList = (props == null) ? Collections.EMPTY_LIST : (List<Map>) props.get(X_BINDINGS);
if (bindingList != null)
{
for (Map bindingMap : bindingList)
@@ -157,117 +154,70 @@ public class AddressHelper
}
}
- public int getTargetNodeType() throws Exception
+ public int getNodeType() throws Exception
{
- if (nodeProps == null || nodeProps.getString(TYPE) == null)
+ if (_nodePropAccess == null || _nodePropAccess.getString(TYPE) == null)
{
// need to query and figure out
return AMQDestination.UNKNOWN_TYPE;
- } else if (nodeProps.getString(TYPE).equals("queue"))
+ }
+ else if (_nodePropAccess.getString(TYPE).equals("queue"))
{
return AMQDestination.QUEUE_TYPE;
- } else if (nodeProps.getString(TYPE).equals("topic"))
+ }
+ else if (_nodePropAccess.getString(TYPE).equals("topic"))
{
return AMQDestination.TOPIC_TYPE;
- } else
+ }
+ else
{
throw new Exception("unkown exchange type");
}
}
- public Node getTargetNode(int addressType)
+ public Node getNode()
{
- // target node here is the default exchange
- if (nodeProps == null || addressType == AMQDestination.QUEUE_TYPE)
- {
- return new ExchangeNode();
- } else if (addressType == AMQDestination.TOPIC_TYPE)
- {
- Map node = (Map) address.getOptions().get(NODE);
- return createExchangeNode(node);
- } else
+ Node node = new Node(_address.getName());
+ if (_nodePropAccess != null)
{
- // don't know yet
- return null;
- }
- }
-
- private Node createExchangeNode(Map parent)
- {
- Map declareArgs = getDeclareArgs(parent);
- MapAccessor argsMap = new MapAccessor(declareArgs);
- ExchangeNode node = new ExchangeNode();
- node.setExchangeType(argsMap.getString(TYPE) == null ? null : argsMap
- .getString(TYPE));
- fillInCommonNodeArgs(node, parent, argsMap);
- return node;
- }
+ Map xDeclareMap = getDeclareArgs(_nodePropMap);
+ MapAccessor xDeclareMapAccessor = new MapAccessor(xDeclareMap);
- private Node createQueueNode(Map parent)
- {
- Map declareArgs = getDeclareArgs(parent);
- MapAccessor argsMap = new MapAccessor(declareArgs);
- QueueNode node = new QueueNode();
- node.setAlternateExchange(argsMap.getString(ALT_EXCHANGE));
- node.setExclusive(argsMap.getBoolean(EXCLUSIVE) == null ? false
- : argsMap.getBoolean(EXCLUSIVE));
- fillInCommonNodeArgs(node, parent, argsMap);
-
- return node;
- }
-
- private void fillInCommonNodeArgs(Node node, Map parent, MapAccessor argsMap)
- {
- node.setDurable(getDurability(parent));
- node.setAutoDelete(argsMap.getBoolean(AUTO_DELETE) == null ? false
- : argsMap.getBoolean(AUTO_DELETE));
- node.setAlternateExchange(argsMap.getString(ALT_EXCHANGE));
- node.setBindings(getBindings(parent));
- if (getDeclareArgs(parent).containsKey(ARGUMENTS))
- {
- node.setDeclareArgs((Map<String,Object>)getDeclareArgs(parent).get(ARGUMENTS));
+ node.setDurable(getBooleanProperty(_nodePropAccess,DURABLE,false));
+ node.setAutoDelete(getBooleanProperty(xDeclareMapAccessor,AUTO_DELETE,false));
+ node.setExclusive(getBooleanProperty(xDeclareMapAccessor,EXCLUSIVE,false));
+ node.setAlternateExchange(xDeclareMapAccessor.getString(ALT_EXCHANGE));
+ if (xDeclareMapAccessor.getString(TYPE) != null)
+ {
+ node.setExchangeType(xDeclareMapAccessor.getString(TYPE));
+ }
+ node.setBindings(getBindings(_nodePropMap));
+ if (!xDeclareMap.isEmpty() && xDeclareMap.containsKey(ARGUMENTS))
+ {
+ node.setDeclareArgs((Map<String,Object>)xDeclareMap.get(ARGUMENTS));
+ }
}
- }
-
- private boolean getDurability(Map map)
- {
- Accessor access = new MapAccessor(map);
- Boolean result = access.getBoolean(DURABLE);
- return (result == null) ? false : result.booleanValue();
+ return node;
}
- /**
- * if the type == queue x-declare args from the node props is used. if the
- * type == exchange x-declare args from the link props is used else just
- * create a default temp queue.
- */
- public Node getSourceNode(int addressType)
+ // This should really be in the Accessor interface
+ private boolean getBooleanProperty(Accessor access, String propName, boolean defaultValue)
{
- if (addressType == AMQDestination.QUEUE_TYPE && nodeProps != null)
- {
- return createQueueNode((Map) address.getOptions().get(NODE));
- }
- if (addressType == AMQDestination.TOPIC_TYPE && linkProps != null)
- {
- return createQueueNode((Map) address.getOptions().get(LINK));
- } else
- {
- // need to query the info
- return new QueueNode();
- }
+ Boolean result = access.getBoolean(propName);
+ return (result == null) ? defaultValue : result.booleanValue();
}
public Link getLink() throws Exception
{
Link link = new Link();
link.setSubscription(new Subscription());
- if (linkProps != null)
+ link.setSubscriptionQueue(new SubscriptionQueue());
+ if (_linkPropAccess != null)
{
- link.setDurable(linkProps.getBoolean(DURABLE) == null ? false
- : linkProps.getBoolean(DURABLE));
- link.setName(linkProps.getString(NAME));
+ link.setDurable(getBooleanProperty(_linkPropAccess,DURABLE,false));
+ link.setName(_linkPropAccess.getString(NAME));
- String reliability = linkProps.getString(RELIABILITY);
+ String reliability = _linkPropAccess.getString(RELIABILITY);
if ( reliability != null)
{
if (reliability.equalsIgnoreCase("unreliable"))
@@ -283,13 +233,12 @@ public class AddressHelper
throw new Exception("The reliability mode '" +
reliability + "' is not yet supported");
}
-
}
- if (((Map) address.getOptions().get(LINK)).get(CAPACITY) instanceof Map)
+ if (((Map) _address.getOptions().get(LINK)).get(CAPACITY) instanceof Map)
{
MapAccessor capacityProps = new MapAccessor(
- (Map) ((Map) address.getOptions().get(LINK))
+ (Map) ((Map) _address.getOptions().get(LINK))
.get(CAPACITY));
link
.setConsumerCapacity(capacityProps
@@ -302,17 +251,19 @@ public class AddressHelper
}
else
{
- int cap = linkProps.getInt(CAPACITY) == null ? 0 : linkProps
+ int cap = _linkPropAccess.getInt(CAPACITY) == null ? 0 : _linkPropAccess
.getInt(CAPACITY);
link.setConsumerCapacity(cap);
link.setProducerCapacity(cap);
}
- link.setFilter(linkProps.getString(FILTER));
+ link.setFilter(_linkPropAccess.getString(FILTER));
// so far filter type not used
- if (((Map) address.getOptions().get(LINK)).containsKey(X_SUBSCRIBE))
+ Map linkMap = (Map) _address.getOptions().get(LINK);
+
+ if (linkMap != null && linkMap.containsKey(X_SUBSCRIBE))
{
- Map x_subscribe = (Map)((Map) address.getOptions().get(LINK)).get(X_SUBSCRIBE);
+ Map x_subscribe = (Map)((Map) _address.getOptions().get(LINK)).get(X_SUBSCRIBE);
if (x_subscribe.containsKey(ARGUMENTS))
{
@@ -324,6 +275,18 @@ public class AddressHelper
link.getSubscription().setExclusive(exclusive);
}
+
+ link.setBindings(getBindings(linkMap));
+ Map xDeclareMap = getDeclareArgs(linkMap);
+ SubscriptionQueue queue = link.getSubscriptionQueue();
+ if (!xDeclareMap.isEmpty() && xDeclareMap.containsKey(ARGUMENTS))
+ {
+ MapAccessor xDeclareMapAccessor = new MapAccessor(xDeclareMap);
+ queue.setAutoDelete(getBooleanProperty(xDeclareMapAccessor,AUTO_DELETE,true));
+ queue.setExclusive(getBooleanProperty(xDeclareMapAccessor,EXCLUSIVE,true));
+ queue.setAlternateExchange(xDeclareMapAccessor.getString(ALT_EXCHANGE));
+ queue.setDeclareArgs((Map<String,Object>)xDeclareMap.get(ARGUMENTS));
+ }
}
return link;
diff --git a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
index 41f6725c8f..40a84ebd02 100644
--- a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
+++ b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
@@ -20,9 +20,14 @@
*/
package org.apache.qpid.client.messaging.address;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.qpid.client.AMQDestination.Binding;
+
public class Link
{
public enum FilterType { SQL92, XQUERY, SUBJECT }
@@ -36,10 +41,11 @@ public class Link
private boolean _isDurable;
private int _consumerCapacity = 0;
private int _producerCapacity = 0;
- private Node node;
private Subscription subscription;
private Reliability reliability = Reliability.AT_LEAST_ONCE;
-
+ private List<Binding> _bindings = new ArrayList<Binding>();
+ private SubscriptionQueue _subscriptionQueue;
+
public Reliability getReliability()
{
return reliability;
@@ -50,21 +56,11 @@ public class Link
this.reliability = reliability;
}
- public Node getNode()
- {
- return node;
- }
-
- public void setNode(Node node)
- {
- this.node = node;
- }
-
public boolean isDurable()
{
return _isDurable;
}
-
+
public void setDurable(boolean durable)
{
_isDurable = durable;
@@ -139,6 +135,74 @@ public class Link
{
this.subscription = subscription;
}
+
+ public List<Binding> getBindings()
+ {
+ return _bindings;
+ }
+
+ public void setBindings(List<Binding> bindings)
+ {
+ _bindings = bindings;
+ }
+
+ public SubscriptionQueue getSubscriptionQueue()
+ {
+ return _subscriptionQueue;
+ }
+
+ public void setSubscriptionQueue(SubscriptionQueue subscriptionQueue)
+ {
+ this._subscriptionQueue = subscriptionQueue;
+ }
+
+ public static class SubscriptionQueue
+ {
+ private Map<String,Object> _declareArgs = new HashMap<String,Object>();
+ private boolean _isAutoDelete = true;
+ private boolean _isExclusive = true;
+ private String _alternateExchange;
+
+ public Map<String,Object> getDeclareArgs()
+ {
+ return _declareArgs;
+ }
+
+ public void setDeclareArgs(Map<String,Object> options)
+ {
+ _declareArgs = options;
+ }
+
+ public boolean isAutoDelete()
+ {
+ return _isAutoDelete;
+ }
+
+ public void setAutoDelete(boolean autoDelete)
+ {
+ _isAutoDelete = autoDelete;
+ }
+
+ public boolean isExclusive()
+ {
+ return _isExclusive;
+ }
+
+ public void setExclusive(boolean exclusive)
+ {
+ _isExclusive = exclusive;
+ }
+
+ public String getAlternateExchange()
+ {
+ return _alternateExchange;
+ }
+
+ public void setAlternateExchange(String altExchange)
+ {
+ _alternateExchange = altExchange;
+ }
+ }
public static class Subscription
{
diff --git a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Node.java b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Node.java
index 0da0327885..005f98f344 100644
--- a/java/client/src/main/java/org/apache/qpid/client/messaging/address/Node.java
+++ b/java/client/src/main/java/org/apache/qpid/client/messaging/address/Node.java
@@ -26,19 +26,33 @@ import org.apache.qpid.client.AMQDestination.Binding;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public abstract class Node
+public class Node
{
private int _nodeType = AMQDestination.UNKNOWN_TYPE;
+ private String _name;
private boolean _isDurable;
private boolean _isAutoDelete;
+ private boolean _isExclusive;
private String _alternateExchange;
+ private String _exchangeType = "topic"; // used when node is an exchange instead of a queue.
private List<Binding> _bindings = new ArrayList<Binding>();
- private Map<String,Object> _declareArgs = Collections.emptyMap();
+ private Map<String,Object> _declareArgs = new HashMap<String,Object>();
- protected Node(int nodeType)
+ protected Node(String name)
+ {
+ _name = name;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public void setNodeType(int nodeType)
{
_nodeType = nodeType;
}
@@ -58,6 +72,16 @@ public abstract class Node
_isDurable = durable;
}
+ public boolean isExclusive()
+ {
+ return _isExclusive;
+ }
+
+ public void setExclusive(boolean exclusive)
+ {
+ _isExclusive = exclusive;
+ }
+
public boolean isAutoDelete()
{
return _isAutoDelete;
@@ -100,56 +124,15 @@ public abstract class Node
public void setDeclareArgs(Map<String,Object> options)
{
_declareArgs = options;
- }
-
- public static class QueueNode extends Node
- {
- private boolean _isExclusive;
- private QpidQueueOptions _queueOptions = new QpidQueueOptions();
-
- public QueueNode()
- {
- super(AMQDestination.QUEUE_TYPE);
- }
-
- public boolean isExclusive()
- {
- return _isExclusive;
- }
-
- public void setExclusive(boolean exclusive)
- {
- _isExclusive = exclusive;
- }
}
-
- public static class ExchangeNode extends Node
- {
- private QpidExchangeOptions _exchangeOptions = new QpidExchangeOptions();
- private String _exchangeType;
-
- public ExchangeNode()
- {
- super(AMQDestination.TOPIC_TYPE);
- }
-
- public String getExchangeType()
- {
- return _exchangeType;
- }
-
- public void setExchangeType(String exchangeType)
- {
- _exchangeType = exchangeType;
- }
-
+
+ public void setExchangeType(String type)
+ {
+ _exchangeType = type;
}
-
- public static class UnknownNodeType extends Node
+
+ public String getExchangeType()
{
- public UnknownNodeType()
- {
- super(AMQDestination.UNKNOWN_TYPE);
- }
+ return _exchangeType;
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
index b314453e31..816caac824 100644
--- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.client.protocol;
+import org.apache.qpid.client.HeartbeatListener;
import org.apache.qpid.util.BytesDataOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,6 +57,7 @@ import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.TransportException;
import org.apache.qpid.transport.network.NetworkConnection;
import java.io.IOException;
@@ -177,6 +179,9 @@ public class AMQProtocolHandler implements ProtocolEngine
private NetworkConnection _network;
private Sender<ByteBuffer> _sender;
+ private long _lastReadTime = System.currentTimeMillis();
+ private long _lastWriteTime = System.currentTimeMillis();
+ private HeartbeatListener _heartbeatListener = HeartbeatListener.DEFAULT;
/**
* Creates a new protocol handler, associated with the specified client connection instance.
@@ -210,48 +215,67 @@ public class AMQProtocolHandler implements ProtocolEngine
}
else
{
- _logger.debug("Session closed called with failover state currently " + _failoverState);
-
- // reconnetablility was introduced here so as not to disturb the client as they have made their intentions
- // known through the policy settings.
-
- if ((_failoverState != FailoverState.IN_PROGRESS) && _connection.failoverAllowed())
+ // Use local variable to keep flag whether fail-over allowed or not,
+ // in order to execute AMQConnection#exceptionRecievedout out of synchronization block,
+ // otherwise it might deadlock with failover mutex
+ boolean failoverNotAllowed = false;
+ synchronized (this)
{
- _logger.debug("FAILOVER STARTING");
- if (_failoverState == FailoverState.NOT_STARTED)
- {
- _failoverState = FailoverState.IN_PROGRESS;
- startFailoverThread();
- }
- else
- {
- _logger.debug("Not starting failover as state currently " + _failoverState);
- }
- }
- else
- {
- _logger.debug("Failover not allowed by policy."); // or already in progress?
-
if (_logger.isDebugEnabled())
{
- _logger.debug(_connection.getFailoverPolicy().toString());
+ _logger.debug("Session closed called with failover state " + _failoverState);
}
- if (_failoverState != FailoverState.IN_PROGRESS)
+ // reconnetablility was introduced here so as not to disturb the client as they have made their intentions
+ // known through the policy settings.
+ if (_failoverState == FailoverState.NOT_STARTED)
{
- _logger.debug("sessionClose() not allowed to failover");
- _connection.exceptionReceived(new AMQDisconnectedException(
- "Server closed connection and reconnection " + "not permitted.",
- _stateManager.getLastException()));
+ // close the sender
+ try
+ {
+ _sender.close();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Exception occured on closing the sender", e);
+ }
+ if (_connection.failoverAllowed())
+ {
+ _failoverState = FailoverState.IN_PROGRESS;
+
+ _logger.debug("FAILOVER STARTING");
+ startFailoverThread();
+ }
+ else if (_connection.isConnected())
+ {
+ failoverNotAllowed = true;
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Failover not allowed by policy:" + _connection.getFailoverPolicy());
+ }
+ }
+ else
+ {
+ _logger.debug("We are in process of establishing the initial connection");
+ }
}
else
{
- _logger.debug("sessionClose() failover in progress");
+ _logger.debug("Not starting the failover thread as state currently " + _failoverState);
}
}
+
+ if (failoverNotAllowed)
+ {
+ _connection.exceptionReceived(new AMQDisconnectedException(
+ "Server closed connection and reconnection not permitted.", _stateManager.getLastException()));
+ }
}
- _logger.debug("Protocol Session [" + this + "] closed");
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Protocol Session [" + this + "] closed");
+ }
}
/** See {@link FailoverHandler} to see rationale for separate thread. */
@@ -280,7 +304,6 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_logger.debug("Protocol Session [" + this + "] idle: reader");
// failover:
- HeartbeatDiagnostics.timeout();
_logger.warn("Timed out while waiting for heartbeat from peer.");
_network.close();
}
@@ -289,7 +312,7 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_logger.debug("Protocol Session [" + this + "] idle: reader");
writeFrame(HeartbeatBody.FRAME);
- HeartbeatDiagnostics.sent();
+ _heartbeatListener.heartbeatSent();
}
/**
@@ -297,14 +320,29 @@ public class AMQProtocolHandler implements ProtocolEngine
*/
public void exception(Throwable cause)
{
- if (_failoverState == FailoverState.NOT_STARTED)
+ boolean causeIsAConnectionProblem =
+ cause instanceof AMQConnectionClosedException ||
+ cause instanceof IOException ||
+ cause instanceof TransportException;
+
+ if (causeIsAConnectionProblem)
{
- if ((cause instanceof AMQConnectionClosedException) || cause instanceof IOException)
+ //ensure the IoSender and IoReceiver are closed
+ try
{
- _logger.info("Exception caught therefore going to attempt failover: " + cause, cause);
- // this will attempt failover
_network.close();
- closed();
+ }
+ catch (Exception e)
+ {
+ //ignore
+ }
+ }
+ FailoverState state = getFailoverState();
+ if (state == FailoverState.NOT_STARTED)
+ {
+ if (causeIsAConnectionProblem)
+ {
+ _logger.info("Connection exception caught therefore going to attempt failover: " + cause, cause);
}
else
{
@@ -319,7 +357,7 @@ public class AMQProtocolHandler implements ProtocolEngine
}
// we reach this point if failover was attempted and failed therefore we need to let the calling app
// know since we cannot recover the situation
- else if (_failoverState == FailoverState.FAILED)
+ else if (state == FailoverState.FAILED)
{
_logger.error("Exception caught by protocol handler: " + cause, cause);
@@ -329,6 +367,10 @@ public class AMQProtocolHandler implements ProtocolEngine
propagateExceptionToAllWaiters(amqe);
_connection.exceptionReceived(cause);
}
+ else
+ {
+ _logger.warn("Exception caught by protocol handler: " + cause, cause);
+ }
}
/**
@@ -403,6 +445,7 @@ public class AMQProtocolHandler implements ProtocolEngine
public void received(ByteBuffer msg)
{
_readBytes += msg.remaining();
+ _lastReadTime = System.currentTimeMillis();
try
{
final ArrayList<AMQDataBlock> dataBlocks = _codecFactory.getDecoder().decodeBuffer(msg);
@@ -431,8 +474,6 @@ public class AMQProtocolHandler implements ProtocolEngine
final AMQBody bodyFrame = frame.getBodyFrame();
- HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody);
-
bodyFrame.handle(frame.getChannel(), _protocolSession);
_connection.bytesReceived(_readBytes);
@@ -521,6 +562,7 @@ public class AMQProtocolHandler implements ProtocolEngine
public synchronized void writeFrame(AMQDataBlock frame, boolean flush)
{
final ByteBuffer buf = asByteBuffer(frame);
+ _lastWriteTime = System.currentTimeMillis();
_writtenBytes += buf.remaining();
_sender.send(buf);
if(flush)
@@ -792,14 +834,14 @@ public class AMQProtocolHandler implements ProtocolEngine
return _protocolSession;
}
- FailoverState getFailoverState()
+ synchronized FailoverState getFailoverState()
{
return _failoverState;
}
- public void setFailoverState(FailoverState failoverState)
+ public synchronized void setFailoverState(FailoverState failoverState)
{
- _failoverState = failoverState;
+ _failoverState= failoverState;
}
public byte getProtocolMajorVersion()
@@ -843,6 +885,23 @@ public class AMQProtocolHandler implements ProtocolEngine
_sender = sender;
}
+ @Override
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime;
+ }
+
+ protected Sender<ByteBuffer> getSender()
+ {
+ return _sender;
+ }
+
/** @param delay delay in seconds (not ms) */
void initHeartbeats(int delay)
{
@@ -850,7 +909,6 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_network.setMaxWriteIdle(delay);
_network.setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
- HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay));
}
}
@@ -865,5 +923,13 @@ public class AMQProtocolHandler implements ProtocolEngine
}
+ public void setHeartbeatListener(HeartbeatListener listener)
+ {
+ _heartbeatListener = listener == null ? HeartbeatListener.DEFAULT : listener;
+ }
+ public void heartbeatBodyReceived()
+ {
+ _heartbeatListener.heartbeatReceived();
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
index af57fd98fc..aed10cf15f 100644
--- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
+++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
@@ -48,6 +48,8 @@ import org.apache.qpid.transport.TransportException;
import javax.jms.JMSException;
import javax.security.sasl.SaslClient;
+
+import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -265,7 +267,7 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
public void heartbeatBodyReceived(int channelId, HeartbeatBody body) throws AMQException
{
-
+ _protocolHandler.heartbeatBodyReceived();
}
/**
@@ -372,6 +374,11 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
}
}
+ public Sender<ByteBuffer> getSender()
+ {
+ return _protocolHandler.getSender();
+ }
+
public void failover(String host, int port)
{
_protocolHandler.failover(host, port);
diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java b/java/client/src/main/java/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java
deleted file mode 100644
index d387a8ba93..0000000000
--- a/java/client/src/main/java/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java
+++ /dev/null
@@ -1,125 +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.client.protocol;
-
-class HeartbeatDiagnostics
-{
- private static final Diagnostics _impl = init();
-
- private HeartbeatDiagnostics()
- {
- }
-
- private static Diagnostics init()
- {
- return Boolean.getBoolean("amqj.heartbeat.diagnostics") ? new On() : new Off();
- }
-
- static void sent()
- {
- _impl.sent();
- }
-
- static void timeout()
- {
- _impl.timeout();
- }
-
- static void received(boolean heartbeat)
- {
- _impl.received(heartbeat);
- }
-
- static void init(int delay, int timeout)
- {
- _impl.init(delay, timeout);
- }
-
- private static interface Diagnostics
- {
- void sent();
- void timeout();
- void received(boolean heartbeat);
- void init(int delay, int timeout);
- }
-
- private static class On implements Diagnostics
- {
- private final String[] messages = new String[50];
- private int i;
-
- private void save(String msg)
- {
- messages[i++] = msg;
- if(i >= messages.length){
- i = 0;//i.e. a circular buffer
- }
- }
-
- public void sent()
- {
- save(System.currentTimeMillis() + ": sent heartbeat");
- }
-
- public void timeout()
- {
- for(int i = 0; i < messages.length; i++)
- {
- if(messages[i] != null)
- {
- System.out.println(messages[i]);
- }
- }
- System.out.println(System.currentTimeMillis() + ": timed out");
- }
-
- public void received(boolean heartbeat)
- {
- save(System.currentTimeMillis() + ": received " + (heartbeat ? "heartbeat" : "data"));
- }
-
- public void init(int delay, int timeout)
- {
- System.out.println(System.currentTimeMillis() + ": initialised delay=" + delay + ", timeout=" + timeout);
- }
- }
-
- private static class Off implements Diagnostics
- {
- public void sent()
- {
-
- }
- public void timeout()
- {
-
- }
- public void received(boolean heartbeat)
- {
-
- }
-
- public void init(int delay, int timeout)
- {
-
- }
- }
-}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
index 9198903408..b43229292f 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
@@ -28,8 +28,10 @@ import org.apache.qpid.util.FileUtils;
import javax.security.sasl.SaslClientFactory;
import java.io.IOException;
import java.io.InputStream;
+import java.security.Provider;
import java.security.Security;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
@@ -67,10 +69,10 @@ public class DynamicSaslRegistrar
}
/** Reads the properties file, and creates a dynamic security provider to register the SASL implementations with. */
- public static void registerSaslProviders()
+ public static ProviderRegistrationResult registerSaslProviders()
{
_logger.debug("public static void registerSaslProviders(): called");
-
+ ProviderRegistrationResult result = ProviderRegistrationResult.FAILED;
// Open the SASL properties file, using the default name is one is not specified.
String filename = System.getProperty(FILE_PROPERTY);
InputStream is =
@@ -89,22 +91,45 @@ public class DynamicSaslRegistrar
if (factories.size() > 0)
{
// Ensure we are used before the defaults
- if (Security.insertProviderAt(new JCAProvider(factories), 1) == -1)
+ JCAProvider qpidProvider = new JCAProvider(factories);
+ if (Security.insertProviderAt(qpidProvider, 1) == -1)
{
- _logger.error("Unable to load custom SASL providers.");
+ Provider registeredProvider = findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME);
+ if (registeredProvider == null)
+ {
+ result = ProviderRegistrationResult.FAILED;
+ _logger.error("Unable to load custom SASL providers.");
+ }
+ else if (registeredProvider.equals(qpidProvider))
+ {
+ result = ProviderRegistrationResult.EQUAL_ALREADY_REGISTERED;
+ _logger.debug("Custom SASL provider is already registered with equal properties.");
+ }
+ else
+ {
+ result = ProviderRegistrationResult.DIFFERENT_ALREADY_REGISTERED;
+ _logger.warn("Custom SASL provider was already registered with different properties.");
+ if (_logger.isDebugEnabled())
+ {
+ _logger.debug("Custom SASL provider " + registeredProvider + " properties: " + new HashMap<Object, Object>(registeredProvider));
+ }
+ }
}
else
{
+ result = ProviderRegistrationResult.SUCCEEDED;
_logger.info("Additional SASL providers successfully registered.");
}
}
else
{
- _logger.warn("No additional SASL providers registered.");
+ result = ProviderRegistrationResult.NO_SASL_FACTORIES;
+ _logger.warn("No additional SASL factories found to register.");
}
}
catch (IOException e)
{
+ result = ProviderRegistrationResult.FAILED;
_logger.error("Error reading properties: " + e, e);
}
finally
@@ -122,6 +147,22 @@ public class DynamicSaslRegistrar
}
}
}
+ return result;
+ }
+
+ static Provider findProvider(String name)
+ {
+ Provider[] providers = Security.getProviders();
+ Provider registeredProvider = null;
+ for (Provider provider : providers)
+ {
+ if (name.equals(provider.getName()))
+ {
+ registeredProvider = provider;
+ break;
+ }
+ }
+ return registeredProvider;
}
/**
@@ -158,15 +199,24 @@ public class DynamicSaslRegistrar
continue;
}
- _logger.debug("Registering class "+ clazz.getName() +" for mechanism "+mechanism);
+ _logger.debug("Found class "+ clazz.getName() +" for mechanism "+mechanism);
factoriesToRegister.put(mechanism, (Class<? extends SaslClientFactory>) clazz);
}
catch (Exception ex)
{
- _logger.error("Error instantiating SaslClientFactory calss " + className + " - skipping");
+ _logger.error("Error instantiating SaslClientFactory class " + className + " - skipping");
}
}
return factoriesToRegister;
}
+
+ public static enum ProviderRegistrationResult
+ {
+ SUCCEEDED,
+ EQUAL_ALREADY_REGISTERED,
+ DIFFERENT_ALREADY_REGISTERED,
+ NO_SASL_FACTORIES,
+ FAILED;
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java b/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
index 4a91f805f6..c9bcaf0d15 100644
--- a/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
+++ b/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
@@ -39,6 +39,11 @@ import java.util.Map;
*/
public class JCAProvider extends Provider
{
+ static final String QPID_CLIENT_SASL_PROVIDER_NAME = "AMQSASLProvider-Client";
+ static final String QPID_CLIENT_SASL_PROVIDER_INFO = "A JCA provider that registers all "
+ + "AMQ SASL providers that want to be registered";
+ static final double QPID_CLIENT_SASL_PROVIDER_VERSION = 1.0;
+
private static final Logger log = LoggerFactory.getLogger(JCAProvider.class);
/**
@@ -48,8 +53,7 @@ public class JCAProvider extends Provider
*/
public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap)
{
- super("AMQSASLProvider-Client", 1.0, "A JCA provider that registers all "
- + "AMQ SASL providers that want to be registered");
+ super(QPID_CLIENT_SASL_PROVIDER_NAME, QPID_CLIENT_SASL_PROVIDER_VERSION, QPID_CLIENT_SASL_PROVIDER_INFO);
register(providerMap);
}
@@ -63,7 +67,7 @@ public class JCAProvider extends Provider
for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet())
{
put( "SaslClientFactory."+me.getKey(), me.getValue().getName());
- log.debug("Registered SASL Client factory for " + me.getKey() + " as " + me.getValue().getName());
+ log.debug("Recording SASL Client factory for " + me.getKey() + " as " + me.getValue().getName());
}
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
index 0b6217ffce..ed75e1f4c3 100644
--- a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
+++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
@@ -157,12 +157,15 @@ public class AMQStateManager implements AMQMethodListener
if (_waiters.size() == 0)
{
- _logger.error("No Waiters for error saving as last error:" + error.getMessage());
+ _logger.info("No Waiters for error. Saving as last error:" + error.getMessage());
_lastException = error;
}
for (StateWaiter waiter : _waiters)
{
- _logger.error("Notifying Waiters(" + _waiters + ") for error:" + error.getMessage());
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Notifying waiter " + waiter + " for error:" + error.getMessage());
+ }
waiter.error(error);
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java b/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java
index 3c9a6e1500..4789dd0ed7 100644
--- a/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java
+++ b/java/client/src/main/java/org/apache/qpid/client/transport/ClientConnectionDelegate.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.client.transport;
+import org.apache.qpid.client.HeartbeatListener;
+import org.apache.qpid.transport.ConnectionHeartbeat;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
@@ -70,6 +72,7 @@ public class ClientConnectionDelegate extends ClientDelegate
}
private final ConnectionURL _connectionURL;
+ private HeartbeatListener _heartbeatListener = HeartbeatListener.DEFAULT;
/**
* @param settings
@@ -165,4 +168,19 @@ public class ClientConnectionDelegate extends ClientDelegate
return null;
}
+
+ @Override
+ public void connectionHeartbeat(Connection conn, ConnectionHeartbeat hearbeat)
+ {
+ // ClientDelegate simply responds to heartbeats with heartbeats
+ _heartbeatListener.heartbeatReceived();
+ super.connectionHeartbeat(conn, hearbeat);
+ _heartbeatListener.heartbeatSent();
+ }
+
+
+ public void setHeartbeatListener(HeartbeatListener listener)
+ {
+ _heartbeatListener = listener == null ? HeartbeatListener.DEFAULT : listener;
+ }
}
diff --git a/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
index 8fd6ff6d33..c4fbeb5607 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
@@ -20,9 +20,8 @@
*/
package org.apache.qpid.jms;
-import org.apache.qpid.framing.AMQShortString;
-
import java.util.List;
+import org.apache.qpid.framing.AMQShortString;
/**
Connection URL format
@@ -35,14 +34,22 @@ public interface ConnectionURL
public static final String AMQ_PROTOCOL = "amqp";
public static final String OPTIONS_SYNC_PERSISTENCE = "sync_persistence";
public static final String OPTIONS_MAXPREFETCH = "maxprefetch";
- public static final String OPTIONS_SYNC_ACK = "sync_ack";
+ public static final String OPTIONS_SYNC_ACK = "sync_ack";
public static final String OPTIONS_SYNC_PUBLISH = "sync_publish";
public static final String OPTIONS_USE_LEGACY_MAP_MESSAGE_FORMAT = "use_legacy_map_msg_format";
+ public static final String OPTIONS_USE_LEGACY_STREAM_MESSAGE_FORMAT = "use_legacy_stream_msg_format";
public static final String OPTIONS_BROKERLIST = "brokerlist";
public static final String OPTIONS_FAILOVER = "failover";
public static final String OPTIONS_FAILOVER_CYCLE = "cyclecount";
/**
+ * This option is used to apply a connection level override of
+ * the {@value BrokerDetails#OPTIONS_SSL} option values in the
+ * {@value ConnectionURL#OPTIONS_BROKERLIST};
+ */
+ public static final String OPTIONS_SSL = "ssl";
+
+ /**
* This option is only applicable for 0-8/0-9/0-9-1 protocols connection
* <p>
* It tells the client to delegate the requeue/DLQ decision to the
@@ -54,9 +61,11 @@ public interface ConnectionURL
public static final String OPTIONS_DEFAULT_QUEUE_EXCHANGE = "defaultQueueExchange";
public static final String OPTIONS_TEMPORARY_TOPIC_EXCHANGE = "temporaryTopicExchange";
public static final String OPTIONS_TEMPORARY_QUEUE_EXCHANGE = "temporaryQueueExchange";
+ public static final String OPTIONS_VERIFY_QUEUE_ON_SEND = "verifyQueueOnSend";
+
public static final byte URL_0_8 = 1;
public static final byte URL_0_10 = 2;
-
+
String getURL();
String getFailoverMethod();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java b/java/client/src/main/java/org/apache/qpid/jms/ListMessage.java
index fa41f3ef06..21dd2a89ee 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/ListMessage.java
@@ -18,21 +18,38 @@
* under the License.
*
*/
-package org.apache.qpid.server.configuration.plugins;
+package org.apache.qpid.jms;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
+import javax.jms.JMSException;
+import java.util.Iterator;
import java.util.List;
-public interface ConfigurationPluginFactory
+public interface ListMessage extends javax.jms.StreamMessage
{
- /**
- * The Parent paths of the configuration that this plugin supports.
- *
- * For example, {@code queue} elements have a parent path of {@code virtualhosts.virtualhost}.
- */
- public List<String> getParentPaths();
-
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException;
+ boolean add(Object e) throws JMSException;
+
+ void add(int index, Object e) throws JMSException;
+
+ boolean contains(Object e) throws JMSException;
+
+ Object get(int index) throws JMSException;
+
+ int indexOf(Object e) throws JMSException;
+
+ Iterator<Object> iterator() throws JMSException;
+
+ Object remove(int index) throws JMSException;
+
+ boolean remove(Object e)throws JMSException;
+
+ Object set(int index, Object e) throws JMSException;
+
+ int size() throws JMSException;
+
+ Object[] toArray() throws JMSException;
+
+ List<Object> asList() throws JMSException;
+
+ void setList(List<Object> l) throws JMSException;
}
diff --git a/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java b/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
index bec8b0917d..82c2b88c30 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/MessageProducer.java
@@ -23,25 +23,11 @@ package org.apache.qpid.jms;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
-import java.io.UnsupportedEncodingException;
/**
*/
public interface MessageProducer extends javax.jms.MessageProducer
{
- /**
- * Set the default MIME type for messages produced by this producer. This reduces the overhead of each message.
- * @param mimeType
- */
- void setMimeType(String mimeType) throws JMSException;
-
- /**
- * Set the default encoding for messages produced by this producer. This reduces the overhead of each message.
- * @param encoding the encoding as understood by XXXX how do I specify this?? RG
- * @throws UnsupportedEncodingException if the encoding is not understood
- */
- void setEncoding(String encoding) throws UnsupportedEncodingException, JMSException;
-
void send(Destination destination, Message message, int deliveryMode,
int priority, long timeToLive, boolean immediate)
throws JMSException;
diff --git a/java/client/src/main/java/org/apache/qpid/jms/Session.java b/java/client/src/main/java/org/apache/qpid/jms/Session.java
index b4bf2d1d85..4801f87295 100644
--- a/java/client/src/main/java/org/apache/qpid/jms/Session.java
+++ b/java/client/src/main/java/org/apache/qpid/jms/Session.java
@@ -21,6 +21,7 @@
package org.apache.qpid.jms;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.jms.ListMessage;
import javax.jms.Destination;
import javax.jms.JMSException;
@@ -100,4 +101,6 @@ public interface Session extends TopicSession, QueueSession
AMQShortString getDefaultTopicExchangeName();
AMQShortString getTemporaryQueueExchangeName();
+
+ ListMessage createListMessage() throws JMSException;
}
diff --git a/java/client/src/test/java/org/apache/qpid/client/AMQConnectionUnitTest.java b/java/client/src/test/java/org/apache/qpid/client/AMQConnectionUnitTest.java
index d186a440da..d309251b44 100644
--- a/java/client/src/test/java/org/apache/qpid/client/AMQConnectionUnitTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/AMQConnectionUnitTest.java
@@ -20,25 +20,60 @@
*/
package org.apache.qpid.client;
-import junit.framework.TestCase;
-
-import org.apache.qpid.AMQInvalidArgumentException;
+import java.util.concurrent.atomic.AtomicReference;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
-import java.util.concurrent.atomic.AtomicReference;
-public class AMQConnectionUnitTest extends TestCase
+import org.apache.qpid.AMQInvalidArgumentException;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AMQConnectionUnitTest extends QpidTestCase
{
+ String _url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'";
+
+ public void testVerifyQueueOnSendDefault() throws Exception
+ {
+ MockAMQConnection connection = new MockAMQConnection(_url);
+ assertFalse(connection.validateQueueOnSend());
+ }
+
+ public void testVerifyQueueOnSendViaSystemProperty() throws Exception
+ {
+ setTestSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "true");
+ MockAMQConnection connection = new MockAMQConnection(_url);
+ assertTrue(connection.validateQueueOnSend());
+
+ setTestSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "false");
+ connection = new MockAMQConnection(_url);
+ assertFalse(connection.validateQueueOnSend());
+ }
+
+ public void testVerifyQueueOnSendViaURL() throws Exception
+ {
+ MockAMQConnection connection = new MockAMQConnection(_url + "&" + ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND + "='true'");
+ assertTrue(connection.validateQueueOnSend());
+
+ connection = new MockAMQConnection(_url + "&" + ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND + "='false'");
+ assertFalse(connection.validateQueueOnSend());
+ }
+
+ public void testVerifyQueueOnSendViaURLoverridesSystemProperty() throws Exception
+ {
+ setTestSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "false");
+ MockAMQConnection connection = new MockAMQConnection(_url + "&" + ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND + "='true'");
+ assertTrue(connection.validateQueueOnSend());
+ }
public void testExceptionReceived()
{
- String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'";
AMQInvalidArgumentException expectedException = new AMQInvalidArgumentException("Test", null);
final AtomicReference<JMSException> receivedException = new AtomicReference<JMSException>();
try
{
- MockAMQConnection connection = new MockAMQConnection(url);
+ MockAMQConnection connection = new MockAMQConnection(_url);
connection.setExceptionListener(new ExceptionListener()
{
@@ -62,4 +97,22 @@ public class AMQConnectionUnitTest extends TestCase
assertEquals("JMSException linked exception is incorrect", expectedException, exception.getLinkedException());
}
+ /**
+ * This should expand to test all the defaults.
+ */
+ public void testDefaultStreamMessageEncoding() throws Exception
+ {
+ MockAMQConnection connection = new MockAMQConnection(_url);
+ assertTrue("Legacy Stream message encoding should be the default",connection.isUseLegacyStreamMessageFormat());
+ }
+
+ /**
+ * This should expand to test all the connection properties.
+ */
+ public void testStreamMessageEncodingProperty() throws Exception
+ {
+ MockAMQConnection connection = new MockAMQConnection(_url + "&use_legacy_stream_msg_format='false'");
+ assertFalse("Stream message encoding should be amqp/list",connection.isUseLegacyStreamMessageFormat());
+ }
+
}
diff --git a/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java b/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
index 028e2d5cc3..40ed9319f1 100644
--- a/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
+++ b/java/client/src/test/java/org/apache/qpid/client/AMQSession_0_10Test.java
@@ -18,6 +18,7 @@
*/
package org.apache.qpid.client;
+import org.apache.qpid.client.message.AMQPEncodedListMessage;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.transport.*;
@@ -28,6 +29,8 @@ import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
+import javax.jms.StreamMessage;
+
import java.util.ArrayList;
import java.util.List;
@@ -276,7 +279,7 @@ public class AMQSession_0_10Test extends QpidTestCase
{
BasicMessageConsumer_0_10 consumer = session.createMessageConsumer(createDestination(), 1, 1, true, false,
null, null, false, true);
- session.sendConsume(consumer, new AMQShortString("test"), null, true, 1);
+ session.sendConsume(consumer, new AMQShortString("test"), true, 1);
}
catch (Exception e)
{
@@ -459,6 +462,13 @@ public class AMQSession_0_10Test extends QpidTestCase
assertNotNull("ExchangeDeclare event was not sent", event);
}
+ public void testCreateStreamMessage() throws Exception
+ {
+ AMQSession_0_10 session = createAMQSession_0_10();
+ StreamMessage m = session.createStreamMessage();
+ assertTrue("Legacy Stream message encoding should be the default" + m.getClass(),!(m instanceof AMQPEncodedListMessage));
+ }
+
public void testGetQueueDepthWithSync()
{
// slow down a flush thread
@@ -587,7 +597,7 @@ public class AMQSession_0_10Test extends QpidTestCase
connection.setSessionFactory(new SessionFactory()
{
- public Session newSession(Connection conn, Binary name, long expiry)
+ public Session newSession(Connection conn, Binary name, long expiry, boolean isNoReplay)
{
return new MockSession(conn, new SessionDelegate(), name, expiry, throwException);
}
@@ -660,7 +670,6 @@ public class AMQSession_0_10Test extends QpidTestCase
if (m instanceof ExchangeBound)
{
ExchangeBoundResult struc = new ExchangeBoundResult();
- struc.setQueueNotFound(true);
result.setValue(struc);
}
else if (m instanceof ExchangeQuery)
diff --git a/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java b/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
index 722cbd0752..066ece7ed1 100644
--- a/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
+++ b/java/client/src/test/java/org/apache/qpid/client/BasicMessageConsumer_0_8_Test.java
@@ -48,7 +48,7 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
TestAMQSession testSession = new TestAMQSession(conn);
BasicMessageConsumer_0_8 consumer =
- new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.SERVER, consumer.getRejectBehaviour());
}
@@ -68,7 +68,7 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
final TestAMQSession testSession = new TestAMQSession(conn);
final BasicMessageConsumer_0_8 consumer =
- new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.NORMAL, consumer.getRejectBehaviour());
}
@@ -94,7 +94,7 @@ public class BasicMessageConsumer_0_8_Test extends TestCase
TestAMQSession testSession = new TestAMQSession(conn);
BasicMessageConsumer_0_8 consumer =
- new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
+ new BasicMessageConsumer_0_8(0, conn, queue, "", false, null, testSession, null, 10, 5, false, Session.SESSION_TRANSACTED, false, false);
assertEquals("Reject behaviour was was not as expected", RejectBehaviour.NORMAL, consumer.getRejectBehaviour());
}
diff --git a/java/client/src/test/java/org/apache/qpid/client/message/AMQPEncodedListMessageUnitTest.java b/java/client/src/test/java/org/apache/qpid/client/message/AMQPEncodedListMessageUnitTest.java
new file mode 100644
index 0000000000..e131ab3dd2
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/client/message/AMQPEncodedListMessageUnitTest.java
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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.client.message;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.jms.MessageFormatException;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+public class AMQPEncodedListMessageUnitTest extends QpidTestCase
+{
+
+ Map<String,String> _map = new HashMap<String,String>();
+ List<Object> _list = new ArrayList<Object>();
+ UUID _uuid = UUID.randomUUID();
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _map.put("Key1","String1");
+ _map.put("Key2","String2");
+ _map.put("Key3","String3");
+
+ _list.add(1);
+ _list.add(2);
+ _list.add(3);
+ }
+
+ /**
+ * Test whether we accept the correct types while rejecting invalid types.
+ */
+ public void testAddObject() throws Exception
+ {
+ AMQPEncodedListMessage m = new AMQPEncodedListMessage(AMQMessageDelegateFactory.FACTORY_0_10);
+ m.add(true);
+ m.add((byte)256);
+ m.add(Short.MAX_VALUE);
+ m.add(Integer.MAX_VALUE);
+ m.add(Long.MAX_VALUE);
+ m.add(10.22);
+ m.add("Msg");
+ m.add("Msg".getBytes());
+ m.add(_list);
+ m.add(_map);
+ m.add(_uuid);
+
+ try
+ {
+ m.add(new Object());
+ fail("Validation for element type failed");
+ }
+ catch (MessageFormatException e)
+ {
+ }
+ }
+
+ public void testListBehaviorForIncommingMsg() throws Exception
+ {
+ BBEncoder encoder = new BBEncoder(1024);
+ encoder.writeList(_list);
+ AMQPEncodedListMessage m = new AMQPEncodedListMessage(new AMQMessageDelegate_0_10(),encoder.segment());
+
+ assertTrue("contains(Object) method did not return true as expected",m.contains(1));
+ assertFalse("contains(Object) method did not return false as expected",m.contains(5));
+ assertEquals("get(index) method returned incorrect value",((Integer)m.get(1)).intValue(),2);
+ assertEquals("indexOf(Object) method returned incorrect index",m.indexOf(2),1);
+ try
+ {
+ m.get(10);
+ }
+ catch (MessageFormatException e)
+ {
+ assertTrue("Incorrect exception type. Expected IndexOutOfBoundsException", e.getCause() instanceof IndexOutOfBoundsException);
+ }
+ }
+
+ public void testStreamMessageInterfaceForIncommingMsg() throws Exception
+ {
+ BBEncoder encoder = new BBEncoder(1024);
+ encoder.writeList(getList());
+ AMQPEncodedListMessage m = new AMQPEncodedListMessage(new AMQMessageDelegate_0_10(),encoder.segment());
+
+ assertEquals(true,m.readBoolean());
+ assertEquals((byte)256,m.readByte());
+ assertEquals(Short.MAX_VALUE,m.readShort());
+ assertEquals(Integer.MAX_VALUE,m.readInt());
+ assertEquals(Long.MAX_VALUE,m.readLong());
+ assertEquals(10.22,m.readDouble());
+ assertEquals("Msg",m.readString());
+ assertEquals(_list,(List)m.readObject());
+ assertEquals(_map,(Map)m.readObject());
+ assertEquals(_uuid,(UUID)m.readObject());
+ }
+
+ public void testMapMessageInterfaceForIncommingMsg() throws Exception
+ {
+ BBEncoder encoder = new BBEncoder(1024);
+ encoder.writeList(getList());
+ AMQPEncodedListMessage m = new AMQPEncodedListMessage(new AMQMessageDelegate_0_10(),encoder.segment());
+
+ assertEquals(true,m.getBoolean("0"));
+ assertEquals((byte)256,m.getByte("1"));
+ assertEquals(Short.MAX_VALUE,m.getShort("2"));
+ assertEquals(Integer.MAX_VALUE,m.getInt("3"));
+ assertEquals(Long.MAX_VALUE,m.getLong("4"));
+ assertEquals(10.22,m.getDouble("5"));
+ assertEquals("Msg",m.getString("6"));
+ assertEquals(_list,(List)m.getObject("7"));
+ assertEquals(_map,(Map)m.getObject("8"));
+ assertEquals(_uuid,(UUID)m.getObject("9"));
+ }
+
+ public List<Object> getList()
+ {
+ List<Object> myList = new ArrayList<Object>();
+ myList.add(true);
+ myList.add((byte)256);
+ myList.add(Short.MAX_VALUE);
+ myList.add(Integer.MAX_VALUE);
+ myList.add(Long.MAX_VALUE);
+ myList.add(10.22);
+ myList.add("Msg");
+ myList.add(_list);
+ myList.add(_map);
+ myList.add(_uuid);
+ return myList;
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/client/messaging/address/AddressHelperTest.java b/java/client/src/test/java/org/apache/qpid/client/messaging/address/AddressHelperTest.java
new file mode 100644
index 0000000000..7401168978
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/client/messaging/address/AddressHelperTest.java
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.client.messaging.address;
+
+import org.apache.qpid.client.AMQDestination;
+import org.apache.qpid.client.AMQDestination.AddressOption;
+import org.apache.qpid.client.AMQDestination.Binding;
+import org.apache.qpid.client.messaging.address.Link.Reliability;
+import org.apache.qpid.messaging.Address;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AddressHelperTest extends QpidTestCase
+{
+ public void testAddressOptions() throws Exception
+ {
+ Address addr = Address.parse("queue/test;{create:sender, assert:always, delete:receiver, mode:browse}");
+ AddressHelper helper = new AddressHelper(addr);
+ assertEquals(AddressOption.SENDER,AddressOption.getOption(helper.getCreate()));
+ assertEquals(AddressOption.ALWAYS,AddressOption.getOption(helper.getAssert()));
+ assertEquals(AddressOption.RECEIVER,AddressOption.getOption(helper.getDelete()));
+ assertTrue("'mode' option wasn't read properly",helper.isBrowseOnly());
+ }
+
+ public void testNodeProperties() throws Exception
+ {
+ Address addr = Address.parse("my-queue;{" +
+ "node: " +
+ "{" +
+ "type: queue ," +
+ "durable: true ," +
+ "x-declare: " +
+ "{" +
+ "exclusive: true," +
+ "auto-delete: true," +
+ "alternate-exchange: 'amq.fanout'," +
+ "arguments: {" +
+ "'qpid.max_size': 1000," +
+ "'qpid.max_count': 100" +
+ "}" +
+ "}, " +
+ "x-bindings: [{exchange : 'amq.direct', queue:my-queue, key : test}, " +
+ "{exchange : 'amq.fanout', queue:my-queue}," +
+ "{exchange: 'amq.match', queue:my-queue, arguments: {x-match: any, dep: sales, loc: CA}}," +
+ "{exchange : 'amq.topic',queue:my-queue, key : 'a.#'}" +
+ "]" +
+
+ "}" +
+ "}");
+ AddressHelper helper = new AddressHelper(addr);
+ Node node = helper.getNode();
+ assertEquals("'type' property wasn't read properly",AMQDestination.QUEUE_TYPE,helper.getNodeType());
+ assertTrue("'durable' property wasn't read properly",node.isDurable());
+ assertTrue("'auto-delete' property wasn't read properly",node.isAutoDelete());
+ assertTrue("'exclusive' property wasn't read properly",node.isExclusive());
+ assertEquals("'alternate-exchange' property wasn't read properly","amq.fanout",node.getAlternateExchange());
+ assertEquals("'arguments' in 'x-declare' property wasn't read properly",2,node.getDeclareArgs().size());
+ assertEquals("'bindings' property wasn't read properly",4,node.getBindings().size());
+ for (Binding binding: node.getBindings())
+ {
+ assertTrue("property 'exchange' in bindings wasn't read properly",binding.getExchange().startsWith("amq."));
+ assertEquals("property 'queue' in bindings wasn't read properly","my-queue",binding.getQueue());
+ if (binding.getExchange().equals("amq.direct"))
+ {
+ assertEquals("'key' property in bindings wasn't read properly","test",binding.getBindingKey());
+ }
+ if (binding.getExchange().equals("amq.match"))
+ {
+ assertEquals("'arguments' property in bindings wasn't read properly",3,binding.getArgs().size());
+ }
+ }
+ }
+
+ public void testLinkProperties() throws Exception
+ {
+ Address addr = Address.parse("my-queue;{" +
+ "link: " +
+ "{" +
+ "name: my-queue ," +
+ "durable: true ," +
+ "reliability: at-least-once," +
+ "capacity: {source:10, target:15}," +
+ "x-declare: " +
+ "{" +
+ "exclusive: true," +
+ "auto-delete: true," +
+ "alternate-exchange: 'amq.fanout'," +
+ "arguments: {" +
+ "'qpid.max_size': 1000," +
+ "'qpid.max_count': 100" +
+ "}" +
+ "}, " +
+ "x-bindings: [{exchange : 'amq.direct', queue:my-queue, key : test}, " +
+ "{exchange : 'amq.fanout', queue:my-queue}," +
+ "{exchange: 'amq.match', queue:my-queue, arguments: {x-match: any, dep: sales, loc: CA}}," +
+ "{exchange : 'amq.topic',queue:my-queue, key : 'a.#'}" +
+ "]," +
+ "x-subscribes:{exclusive: true, arguments: {a:b,x:y}}" +
+ "}" +
+ "}");
+
+ AddressHelper helper = new AddressHelper(addr);
+ Link link = helper.getLink();
+ assertEquals("'name' property wasn't read properly","my-queue",link.getName());
+ assertTrue("'durable' property wasn't read properly",link.isDurable());
+ assertEquals("'reliability' property wasn't read properly",Reliability.AT_LEAST_ONCE,link.getReliability());
+ assertTrue("'auto-delete' property in 'x-declare' wasn't read properly",link.getSubscriptionQueue().isAutoDelete());
+ assertTrue("'exclusive' property in 'x-declare' wasn't read properly",link.getSubscriptionQueue().isExclusive());
+ assertEquals("'alternate-exchange' property in 'x-declare' wasn't read properly","amq.fanout",link.getSubscriptionQueue().getAlternateExchange());
+ assertEquals("'arguments' in 'x-declare' property wasn't read properly",2,link.getSubscriptionQueue().getDeclareArgs().size());
+ assertEquals("'bindings' property wasn't read properly",4,link.getBindings().size());
+ for (Binding binding: link.getBindings())
+ {
+ assertTrue("property 'exchange' in bindings wasn't read properly",binding.getExchange().startsWith("amq."));
+ assertEquals("property 'queue' in bindings wasn't read properly","my-queue",binding.getQueue());
+ if (binding.getExchange().equals("amq.direct"))
+ {
+ assertEquals("'key' property in bindings wasn't read properly","test",binding.getBindingKey());
+ }
+ if (binding.getExchange().equals("amq.match"))
+ {
+ assertEquals("'arguments' property in bindings wasn't read properly",3,binding.getArgs().size());
+ }
+ }
+ assertTrue("'exclusive' property in 'x-subscribe' wasn't read properly",link.getSubscription().isExclusive());
+ assertEquals("'arguments' in 'x-subscribe' property wasn't read properly",2,link.getSubscription().getArgs().size());
+ }
+
+}
diff --git a/java/client/src/test/java/org/apache/qpid/client/security/DynamicSaslRegistrarTest.java b/java/client/src/test/java/org/apache/qpid/client/security/DynamicSaslRegistrarTest.java
new file mode 100644
index 0000000000..4281984212
--- /dev/null
+++ b/java/client/src/test/java/org/apache/qpid/client/security/DynamicSaslRegistrarTest.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.client.security;
+
+import java.io.File;
+import java.security.Provider;
+import java.security.Security;
+
+import org.apache.qpid.client.security.DynamicSaslRegistrar.ProviderRegistrationResult;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+public class DynamicSaslRegistrarTest extends QpidTestCase
+{
+ private Provider _registeredProvider;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ //If the client provider is already registered, remove it for the duration of the test
+ _registeredProvider = DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME);
+ if (_registeredProvider != null)
+ {
+ Security.removeProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME);
+ }
+ }
+
+ public void tearDown() throws Exception
+ {
+ //Remove any provider left behind by the test.
+ Security.removeProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME);
+ try
+ {
+ //If the client provider was already registered before the test, restore it.
+ if (_registeredProvider != null)
+ {
+ Security.insertProviderAt(_registeredProvider, 1);
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testRegisterDefaultProvider()
+ {
+ assertNull("Provider should not yet be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ ProviderRegistrationResult firstRegistrationResult = DynamicSaslRegistrar.registerSaslProviders();
+ assertEquals("Unexpected registration result", ProviderRegistrationResult.SUCCEEDED, firstRegistrationResult);
+ assertNotNull("Providers should now be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+ }
+
+ public void testRegisterDefaultProviderTwice()
+ {
+ assertNull("Provider should not yet be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ DynamicSaslRegistrar.registerSaslProviders();
+ assertNotNull("Providers should now be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ ProviderRegistrationResult result = DynamicSaslRegistrar.registerSaslProviders();
+ assertEquals("Unexpected registration result when trying to re-register", ProviderRegistrationResult.EQUAL_ALREADY_REGISTERED, result);
+ assertNotNull("Providers should still be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+ }
+
+ @SuppressWarnings("serial")
+ public void testRegisterDefaultProviderWhenAnotherIsAlreadyPresentWithDifferentFactories()
+ {
+ assertNull("Provider should not be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ //Add a test provider with the same name, version, info as the default client provider, but with different factory properties (none).
+ Provider testProvider = new Provider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME,
+ JCAProvider.QPID_CLIENT_SASL_PROVIDER_VERSION,
+ JCAProvider.QPID_CLIENT_SASL_PROVIDER_INFO){};
+ Security.addProvider(testProvider);
+ assertSame("Test provider should be registered", testProvider, DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ //Try to register the default provider now that another with the same name etc (but different factories)
+ //is already registered, expect it not to be registered as a result.
+ ProviderRegistrationResult result = DynamicSaslRegistrar.registerSaslProviders();
+ assertEquals("Unexpected registration result", ProviderRegistrationResult.DIFFERENT_ALREADY_REGISTERED, result);
+
+ //Verify the test provider is still registered
+ assertSame("Test provider should still be registered", testProvider, DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+ }
+
+ public void testRegisterWithNoFactories()
+ {
+ File emptyTempFile = TestFileUtils.createTempFile(this);
+
+ assertNull("Provider should not be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ //Adjust the location of the properties file to point at an empty file, so no factories are found to register.
+ setTestSystemProperty("amq.dynamicsaslregistrar.properties", emptyTempFile.getPath());
+
+ //Try to register the default provider, expect it it not to be registered because there were no factories.
+ ProviderRegistrationResult result = DynamicSaslRegistrar.registerSaslProviders();
+ assertEquals("Unexpected registration result", ProviderRegistrationResult.NO_SASL_FACTORIES, result);
+
+ assertNull("Provider should not be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+ }
+
+ public void testRegisterWithMissingFileGetsDefault()
+ {
+ //Create a temp file and then delete it, such that we get a path which doesn't exist
+ File tempFile = TestFileUtils.createTempFile(this);
+ assertTrue("Failed to delete file", tempFile.delete());
+
+ assertNull("Provider should not be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+
+ //Adjust the location of the properties file to point at non-existent file.
+ setTestSystemProperty("amq.dynamicsaslregistrar.properties", tempFile.getPath());
+
+ //Try to register the default provider, expect it to fall back to the default in the jar and succeed.
+ ProviderRegistrationResult result = DynamicSaslRegistrar.registerSaslProviders();
+ assertEquals("Unexpected registration result", ProviderRegistrationResult.SUCCEEDED, result);
+
+ assertNotNull("Provider should be registered", DynamicSaslRegistrar.findProvider(JCAProvider.QPID_CLIENT_SASL_PROVIDER_NAME));
+ }
+}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
index 412c458247..1e9e5b00a5 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
@@ -120,6 +120,48 @@ public class BrokerDetailsTest extends TestCase
{
assertTrue(urise.getReason().equals("Illegal character in port number"));
}
+ }
+
+ public void testToStringMasksKeyStorePassword() throws Exception
+ {
+ String url = "tcp://localhost:5672?key_store_password='password'";
+ BrokerDetails details = new AMQBrokerDetails(url);
+
+ String expectedToString = "tcp://localhost:5672?key_store_password='********'";
+ String actualToString = details.toString();
+
+ assertEquals("Unexpected toString", expectedToString, actualToString);
+ }
+
+ public void testToStringMasksTrustStorePassword() throws Exception
+ {
+ String url = "tcp://localhost:5672?trust_store_password='password'";
+ BrokerDetails details = new AMQBrokerDetails(url);
+
+ String expectedToString = "tcp://localhost:5672?trust_store_password='********'";
+ String actualToString = details.toString();
+
+ assertEquals("Unexpected toString", expectedToString, actualToString);
+ }
+
+ public void testDefaultSsl() throws URLSyntaxException
+ {
+ String brokerURL = "tcp://localhost:5672";
+ AMQBrokerDetails broker = new AMQBrokerDetails(brokerURL);
+
+ assertNull("default value should be null", broker.getProperty(BrokerDetails.OPTIONS_SSL));
+ }
+
+ public void testOverridingSsl() throws URLSyntaxException
+ {
+ String brokerURL = "tcp://localhost:5672?ssl='true'";
+ AMQBrokerDetails broker = new AMQBrokerDetails(brokerURL);
+
+ assertTrue("value should be true", Boolean.valueOf(broker.getProperty(BrokerDetails.OPTIONS_SSL)));
+
+ brokerURL = "tcp://localhost:5672?ssl='false''&maxprefetch='1'";
+ broker = new AMQBrokerDetails(brokerURL);
+ assertFalse("value should be false", Boolean.valueOf(broker.getProperty(BrokerDetails.OPTIONS_SSL)));
}
}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
index 392ef1f29b..8c193622e3 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
@@ -30,7 +30,6 @@ import org.apache.qpid.url.URLSyntaxException;
public class ConnectionURLTest extends TestCase
{
-
public void testFailoverURL() throws URLSyntaxException
{
String url = "amqp://ritchiem:bob@/test?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin?cyclecount='100''";
@@ -252,55 +251,47 @@ public class ConnectionURLTest extends TestCase
assertTrue(service.getPort() == 5672);
}
- public void testSingleTransportDefaultedBrokerWithIPandPort() throws URLSyntaxException
+ public void testConnectionURLOptionToStringMasksPassword() throws URLSyntaxException
{
- String url = "amqp://guest:guest@/test?brokerlist='127.0.0.1:1234'";
+ String url = "amqp://guest:guest@client/localhost?brokerlist='tcp://localhost:1234'";
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ String expectedToString = "amqp://guest:********@client/localhost?brokerlist='tcp://localhost:1234'";
+ String actualToString = connectionurl.toString();
+ assertEquals("Unexpected toString form", expectedToString, actualToString);
+ }
+
+ public void testConnectionURLOptionToStringMasksSslTrustStorePassword() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@client/vhost?brokerlist='tcp://host:1234?trust_store_password='truststorepassword''";
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
-// ConnectionURL connectionurl = new AMQConnectionURL(url);
-//
-// assertTrue(connectionurl.getFailoverMethod() == null);
-// assertTrue(connectionurl.getUsername().equals("guest"));
-// assertTrue(connectionurl.getPassword().equals("guest"));
-// assertTrue(connectionurl.getVirtualHost().equals("/temp"));
-//
-//
-// assertTrue(connectionurl.getBrokerCount() == 1);
-//
-// BrokerDetails service = connectionurl.getBrokerDetails(0);
-//
-// assertTrue(service.getTransport().equals("tcp"));
-//
-// assertTrue(service.getHost().equals("127.0.0.1"));
-// assertTrue(service.getPort() == 1234);
+ String expectedToString = "amqp://guest:********@client/vhost?brokerlist='tcp://host:1234?trust_store_password='********''";
+ String actualToString = connectionurl.toString();
+ assertEquals("Unexpected toString form", expectedToString, actualToString);
+ }
+
+ public void testConnectionURLOptionToStringMasksSslKeyStorePassword() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@client/vhost?brokerlist='tcp://host:1234?key_store_password='keystorepassword1';tcp://host:1235?key_store_password='keystorepassword2''";
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ String expectedToString = "amqp://guest:********@client/vhost?brokerlist='tcp://host:1234?key_store_password='********';tcp://host:1235?key_store_password='********''";
+ String actualToString = connectionurl.toString();
+ assertEquals("Unexpected toString form", expectedToString, actualToString);
}
/**
* Test for QPID-3662 to ensure the {@code toString()} representation is correct.
*/
- public void testConnectionURLOptionToString() throws URLSyntaxException
+ public void testConnectionURLOptionToStringWithMaxPreftech() throws URLSyntaxException
{
String url = "amqp://guest:guest@client/localhost?maxprefetch='1'&brokerlist='tcp://localhost:1234?tcp_nodelay='true''";
ConnectionURL connectionurl = new AMQConnectionURL(url);
- assertNull(connectionurl.getFailoverMethod());
- assertEquals("guest", connectionurl.getUsername());
- assertEquals("guest", connectionurl.getPassword());
- assertEquals("client", connectionurl.getClientName());
- assertEquals("/localhost", connectionurl.getVirtualHost());
- assertEquals("1", connectionurl.getOption("maxprefetch"));
- assertTrue(connectionurl.getBrokerCount() == 1);
-
- BrokerDetails service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("localhost"));
- assertTrue(service.getPort() == 1234);
- assertTrue(service.getProperties().containsKey("tcp_nodelay"));
- assertEquals("true", service.getProperties().get("tcp_nodelay"));
-
- String nopasswd = "amqp://guest:********@client/localhost?maxprefetch='1'&brokerlist='tcp://localhost:1234?tcp_nodelay='true''";
- String tostring = connectionurl.toString();
- assertEquals(tostring.indexOf("maxprefetch"), tostring.lastIndexOf("maxprefetch"));
- assertEquals(nopasswd, tostring);
+ String expectedToString = "amqp://guest:********@client/localhost?maxprefetch='1'&brokerlist='tcp://localhost:1234?tcp_nodelay='true''";
+ String actualToString = connectionurl.toString();
+ assertEquals("Unexpected toString form", expectedToString, actualToString);
}
public void testSingleTransportMultiOptionURL() throws URLSyntaxException
@@ -572,9 +563,64 @@ public class ConnectionURLTest extends TestCase
connectionurl.getOption(ConnectionURL.OPTIONS_REJECT_BEHAVIOUR));
}
- public static junit.framework.Test suite()
+ /**
+ * Verify that when the ssl option is not specified, asking for the option returns null,
+ * such that this can later be used to verify it wasnt specified.
+ */
+ public void testDefaultSsl() throws URLSyntaxException
{
- return new junit.framework.TestSuite(ConnectionURLTest.class);
+ String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&foo='bar'";
+ ConnectionURL connectionURL = new AMQConnectionURL(url);
+
+ assertNull("default ssl value should be null", connectionURL.getOption(ConnectionURL.OPTIONS_SSL));
+ }
+
+ /**
+ * Verify that when the ssl option is specified, asking for the option returns the value,
+ * such that this can later be used to verify what value it was specified as.
+ */
+ public void testOverridingSsl() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&ssl='true'";
+ ConnectionURL connectionURL = new AMQConnectionURL(url);
+
+ assertTrue("value should be true", Boolean.valueOf(connectionURL.getOption(ConnectionURL.OPTIONS_SSL)));
+
+ url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&ssl='false'";
+ connectionURL = new AMQConnectionURL(url);
+
+ assertFalse("value should be false", Boolean.valueOf(connectionURL.getOption(ConnectionURL.OPTIONS_SSL)));
+ }
+
+ /**
+ * Verify that when the {@value ConnectionURL#OPTIONS_VERIFY_QUEUE_ON_SEND} option is not
+ * specified, asking for the option returns null, such that this can later be used to
+ * verify it wasn't specified.
+ */
+ public void testDefaultVerifyQueueOnSend() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&foo='bar'";
+ ConnectionURL connectionURL = new AMQConnectionURL(url);
+
+ assertNull("default ssl value should be null", connectionURL.getOption(ConnectionURL.OPTIONS_SSL));
+ }
+
+ /**
+ * Verify that when the {@value ConnectionURL#OPTIONS_VERIFY_QUEUE_ON_SEND} option is
+ * specified, asking for the option returns the value, such that this can later be used
+ * to verify what value it was specified as.
+ */
+ public void testOverridingVerifyQueueOnSend() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&verifyQueueOnSend='true'";
+ ConnectionURL connectionURL = new AMQConnectionURL(url);
+
+ assertTrue("value should be true", Boolean.valueOf(connectionURL.getOption(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND)));
+
+ url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'&verifyQueueOnSend='false'";
+ connectionURL = new AMQConnectionURL(url);
+
+ assertFalse("value should be false", Boolean.valueOf(connectionURL.getOption(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND)));
}
}
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java
index 9addb0ee71..8f578e6a2f 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/destinationurl/DestinationURLTest.java
@@ -193,6 +193,126 @@ public class DestinationURLTest extends TestCase
assertTrue(dest.getQueueName().equals("test:testQueueD"));
}
+ public void testExchangeOptionsNotPresent() throws URISyntaxException
+ {
+ String url = "exchangeClass://exchangeName/Destination/Queue";
+
+ AMQBindingURL burl = new AMQBindingURL(url);
+
+ assertTrue(url.equals(burl.toString()));
+
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_DURABLE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_AUTODELETE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_INTERNAL));
+
+ class MyTestAMQDestination extends AMQDestination
+ {
+ public MyTestAMQDestination(BindingURL url)
+ {
+ super(url);
+ }
+ public boolean isNameRequired()
+ {
+ return false;
+ }
+ };
+
+ AMQDestination dest = new MyTestAMQDestination(burl);
+ assertFalse(dest.isExchangeAutoDelete());
+ assertFalse(dest.isExchangeDurable());
+ assertFalse(dest.isExchangeInternal());
+ }
+
+ public void testExchangeAutoDeleteOptionPresent() throws URISyntaxException
+ {
+ String url = "exchangeClass://exchangeName/Destination/Queue?" + BindingURL.OPTION_EXCHANGE_AUTODELETE + "='true'";
+
+ AMQBindingURL burl = new AMQBindingURL(url);
+
+ assertTrue(url.equals(burl.toString()));
+
+ assertEquals("true", burl.getOption(BindingURL.OPTION_EXCHANGE_AUTODELETE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_DURABLE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_INTERNAL));
+
+ class MyTestAMQDestination extends AMQDestination
+ {
+ public MyTestAMQDestination(BindingURL url)
+ {
+ super(url);
+ }
+ public boolean isNameRequired()
+ {
+ return false;
+ }
+ };
+
+ AMQDestination dest = new MyTestAMQDestination(burl);
+ assertTrue(dest.isExchangeAutoDelete());
+ assertFalse(dest.isExchangeDurable());
+ assertFalse(dest.isExchangeInternal());
+ }
+
+ public void testExchangeDurableOptionPresent() throws URISyntaxException
+ {
+ String url = "exchangeClass://exchangeName/Destination/Queue?" + BindingURL.OPTION_EXCHANGE_DURABLE + "='true'";
+
+ AMQBindingURL burl = new AMQBindingURL(url);
+
+ assertTrue(url.equals(burl.toString()));
+
+ assertEquals("true", burl.getOption(BindingURL.OPTION_EXCHANGE_DURABLE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_AUTODELETE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_INTERNAL));
+
+ class MyTestAMQDestination extends AMQDestination
+ {
+ public MyTestAMQDestination(BindingURL url)
+ {
+ super(url);
+ }
+ public boolean isNameRequired()
+ {
+ return false;
+ }
+ };
+
+ AMQDestination dest = new MyTestAMQDestination(burl);
+ assertTrue(dest.isExchangeDurable());
+ assertFalse(dest.isExchangeAutoDelete());
+ assertFalse(dest.isExchangeInternal());
+ }
+
+ public void testExchangeInternalOptionPresent() throws URISyntaxException
+ {
+ String url = "exchangeClass://exchangeName/Destination/Queue?" + BindingURL.OPTION_EXCHANGE_INTERNAL + "='true'";
+
+ AMQBindingURL burl = new AMQBindingURL(url);
+
+ assertTrue(url.equals(burl.toString()));
+
+ assertEquals("true", burl.getOption(BindingURL.OPTION_EXCHANGE_INTERNAL));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_AUTODELETE));
+ assertNull(burl.getOption(BindingURL.OPTION_EXCHANGE_DURABLE));
+
+ class MyTestAMQDestination extends AMQDestination
+ {
+ public MyTestAMQDestination(BindingURL url)
+ {
+ super(url);
+ }
+ public boolean isNameRequired()
+ {
+ return false;
+ }
+ };
+
+ AMQDestination dest = new MyTestAMQDestination(burl);
+ assertTrue(dest.isExchangeInternal());
+ assertFalse(dest.isExchangeDurable());
+ assertFalse(dest.isExchangeAutoDelete());
+ }
+
public void testRejectBehaviourPresent() throws URISyntaxException
{
String url = "exchangeClass://exchangeName/Destination/Queue?rejectbehaviour='server'";
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java b/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
index f199961b6f..4ad9069ba0 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java
@@ -124,7 +124,7 @@ public class TestAMQSession extends AMQSession_0_8
return false;
}
- public void sendConsume(BasicMessageConsumer_0_8 consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, boolean nowait, int tag) throws AMQException, FailoverException
+ public void sendConsume(BasicMessageConsumer_0_8 consumer, AMQShortString queueName, boolean nowait, int tag) throws AMQException, FailoverException
{
}
@@ -139,13 +139,13 @@ public class TestAMQSession extends AMQSession_0_8
return null;
}
- public void sendExchangeDeclare(AMQShortString name, AMQShortString type, AMQProtocolHandler protocolHandler, boolean nowait) throws AMQException, FailoverException
+ public void sendExchangeDeclare(AMQShortString name, AMQShortString type, boolean nowait, boolean durable, boolean autoDelete, boolean internal) throws AMQException, FailoverException
{
}
public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler,
- boolean nowait, boolean passive) throws AMQException, FailoverException
+ boolean passive) throws AMQException, FailoverException
{
}
@@ -189,14 +189,6 @@ public class TestAMQSession extends AMQSession_0_8
{
}
- public void handleAddressBasedDestination(AMQDestination dest,
- boolean isConsumer,
- boolean noWait) throws AMQException
- {
- throw new UnsupportedOperationException("The new addressing based sytanx is "
- + "not supported for AMQP 0-8/0-9 versions");
- }
-
@Override
protected void flushAcknowledgments()
{
diff --git a/java/common.xml b/java/common.xml
index 2b61ef08c2..ce5693fd28 100644
--- a/java/common.xml
+++ b/java/common.xml
@@ -23,7 +23,10 @@
<dirname property="project.root" file="${ant.file.common}"/>
<property name="project.name" value="qpid"/>
- <property name="project.version" value="0.19"/>
+ <!-- Version used for standard build output -->
+ <property name="project.version" value="0.21"/>
+ <!-- The release version used for maven output. SNAPSHOT added via maven.version.suffix -->
+ <property name="project.version.maven" value="0.22"/>
<property name="project.url" value="http://qpid.apache.org"/>
<property name="project.groupid" value="org.apache.qpid"/>
<property name="project.namever" value="${project.name}-${project.version}"/>
@@ -42,7 +45,7 @@
<property name="build.report" location="${build}/report"/>
<property name="build.release" location="${build}/release"/>
<property name="build.release.prepare" location="${build.release}/prepare"/>
- <property name="build.plugins" location="${build}/lib/plugins"/>
+ <property name="build.scratch.broker.plugins.lib" location="${build.scratch}/broker-plugins/lib"/>
<property name="build.coverage.report" location="${build}/coverage/report"/>
<property name="build.coverage.src" location="${build}/coverage/src"/>
<property name="build.findbugs" location="${build}/findbugs"/>
@@ -93,6 +96,10 @@
<property name="nexus.host" value="repository.apache.org"/>
<property name="nexus.upload.url" value="https://${nexus.host}/service/local/staging/deploy/maven2"/>
+ <!-- properties for deplying snapshot artifacts -->
+ <property name="maven.snapshots.repo.id" value="apache.snapshots.https"/>
+ <property name="maven.snapshots.repo.url" value="https://${nexus.host}/content/repositories/snapshots"/>
+
<!-- properties for downloading ivy, and then our dependencies -->
<property name="ivy.jar.dir" value="${project.root}/lib/ivy" />
<property name="ivy.install.version" value="2.2.0" />
diff --git a/java/common/bin/qpid-run b/java/common/bin/qpid-run
index 1e373340ce..a10766b37a 100755
--- a/java/common/bin/qpid-run
+++ b/java/common/bin/qpid-run
@@ -88,10 +88,10 @@ SYSTEM_PROPS[${#SYSTEM_PROPS[@]}]="-DQPID_WORK=$QPID_WORK"
if [ -n "$QPID_LOG_PREFIX" ]; then
if [ "X$QPID_LOG_PREFIX" = "XPID" ]; then
log $INFO Using pid in qpid log name prefix
- LOG_PREFIX=" -Dlogprefix=$$"
+ LOG_PREFIX="-Dlogprefix=$$"
else
log $INFO Using qpid logprefix property
- LOG_PREFIX=" -Dlogprefix=$QPID_LOG_PREFIX"
+ LOG_PREFIX="-Dlogprefix=$QPID_LOG_PREFIX"
fi
SYSTEM_PROPS[${#SYSTEM_PROPS[@]}]="${LOG_PREFIX}"
fi
@@ -99,10 +99,10 @@ fi
if [ -n "$QPID_LOG_SUFFIX" ]; then
if [ "X$QPID_LOG_SUFFIX" = "XPID" ]; then
log $INFO Using pid in qpid log name suffix
- LOG_SUFFIX=" -Dlogsuffix=$$"
+ LOG_SUFFIX="-Dlogsuffix=$$"
else
log $INFO Using qpig logsuffix property
- LOG_SUFFIX=" -Dlogsuffix=$QPID_LOG_SUFFIX"
+ LOG_SUFFIX="-Dlogsuffix=$QPID_LOG_SUFFIX"
fi
SYSTEM_PROPS[${#SYSTEM_PROPS[@]}]="${LOG_SUFFIX}"
fi
diff --git a/java/common/build.xml b/java/common/build.xml
index 9caf93c026..e599c840db 100644
--- a/java/common/build.xml
+++ b/java/common/build.xml
@@ -53,7 +53,15 @@
</target>
<target name="compile_gentools">
- <ant dir="${gentools.home}" />
+ <mkdir dir="${gentools.build}/classes"/>
+ <javac srcdir="${gentools.home}/src" destdir="${gentools.build}/classes" source="${java.source}" target="${java.target}" fork="true" includeantruntime="false">
+ <classpath>
+ <fileset dir="${project.root}">
+ <include name="${velocity.jar}"/>
+ <include name="${velocity-dep.jar}"/>
+ </fileset>
+ </classpath>
+ </javac>
</target>
<target name="check_gentool_deps">
@@ -64,15 +72,12 @@
<target name="gentools" depends="compile_gentools,check_gentool_deps" unless="gentools.notRequired">
<mkdir dir="${framing.generated.dir}"/>
- <java classname="org.apache.qpid.gentools.Main" fork="true" dir="${gentools.home}/src" failonerror="true">
+ <java classname="org.apache.qpid.gentools.Main" fork="true" dir="${gentools.build}/classes" failonerror="true">
<arg line='-j -o "${framing.generated.dir}" -t "${project.root}/common/templates" ${xml.spec.list}'/>
<classpath>
- <pathelement path="${gentools.home}/src" />
- <fileset dir="${gentools.home}/lib">
- <include name="**/*.jar"/>
- </fileset>
- <pathelement path="${gentools.home}/lib/velocity-1.4.jar" />
- <pathelement path="${gentools.home}/lib/velocity-dep-1.4.jar" />
+ <pathelement path="${gentools.build}/classes" />
+ <pathelement path="${project.root}/${velocity.jar}" />
+ <pathelement path="${project.root}/${velocity-dep.jar}" />
</classpath>
</java>
<touch file="${gentools.timestamp}" />
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpClass.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpClass.java
new file mode 100644
index 0000000000..26195da2e3
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpClass.java
@@ -0,0 +1,197 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.Collection;
+
+public class AmqpClass implements Printable, NodeAware
+{
+
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+ private final AmqpFieldMap _fieldMap = new AmqpFieldMap();
+ private final AmqpMethodMap _methodMap = new AmqpMethodMap();
+ private final AmqpOrdinalVersionMap _indexMap = new AmqpOrdinalVersionMap();
+
+
+ private final String _name;
+ private final Generator _generator;
+
+ public AmqpClass(String name, Generator generator)
+ {
+ _name = name;
+ _generator = generator;
+ }
+
+ public boolean addFromNode(Node classNode, int ordinal, AmqpVersion version)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ getVersionSet().add(version);
+ int index = Utils.getNamedIntegerAttribute(classNode, "index");
+ AmqpVersionSet indexVersionSet = getIndexMap().get(index);
+ if (indexVersionSet != null)
+ {
+ indexVersionSet.add(version);
+ }
+ else
+ {
+ indexVersionSet = new AmqpVersionSet();
+ indexVersionSet.add(version);
+ getIndexMap().put(index, indexVersionSet);
+ }
+ NodeList nList = classNode.getChildNodes();
+ int fieldCntr = getFieldMap().size();
+ for (int i = 0; i < nList.getLength(); i++)
+ {
+ Node child = nList.item(i);
+ if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0)
+ {
+ String fieldName = getGenerator().prepareDomainName(Utils.getNamedAttribute(child,
+ Utils.ATTRIBUTE_NAME));
+ AmqpField thisField = getFieldMap().get(fieldName);
+ if (thisField == null)
+ {
+ thisField = new AmqpField(fieldName, getGenerator());
+ getFieldMap().add(fieldName, thisField);
+ }
+ if (!thisField.addFromNode(child, fieldCntr++, version))
+ {
+ String className = getGenerator().prepareClassName(Utils.getNamedAttribute(classNode,
+ Utils.ATTRIBUTE_NAME));
+ System.out.println("INFO: Generation supression tag found for field " +
+ className + "." + fieldName + " - removing.");
+ thisField.removeVersion(version);
+ getFieldMap().remove(fieldName);
+ }
+ }
+ else if (child.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0)
+ {
+ String methodName = getGenerator().prepareMethodName(Utils.getNamedAttribute(child,
+ Utils.ATTRIBUTE_NAME));
+ AmqpMethod thisMethod = getMethodMap().get(methodName);
+ if (thisMethod == null)
+ {
+ thisMethod = new AmqpMethod(methodName, getGenerator());
+ getMethodMap().put(methodName, thisMethod);
+ }
+ if (!thisMethod.addFromNode(child, 0, version))
+ {
+ String className = getGenerator().prepareClassName(Utils.getNamedAttribute(classNode,
+ Utils.ATTRIBUTE_NAME));
+ System.out.println("INFO: Generation supression tag found for method " +
+ className + "." + methodName + " - removing.");
+ thisMethod.removeVersion(version);
+ getMethodMap().remove(methodName);
+ }
+ }
+ else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0)
+ {
+ String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE);
+ if (value.compareTo("no-gen") == 0)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void removeVersion(AmqpVersion version)
+ {
+ getIndexMap().removeVersion(version);
+ getFieldMap().removeVersion(version);
+ getMethodMap().removeVersion(version);
+ getVersionSet().remove(version);
+ }
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ String margin = Utils.createSpaces(marginSize);
+ String tab = Utils.createSpaces(tabSize);
+ out.println(margin + "[C] " + getName() + ": " + getVersionSet());
+
+ for (Integer thisIndex : getIndexMap().keySet())
+ {
+ AmqpVersionSet indexVersionSet = getIndexMap().get(thisIndex);
+ out.println(margin + tab + "[I] " + thisIndex + indexVersionSet);
+ }
+
+ for (String thisFieldName : getFieldMap().keySet())
+ {
+ AmqpField thisField = getFieldMap().get(thisFieldName);
+ thisField.print(out, marginSize + tabSize, tabSize);
+ }
+
+ for (String thisMethodName : getMethodMap().keySet())
+ {
+ AmqpMethod thisMethod = getMethodMap().get(thisMethodName);
+ thisMethod.print(out, marginSize + tabSize, tabSize);
+ }
+ }
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public Generator getGenerator()
+ {
+ return _generator;
+ }
+
+
+ public AmqpFieldMap getFieldMap()
+ {
+ return _fieldMap;
+ }
+
+
+ public AmqpMethodMap getMethodMap()
+ {
+ return _methodMap;
+ }
+
+ public Collection<AmqpMethod> getMethods()
+ {
+ return getMethodMap().values();
+ }
+
+
+ public String getName()
+ {
+ return _name;
+ }
+
+
+ public AmqpOrdinalVersionMap getIndexMap()
+ {
+ return _indexMap;
+ }
+
+ public SingleVersionClass asSingleVersionClass(AmqpVersion version)
+ {
+ return new SingleVersionClass(this,version, _generator);
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java
new file mode 100644
index 0000000000..a27a50d07e
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpClassMap.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.gentools;
+
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpClassMap extends TreeMap<String, AmqpClass>
+{
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstant.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstant.java
new file mode 100644
index 0000000000..df5bc6c362
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstant.java
@@ -0,0 +1,191 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.PrintStream;
+import java.util.TreeMap;
+
+/**
+ * @author kpvdr
+ * Class to represent the &lt;constant&gt; declaration within the AMQP specification.
+ * Currently, only integer values exist within the specification, however looking forward
+ * to other possible types in the future, string and double types are also supported.
+ * <p/>
+ * The &lt;constant&gt; declaration in the specification contains only two attributes:
+ * name and value.
+ * <p/>
+ * The value of the constant is mapped against the version(s) for which the name is defined.
+ * This allows for a change in the value rather than the name only from one version to the next.
+ */
+@SuppressWarnings("serial")
+public class AmqpConstant extends TreeMap<String, AmqpVersionSet>
+ implements Printable, VersionConsistencyCheck, Comparable<AmqpConstant>
+{
+ /**
+ * Constant name as defined by the name attribute of the &lt;constant&gt; declaration.
+ */
+ private final String _name;
+
+ /**
+ * Set of versions for which this constant name is defined.
+ */
+ private final AmqpVersionSet _versionSet;
+
+ /**
+ * Constructor
+ *
+ * @param name Constant name as defined by the name attribute of the &lt;constant&gt; declaration.
+ * @param value Constant value as defined by the value attribute of the &lt;constant&gt; declaration.
+ * @param version AMQP version for which this constant is defined
+ */
+ public AmqpConstant(String name, String value, AmqpVersion version)
+ {
+ _name = name;
+ _versionSet = new AmqpVersionSet(version);
+ AmqpVersionSet valueVersionSet = new AmqpVersionSet(version);
+ put(value, valueVersionSet);
+ }
+
+
+ /**
+ * Get the name of this constant.
+ *
+ * @return Name of this constant, being the name attribute of the &lt;constant&gt; declaration
+ * represented by this class.
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ * Get the value of this constant as a String.
+ *
+ * @param version AMQP version for which this value is required.
+ * @return Value of this constant, being the value attribute of the &lt;constant&gt; declaration
+ * represented by this class.
+ * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
+ * defined in the AMQP specifications.
+ */
+ public String getStringValue(AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ for (String thisValue : keySet())
+ {
+ AmqpVersionSet versionSet = get(thisValue);
+ if (versionSet.contains(version))
+ {
+ return thisValue;
+ }
+ }
+ throw new AmqpTypeMappingException("Unable to find value for constant \"" + getName() +
+ "\" for version " + version.toString() + ".");
+ }
+
+ /**
+ * Get the value of this constant as an integer.
+ *
+ * @param version AMQP version for which this value is required.
+ * @return Value of this constant, being the value attribute of the &lt;constant&gt; declaration
+ * represented by this class.
+ * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
+ * defined in the AMQP specifications.
+ */
+ public int getIntegerValue(AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ return Integer.parseInt(getStringValue(version));
+ }
+
+ /**
+ * Get the value of this constant as a double.
+ *
+ * @param version AMQP version for which this value is required.
+ * @return Value of this constant, being the value attribute of the &lt;constant&gt; declaration
+ * represented by this class.
+ * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
+ * defined in the AMQP specifications.
+ */
+ public double getDoubleValue(AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ return Double.parseDouble(getStringValue(version));
+ }
+
+ /**
+ * Get the version set for this constant. It contains the all the versions for which this
+ * constant name exists.
+ *
+ * @return Set of versions for which this constant exists.
+ */
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+
+ public int compareTo(AmqpConstant other)
+ {
+ int res = getName().compareTo(other.getName());
+ if (res != 0)
+ {
+ return res;
+ }
+ return getVersionSet().compareTo(other.getVersionSet());
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.qpid.gentools.VersionConsistencyCheck#isVersionConsistent(org.apache.qpid.gentools.AmqpVersionSet)
+ */
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (size() != 1)
+ {
+ return false;
+ }
+ return get(firstKey()).equals(globalVersionSet);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int)
+ */
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ String margin = Utils.createSpaces(marginSize);
+ String tab = Utils.createSpaces(tabSize);
+ if (size() == 1)
+ {
+ out.println(margin + tab + "[C] " + getName() + " = \"" + firstKey() + "\" " + getVersionSet());
+ }
+ else
+ {
+ out.println(margin + tab + "[C] " + getName() + ": " + getVersionSet());
+ for (String thisValue : keySet())
+ {
+ out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue));
+ }
+ }
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java
new file mode 100644
index 0000000000..ab8b8be61e
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+/**
+ * @author kpvdr
+ * This class implements a set collection for {@link AmqpConstant AmqpConstant} objects, being the collection
+ * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set.
+ * The {@link AmqpConstant AmqpConstant} objects (derived from {@link java.util.TreeMap TreeMap}) keep track of
+ * the value and version(s) assigned to this name.
+ */
+@SuppressWarnings("serial")
+public class AmqpConstantSet implements Printable, NodeAware //, Comparable<AmqpConstantSet>
+{
+ private final LanguageConverter _converter;
+ private final TreeSet<AmqpConstant> _constants = new TreeSet<AmqpConstant>();
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+
+ public AmqpConstantSet(LanguageConverter converter)
+ {
+ _converter = converter;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.qpid.gentools.NodeAware#addFromNode(org.w3c.dom.Node, int, org.apache.qpid.gentools.AmqpVersion)
+ */
+ public boolean addFromNode(Node node, int ordinal, AmqpVersion version)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ _versionSet.add(version);
+ NodeList nodeList = node.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++)
+ {
+ Node childNode = nodeList.item(i);
+ if (childNode.getNodeName().compareTo(Utils.ELEMENT_CONSTANT) == 0)
+ {
+ String name = getConverter().prepareConstantName(Utils.getNamedAttribute(childNode, Utils.ATTRIBUTE_NAME));
+ String value = Utils.getNamedAttribute(childNode, Utils.ATTRIBUTE_VALUE);
+ // Find this name in the existing set of objects
+ boolean foundName = false;
+ Iterator<AmqpConstant> cItr = _constants.iterator();
+ while (cItr.hasNext() && !foundName)
+ {
+ AmqpConstant thisConstant = cItr.next();
+ if (name.compareTo(thisConstant.getName()) == 0)
+ {
+ foundName = true;
+ thisConstant.getVersionSet().add(version);
+ // Now, find the value in the map
+ boolean foundValue = false;
+ for (String thisValue : thisConstant.keySet())
+ {
+ if (value.compareTo(thisValue) == 0)
+ {
+ foundValue = true;
+ // Add this version to existing version set.
+ AmqpVersionSet versionSet = thisConstant.get(thisValue);
+ versionSet.add(version);
+ }
+ }
+ // Check that the value was found - if not, add it
+ if (!foundValue)
+ {
+ thisConstant.put(value, new AmqpVersionSet(version));
+ }
+ }
+ }
+ // Check that the name was found - if not, add it
+ if (!foundName)
+ {
+ _constants.add(new AmqpConstant(name, value, version));
+ }
+ }
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int)
+ */
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ out.println(Utils.createSpaces(marginSize) + "Constants: ");
+ for (AmqpConstant thisAmqpConstant : _constants)
+ {
+ thisAmqpConstant.print(out, marginSize, tabSize);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+// public int compareTo(AmqpConstantSet other)
+// {
+// int res = size() - other.size();
+// if (res != 0)
+// return res;
+// Iterator<AmqpConstant> cItr = iterator();
+// Iterator<AmqpConstant> oItr = other.iterator();
+// while (cItr.hasNext() && oItr.hasNext())
+// {
+// AmqpConstant constant = cItr.next();
+// AmqpConstant oConstant = oItr.next();
+// res = constant.compareTo(oConstant);
+// if (res != 0)
+// return res;
+// }
+// return 0;
+// }
+
+ public Iterable<? extends AmqpConstant> getContstants()
+ {
+ return _constants;
+ }
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public LanguageConverter getConverter()
+ {
+ return _converter;
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomain.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomain.java
new file mode 100644
index 0000000000..ba8552a6a6
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomain.java
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.PrintStream;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpDomain extends TreeMap<String, AmqpVersionSet> implements Printable
+{
+ private final String _domainName;
+
+ public AmqpDomain(String domainName)
+ {
+ _domainName = domainName;
+ }
+
+ public void addDomain(String domainType, AmqpVersion version) throws AmqpParseException
+ {
+ AmqpVersionSet versionSet = get(domainType);
+ if (versionSet == null) // First time, create new entry
+ {
+ versionSet = new AmqpVersionSet();
+ put(domainType, versionSet);
+ }
+ versionSet.add(version);
+ }
+
+ public String getDomainType(AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ for (String thisDomainType : keySet())
+ {
+ AmqpVersionSet versionSet = get(thisDomainType);
+ if (versionSet.contains(version))
+ {
+ return thisDomainType;
+ }
+ }
+ throw new AmqpTypeMappingException("Unable to find version " + version + ".");
+ }
+
+ public boolean hasVersion(String type, AmqpVersion v)
+ {
+ AmqpVersionSet vs = get(type);
+ if (vs == null)
+ {
+ return false;
+ }
+ return vs.contains(v);
+ }
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ String margin = Utils.createSpaces(marginSize);
+ String tab = Utils.createSpaces(tabSize);
+ out.println(margin + getDomainName() + ":");
+
+ for (String thisDomainType : keySet())
+ {
+ AmqpVersionSet vs = get(thisDomainType);
+ out.println(margin + tab + thisDomainType + " : " + vs.toString());
+ }
+ }
+
+ public String getDomainName()
+ {
+ return _domainName;
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java
new file mode 100644
index 0000000000..0cd9d214bd
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpDomainMap extends TreeMap<String, AmqpDomain> implements Printable, NodeAware
+{
+ private final LanguageConverter _converter;
+
+ public AmqpDomainMap(LanguageConverter converter)
+ {
+ _converter = converter;
+
+ }
+
+ public boolean addFromNode(Node n, int o, AmqpVersion v)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ NodeList nl = n.getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++)
+ {
+ Node c = nl.item(i);
+ // All versions 0.9 and greater use <domain> for all domains
+ if (c.getNodeName().compareTo(Utils.ELEMENT_DOMAIN) == 0)
+ {
+ String domainName = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME));
+ String type = Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE);
+ AmqpDomain thisDomain = get(domainName);
+ if (thisDomain == null)
+ {
+ thisDomain = new AmqpDomain(domainName);
+ put(domainName, thisDomain);
+ }
+ thisDomain.addDomain(type, v);
+ }
+ // Version(s) 0.8 and earlier use <domain> for all complex domains and use
+ // attribute <field type=""...> for simple types. Add these simple types to
+ // domain list - but beware of duplicates!
+ else if (c.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0)
+ {
+ try
+ {
+ String type = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE));
+ AmqpDomain thisDomain = get(type);
+ if (thisDomain == null)
+ {
+ thisDomain = new AmqpDomain(type);
+ put(type, thisDomain);
+ }
+ if (!thisDomain.hasVersion(type, v))
+ {
+ thisDomain.addDomain(type, v);
+ }
+ }
+ catch (AmqpParseException e)
+ {
+ } // Ignore fields without type attribute
+ }
+ else if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0 ||
+ c.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0)
+ {
+ addFromNode(c, 0, v);
+ }
+ }
+ return true;
+ }
+
+ public String getDomainType(String domainName, AmqpVersion version)
+ {
+ AmqpDomain domainType = get(domainName);
+ // For AMQP 8.0, primitive types were not described as domains, so
+ // return itself as the type.
+ if (domainType == null)
+ {
+ return domainName;
+ }
+ try
+ {
+ return domainType.getDomainType(version);
+ }
+ catch (AmqpTypeMappingException e)
+ {
+ throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName +
+ "\" version " + version + ".");
+ }
+ }
+
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ out.println(Utils.createSpaces(marginSize) + "Domain Map:");
+ for (String thisDomainName : keySet())
+ {
+ AmqpDomain domain = get(thisDomainName);
+ domain.print(out, marginSize + tabSize, tabSize);
+ }
+ }
+
+ public LanguageConverter getConverter()
+ {
+ return _converter;
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java
new file mode 100644
index 0000000000..e39550b96f
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.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.gentools;
+
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpDomainVersionMap extends TreeMap<String, AmqpVersionSet> implements VersionConsistencyCheck
+{
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (size() != 1)
+ {
+ return false;
+ }
+ return get(firstKey()).equals(globalVersionSet);
+ }
+
+ public boolean removeVersion(AmqpVersion version)
+ {
+ Boolean res = false;
+ ArrayList<String> removeList = new ArrayList<String>();
+ for (String domainName : keySet())
+ {
+ AmqpVersionSet versionSet = get(domainName);
+ if (versionSet.contains(version))
+ {
+ versionSet.remove(version);
+ if (versionSet.isEmpty())
+ {
+ removeList.add(domainName);
+ }
+ res = true;
+ }
+ }
+ // Get rid of domains no longer in use
+ for (String domainName : removeList)
+ {
+ remove(domainName);
+ }
+ return res;
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpField.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpField.java
new file mode 100644
index 0000000000..7c721cf913
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpField.java
@@ -0,0 +1,269 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck
+{
+
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+ private final AmqpDomainVersionMap _domainMap = new AmqpDomainVersionMap();
+ private final AmqpOrdinalVersionMap _ordinalMap = new AmqpOrdinalVersionMap();
+
+ private final String _name;
+ private final Generator _generator;
+
+ private final Map<AmqpVersion, String> _versionToDomainMap = new HashMap<AmqpVersion, String>();
+ private final Map<AmqpVersion, Integer> _versionToOrdinalMap = new HashMap<AmqpVersion, Integer>();
+
+
+ public AmqpField(String name, Generator generator)
+ {
+ _name = name;
+ _generator = generator;
+
+ }
+
+ public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ _versionSet.add(version);
+ String domainType;
+ // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields.
+ try
+ {
+ domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN));
+ }
+ catch (AmqpParseException e)
+ {
+ domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE));
+ }
+ AmqpVersionSet thisVersionList = _domainMap.get(domainType);
+ if (thisVersionList == null) // First time, create new entry
+ {
+ thisVersionList = new AmqpVersionSet();
+ _domainMap.put(domainType, thisVersionList);
+ }
+
+ _versionToDomainMap.put(version, domainType);
+ _versionToOrdinalMap.put(version, ordinal);
+
+ thisVersionList.add(version);
+ thisVersionList = _ordinalMap.get(ordinal);
+ if (thisVersionList == null) // First time, create new entry
+ {
+ thisVersionList = new AmqpVersionSet();
+ _ordinalMap.put(ordinal, thisVersionList);
+ }
+ thisVersionList.add(version);
+ NodeList nList = fieldNode.getChildNodes();
+ for (int i = 0; i < nList.getLength(); i++)
+ {
+ Node child = nList.item(i);
+ if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0)
+ {
+ String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE);
+ if (value.compareTo("no-gen") == 0)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void removeVersion(AmqpVersion version)
+ {
+ _domainMap.removeVersion(version);
+ _ordinalMap.removeVersion(version);
+ _versionSet.remove(version);
+ }
+
+ public boolean isCodeTypeConsistent(LanguageConverter converter)
+ throws AmqpTypeMappingException
+ {
+ if (_domainMap.size() == 1)
+ {
+ return true; // By definition
+ }
+ ArrayList<String> codeTypeList = new ArrayList<String>();
+ for (String thisDomainName : _domainMap.keySet())
+ {
+ AmqpVersionSet versionSet = _domainMap.get(thisDomainName);
+ String codeType = converter.getGeneratedType(thisDomainName, versionSet.first());
+ if (!codeTypeList.contains(codeType))
+ {
+ codeTypeList.add(codeType);
+ }
+ }
+ return codeTypeList.size() == 1;
+ }
+
+ public boolean isConsistent(Generator generator)
+ throws AmqpTypeMappingException
+ {
+ if (!isCodeTypeConsistent(generator))
+ {
+ return false;
+ }
+ if (_ordinalMap.size() != 1)
+ {
+ return false;
+ }
+ // Since the various doamin names map to the same code type, add the version occurrences
+ // across all domains to see we have all possible versions covered
+ int vCntr = 0;
+ for (String thisDomainName : _domainMap.keySet())
+ {
+ vCntr += _domainMap.get(thisDomainName).size();
+ }
+ return vCntr == generator.getVersionSet().size();
+ }
+
+ public boolean isTypeAndNameConsistent(Generator generator)
+ throws AmqpTypeMappingException
+ {
+ if (!isCodeTypeConsistent(generator))
+ {
+ return false;
+ }
+ // Since the various doamin names map to the same code type, add the version occurrences
+ // across all domains to see we have all possible versions covered
+ int vCntr = 0;
+ for (String thisDomainName : _domainMap.keySet())
+ {
+ vCntr += _domainMap.get(thisDomainName).size();
+ }
+ return vCntr == getVersionSet().size();
+ }
+
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ String margin = Utils.createSpaces(marginSize);
+ out.println(margin + "[F] " + _name + ": " + _versionSet);
+
+ for (Integer thisOrdinal : _ordinalMap.keySet())
+ {
+ AmqpVersionSet versionList = _ordinalMap.get(thisOrdinal);
+ out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString());
+ }
+
+ for (String thisDomainName : _domainMap.keySet())
+ {
+ AmqpVersionSet versionList = _domainMap.get(thisDomainName);
+ out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString());
+ }
+ }
+
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (!_versionSet.equals(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_domainMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_ordinalMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+ public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (!_versionSet.equals(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_domainMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_ordinalMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public String getDomain(AmqpVersion version)
+ {
+ return _versionToDomainMap.get(version);
+ }
+
+ public String getConsistentNativeType()
+ {
+ return _generator.getNativeType(_generator.getDomainType(getDomain(_versionSet.first()),_versionSet.first()));
+ }
+
+ public int getOrdinal(AmqpVersion version)
+ {
+ return _versionToOrdinalMap.get(version);
+ }
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public AmqpDomainVersionMap getDomainMap()
+ {
+ return _domainMap;
+ }
+
+ public AmqpOrdinalVersionMap getOrdinalMap()
+ {
+ return _ordinalMap;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public LanguageConverter getGenerator()
+ {
+ return _generator;
+ }
+
+ public Map<AmqpVersion, String> getVersionToDomainMap()
+ {
+ return _versionToDomainMap;
+ }
+
+ public Map<AmqpVersion, Integer> getVersionToOrdinalMap()
+ {
+ return _versionToOrdinalMap;
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java
new file mode 100644
index 0000000000..0bb5e03a61
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java
@@ -0,0 +1,452 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpFieldMap implements VersionConsistencyCheck
+{
+
+ private final TreeMap<String, AmqpField> _map = new TreeMap<String, AmqpField>();
+
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+
+ public void removeVersion(AmqpVersion version)
+ {
+ String[] fieldNameArray = new String[size()];
+ _map.keySet().toArray(fieldNameArray);
+ Iterator<Entry<String, AmqpField>> iter = _map.entrySet().iterator();
+
+ while (iter.hasNext())
+ {
+ Entry<String, AmqpField> entry = iter.next();
+ entry.getValue().removeVersion(version);
+ iter.remove();
+ }
+ }
+
+ public int size()
+ {
+ return _map.size();
+
+ }
+
+ public AmqpFieldMap getFieldMapForOrdinal(int ordinal)
+ {
+ AmqpFieldMap newMap = new AmqpFieldMap();
+ for (AmqpField field : _map.values())
+ {
+
+ TreeMap<Integer, AmqpVersionSet> ordinalMap = field.getOrdinalMap();
+ AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal);
+ if (ordinalVersions != null)
+ {
+ newMap.add(field.getName(), field);
+ }
+ }
+ return newMap;
+ }
+
+ public void add(String name, AmqpField field)
+ {
+ _versionSet.addAll(field.getVersionSet());
+ _map.put(name, field);
+ }
+
+ public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version, boolean codeTypeFlag,
+ LanguageConverter converter)
+ {
+ // TODO: REVIEW THIS! There may be a bug here that affects C++ generation (only with >1 version)...
+ // If version == null (a common scenario) then the version map is built up on the
+ // basis of first found item, and ignores other version variations.
+ // This should probably be disallowed by throwing an NPE, as AmqpOrdinalFieldMap cannot
+ // represent these possibilities.
+ // *OR*
+ // Change the structure of AmqpOrdianlFieldMap to allow for the various combinations that
+ // will result from version variation - but that is what AmqpFieldMap is... :-$
+ AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap();
+ for (AmqpField field : _map.values())
+ {
+
+ if (version == null || field.getVersionSet().contains(version))
+ {
+ // 1. Search for domain name in field domain map with version that matches
+ String domain = "";
+ boolean dFound = false;
+ for (String thisDomainName : field.getDomainMap().keySet())
+ {
+ domain = thisDomainName;
+ AmqpVersionSet versionSet = field.getDomainMap().get(domain);
+ if (version == null || versionSet.contains(version))
+ {
+ if (codeTypeFlag)
+ {
+ domain = converter.getGeneratedType(domain, version);
+ }
+ dFound = true;
+ }
+ }
+
+ // 2. Search for ordinal in field ordianl map with version that matches
+ int ordinal = -1;
+ boolean oFound = false;
+ for (Integer thisOrdinal : field.getOrdinalMap().keySet())
+ {
+ ordinal = thisOrdinal;
+ AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal);
+ if (version == null || versionSet.contains(version))
+ {
+ oFound = true;
+ }
+ }
+
+ if (dFound && oFound)
+ {
+ String[] fieldDomainPair = {field.getName(), domain};
+ ordinalFieldMap.put(ordinal, fieldDomainPair);
+ }
+ }
+ }
+ return ordinalFieldMap;
+ }
+
+ public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet)
+ throws AmqpTypeMappingException
+ {
+ if (size() != 1) // Only one field for this ordinal
+ {
+ return false;
+ }
+ return _map.get(_map.firstKey()).isConsistent(generator);
+ }
+
+ public int getNumFields(AmqpVersion version)
+ {
+ int fCntr = 0;
+ for (AmqpField field : _map.values())
+ {
+
+ if (field.getVersionSet().contains(version))
+ {
+ fCntr++;
+ }
+ }
+ return fCntr;
+ }
+
+ public String parseFieldMap(CommandGenerateMethod commonGenerateMethod, MangledGenerateMethod mangledGenerateMethod,
+ int indentSize, int tabSize, LanguageConverter converter)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String cr = Utils.LINE_SEPARATOR;
+ StringBuffer sb = new StringBuffer();
+
+ if (commonGenerateMethod == null)
+ {
+ // Generate warnings in code if required methods are null.
+ sb.append(indent + "/*********************************************************" + cr);
+ sb.append(indent + " * WARNING: Generated code could be missing." + cr);
+ sb.append(indent + " * In call to parseFieldMap(), generation method was null." + cr);
+ sb.append(indent + " * Check for NoSuchMethodException on startup." + cr);
+ sb.append(indent + " *********************************************************/" + cr);
+ }
+
+ Iterator<Entry<String, AmqpField>> itr = _map.entrySet().iterator();
+ while (itr.hasNext())
+ {
+ Entry<String, AmqpField> entry = itr.next();
+ String fieldName = entry.getKey();
+ AmqpField field = entry.getValue();
+ if (field.isCodeTypeConsistent(converter))
+ {
+ // All versions identical - Common declaration
+ String domainName = field.getDomainMap().firstKey();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = converter.getGeneratedType(domainName, versionSet.first());
+ if (commonGenerateMethod != null)
+ {
+ sb.append(commonGenerateMethod.generate(codeType, field, versionSet,
+ indentSize, tabSize, itr.hasNext()));
+ }
+ }
+ else if (mangledGenerateMethod != null) // Version-mangled
+ {
+ sb.append(mangledGenerateMethod.generate(field, indentSize, tabSize,
+ itr.hasNext()));
+ }
+ }
+ return sb.toString();
+ }
+
+ public String parseFieldMapOrdinally(GenerateMethod generateMethod, BitFieldGenerateMethod bitGenerateMethod,
+ int indentSize, int tabSize, Generator codeGenerator)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String cr = Utils.LINE_SEPARATOR;
+ StringBuffer sb = new StringBuffer();
+
+ // Generate warnings in code if required methods are null.
+ if (generateMethod == null || bitGenerateMethod == null)
+ {
+ sb.append(indent + "/***********************************************" + cr);
+ sb.append(indent + " * WARNING: In call to parseFieldMapOrdinally():" + cr);
+ if (generateMethod == null)
+ {
+ sb.append(indent + " * => generateMethod is null." + cr);
+ }
+ if (bitGenerateMethod == null)
+ {
+ sb.append(indent + " * => bitGenerateMethod is null." + cr);
+ }
+ sb.append(indent + " * Generated code could be missing." + cr);
+ sb.append(indent + " * Check for NoSuchMethodException on startup." + cr);
+ sb.append(indent + " ***********************************************/" + cr);
+ }
+
+ /* We must process elements in ordinal order because adjacent booleans (bits)
+ * must be combined into a single byte (in groups of up to 8). Start with shared
+ * declarations until an ordinal divergence is found. (For most methods where
+ * there is no difference between versions, this will simplify the generated
+ * code. */
+
+ ArrayList<String> bitFieldList = new ArrayList<String>();
+ boolean ordinalDivergenceFlag = false;
+ int ordinal = 0;
+ while (ordinal < size() && !ordinalDivergenceFlag)
+ {
+ /* Since the getFieldMapOrdinal() function may map more than one Field to
+ * an ordinal, the number of ordinals may be less than the total number of
+ * fields in the fieldMap. Check for empty fieldmaps... */
+ AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(ordinal);
+ if (ordinalFieldMap.size() > 0)
+ {
+ if (ordinalFieldMap.isDomainConsistent(codeGenerator, getVersionSet()))
+ {
+ String fieldName = ordinalFieldMap.getFirstFieldName();
+ String domain = ordinalFieldMap._map.get(fieldName).getDomainMap().firstKey();
+
+ String domainType = codeGenerator.getDomainType(domain,
+ codeGenerator.getVersionSet().first());
+
+ if (domainType.compareTo("bit") == 0)
+ {
+ bitFieldList.add(fieldName);
+ }
+ else if (bitFieldList.size() > 0)
+ {
+ // End of bit types - handle deferred bit type generation
+ if (bitGenerateMethod != null)
+ {
+ sb.append(bitGenerateMethod.generate(bitFieldList, ordinal,
+ indentSize, tabSize));
+ }
+ bitFieldList.clear();
+ }
+ if (!ordinalDivergenceFlag)
+ {
+ // Defer generation of bit types until all adjacent bits have been
+ // accounted for.
+ if (bitFieldList.size() == 0 && generateMethod != null)
+ {
+ sb.append(generateMethod.generate(domainType, fieldName, ordinal,
+ indentSize, tabSize));
+ }
+ }
+ ordinal++;
+ }
+ else
+ {
+ ordinalDivergenceFlag = true;
+ }
+ }
+ }
+
+ // Check if there is still more to do under a version-specific breakout
+ if (ordinalDivergenceFlag && ordinal < size())
+ {
+ // 1. Cycle through all versions in order, create outer if(version) structure
+ AmqpVersion[] versionArray = new AmqpVersion[getVersionSet().size()];
+ getVersionSet().toArray(versionArray);
+ for (int v = 0; v < versionArray.length; v++)
+ {
+ sb.append(indent);
+ if (v > 0)
+ {
+ sb.append("else ");
+ }
+ sb.append("if (major == " + versionArray[v].getMajor() + " && minor == " +
+ versionArray[v].getMinor() + ")" + cr);
+ sb.append(indent + "{" + cr);
+
+ // 2. Cycle though each ordinal from where we left off in the loop above.
+ ArrayList<String> bitFieldList2 = new ArrayList<String>(bitFieldList);
+ for (int o = ordinal; o < size(); o++)
+ {
+ AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(o);
+ if (ordinalFieldMap.size() > 0)
+ {
+ // 3. Cycle through each of the fields that have this ordinal.
+ Iterator<Map.Entry<String, AmqpField>> i = ordinalFieldMap._map.entrySet().iterator();
+ while (i.hasNext())
+ {
+
+ Map.Entry<String, AmqpField> entry = i.next();
+ AmqpField field = entry.getValue();
+ String fieldName = entry.getKey();
+
+ // 4. Some fields may have more than one ordinal - match by both
+ // ordinal and version.
+ Iterator<Integer> j = field.getOrdinalMap().keySet().iterator();
+ while (j.hasNext())
+ {
+ int thisOrdinal = j.next();
+ AmqpVersionSet v1 = field.getOrdinalMap().get(thisOrdinal);
+ if (thisOrdinal == o && v1.contains(versionArray[v]))
+ {
+ // 5. Now get the domain for this version
+ int domainCntr = 0;
+ Iterator<String> k = field.getDomainMap().keySet().iterator();
+ while (k.hasNext())
+ {
+ // Mangle domain-divergent field names
+ String mangledFieldName = fieldName;
+ if (field.getDomainMap().size() > 1)
+ {
+ mangledFieldName += "_" + (domainCntr++);
+ }
+ String domainName = k.next();
+ AmqpVersionSet v2 = field.getDomainMap().get(domainName);
+ if (v2.contains(versionArray[v]))
+ {
+ // 6. (Finally!!) write the declaration
+ String domainType = codeGenerator.getDomainType(domainName,
+ versionArray[v]);
+ if (domainType.compareTo("bit") == 0)
+ {
+ bitFieldList2.add(mangledFieldName);
+ }
+ else if (bitFieldList2.size() > 0)
+ {
+ // End of bit types - handle deferred bit type generation
+ if (bitGenerateMethod != null)
+ {
+ sb.append(bitGenerateMethod.generate(
+ bitFieldList2, o, indentSize + tabSize,
+ tabSize));
+ }
+ bitFieldList2.clear();
+ }
+ // Defer generation of bit types until all adjacent bits have
+ // been accounted for.
+ if (bitFieldList2.size() == 0 && generateMethod != null)
+ {
+ sb.append(generateMethod.generate(domainType,
+ mangledFieldName, o, indentSize + tabSize, tabSize));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ // Check for remaining deferred bits
+ if (bitFieldList2.size() > 0 && bitGenerateMethod != null)
+ {
+ sb.append(bitGenerateMethod.generate(bitFieldList2, size(),
+ indentSize + tabSize, tabSize));
+ }
+ sb.append(indent + "}" + cr);
+ }
+ }
+ // Check for remaining deferred bits
+ else if (bitFieldList.size() > 0 && bitGenerateMethod != null)
+ {
+ sb.append(bitGenerateMethod.generate(bitFieldList, size(),
+ indentSize, tabSize));
+ }
+ return sb.toString();
+ }
+
+ private String getFirstFieldName()
+ {
+ return _map.firstKey();
+ }
+
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ for (String thisFieldName : _map.keySet())
+ {
+ AmqpField field = _map.get(thisFieldName);
+ if (!field.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet)
+ {
+ for (String thisFieldName : _map.keySet())
+ {
+ AmqpField field = _map.get(thisFieldName);
+ if (!field.isVersionInterfaceConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public Collection<AmqpField> values()
+ {
+ return _map.values();
+ }
+
+ public AmqpField get(String fieldName)
+ {
+ return _map.get(fieldName);
+ }
+
+ public void remove(String fieldName)
+ {
+ _map.remove(fieldName);
+ }
+
+ public Set<String> keySet()
+ {
+ return _map.keySet();
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java
new file mode 100644
index 0000000000..5993a1b715
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpFlagMap extends TreeMap<Boolean, AmqpVersionSet> implements VersionConsistencyCheck
+{
+ public boolean isSet()
+ {
+ return containsKey(true);
+ }
+
+ public String toString()
+ {
+ AmqpVersionSet versionSet = get(true);
+ if (versionSet != null)
+ {
+ return versionSet.toString();
+ }
+ return "";
+ }
+
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (size() != 1)
+ {
+ return false;
+ }
+ return get(firstKey()).equals(globalVersionSet);
+ }
+
+ public boolean removeVersion(AmqpVersion version)
+ {
+ Boolean res = false;
+ ArrayList<Boolean> removeList = new ArrayList<Boolean>();
+ for (Boolean flag : keySet())
+ {
+ AmqpVersionSet versionSet = get(flag);
+ if (versionSet.contains(version))
+ {
+ versionSet.remove(version);
+ if (versionSet.isEmpty())
+ {
+ removeList.add(flag);
+ }
+ res = true;
+ }
+ }
+ // Get rid of flags no longer in use
+ for (Boolean flag : removeList)
+ {
+ remove(flag);
+ }
+ return res;
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpMethod.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpMethod.java
new file mode 100644
index 0000000000..4ec39b209e
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpMethod.java
@@ -0,0 +1,351 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class AmqpMethod implements Printable, NodeAware, VersionConsistencyCheck
+{
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+ private final AmqpFieldMap _fieldMap = new AmqpFieldMap();
+
+ private final AmqpOrdinalVersionMap _indexMap = new AmqpOrdinalVersionMap();
+ private final AmqpFlagMap _clientMethodFlagMap = new AmqpFlagMap(); // Method called on client (<chassis name="server"> in XML)
+ private final AmqpFlagMap _serverMethodFlagMap = new AmqpFlagMap(); // Method called on server (<chassis name="client"> in XML)
+
+ private final Map<AmqpVersion, AmqpFieldMap> _versionToFieldsMap = new HashMap<AmqpVersion, AmqpFieldMap>();
+
+ private final Map<AmqpVersion, AtomicInteger> _versionToFieldCount = new HashMap<AmqpVersion, AtomicInteger>();
+
+ private final String _name;
+ private final Generator _generator;
+
+
+ public AmqpMethod(String name, Generator generator)
+ {
+ _name = name;
+ _generator = generator;
+ }
+
+ public boolean addFromNode(Node methodNode, int ordinal, AmqpVersion version)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ _versionSet.add(version);
+ boolean serverChassisFlag = false;
+ boolean clientChassisFlag = false;
+ int index = Utils.getNamedIntegerAttribute(methodNode, "index");
+ AmqpVersionSet indexVersionSet = _indexMap.get(index);
+ if (indexVersionSet != null)
+ {
+ indexVersionSet.add(version);
+ }
+ else
+ {
+ indexVersionSet = new AmqpVersionSet();
+ indexVersionSet.add(version);
+ _indexMap.put(index, indexVersionSet);
+ }
+ NodeList nList = methodNode.getChildNodes();
+ AtomicInteger fieldCntr = _versionToFieldCount.get(version);
+ if(fieldCntr == null)
+ {
+ fieldCntr = new AtomicInteger(0);
+ _versionToFieldCount.put(version, fieldCntr);
+ }
+ for (int i = 0; i < nList.getLength(); i++)
+ {
+ Node child = nList.item(i);
+ if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0)
+ {
+ String fieldName = _generator.prepareDomainName(Utils.getNamedAttribute(child,
+ Utils.ATTRIBUTE_NAME));
+ AmqpField thisField = _fieldMap.get(fieldName);
+ AmqpFieldMap versionSpecificFieldMap = _versionToFieldsMap.get(version);
+ if (versionSpecificFieldMap == null)
+ {
+ versionSpecificFieldMap = new AmqpFieldMap();
+ _versionToFieldsMap.put(version, versionSpecificFieldMap);
+ }
+
+
+ if (thisField == null)
+ {
+ thisField = new AmqpField(fieldName, _generator);
+ _fieldMap.add(fieldName, thisField);
+ }
+
+ AmqpField versionSpecificField = new AmqpField(fieldName, _generator);
+ versionSpecificFieldMap.add(fieldName, versionSpecificField);
+
+ versionSpecificField.addFromNode(child, fieldCntr.intValue(), version);
+
+ if (!thisField.addFromNode(child, fieldCntr.getAndIncrement(), version))
+ {
+ String className = _generator.prepareClassName(Utils.getNamedAttribute(methodNode.getParentNode(),
+ Utils.ATTRIBUTE_NAME));
+ String methodName = _generator.prepareMethodName(Utils.getNamedAttribute(methodNode,
+ Utils.ATTRIBUTE_NAME));
+ System.out.println("INFO: Generation supression tag found for field " +
+ className + "." + methodName + "." + fieldName + " - removing.");
+ thisField.removeVersion(version);
+ _fieldMap.remove(fieldName);
+ }
+ }
+ else if (child.getNodeName().compareTo(Utils.ELEMENT_CHASSIS) == 0)
+ {
+ String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME);
+ if (chassisName.compareTo("server") == 0)
+ {
+ serverChassisFlag = true;
+ }
+ else if (chassisName.compareTo("client") == 0)
+ {
+ clientChassisFlag = true;
+ }
+ }
+ else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0)
+ {
+ String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE);
+ if (value.compareTo("no-gen") == 0)
+ {
+ return false;
+ }
+ }
+ }
+ processChassisFlags(serverChassisFlag, clientChassisFlag, version);
+ return true;
+ }
+
+ public void removeVersion(AmqpVersion version)
+ {
+ _clientMethodFlagMap.removeVersion(version);
+ _serverMethodFlagMap.removeVersion(version);
+ _indexMap.removeVersion(version);
+ _fieldMap.removeVersion(version);
+ _versionSet.remove(version);
+ }
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ String margin = Utils.createSpaces(marginSize);
+ String tab = Utils.createSpaces(tabSize);
+ out.println(margin + "[M] " + _name + " {" + (_serverMethodFlagMap.isSet() ? "S " +
+ _serverMethodFlagMap + (
+ _clientMethodFlagMap.isSet() ? ", " : "") : "") +
+ (_clientMethodFlagMap.isSet()
+ ? "C " + _clientMethodFlagMap : "") + "}" + ": " +
+ _versionSet);
+
+ for (Integer thisIndex : _indexMap.keySet())
+ {
+ AmqpVersionSet indexVersionSet = _indexMap.get(thisIndex);
+ out.println(margin + tab + "[I] " + thisIndex + indexVersionSet);
+ }
+
+ for (String thisFieldName : _fieldMap.keySet())
+ {
+ AmqpField thisField = _fieldMap.get(thisFieldName);
+ thisField.print(out, marginSize + tabSize, tabSize);
+ }
+ }
+
+ protected void processChassisFlags(boolean serverFlag, boolean clientFlag, AmqpVersion version)
+ {
+ AmqpVersionSet versionSet = _serverMethodFlagMap.get(serverFlag);
+ if (versionSet != null)
+ {
+ versionSet.add(version);
+ }
+ else
+ {
+ versionSet = new AmqpVersionSet();
+ versionSet.add(version);
+ _serverMethodFlagMap.put(serverFlag, versionSet);
+ }
+
+ versionSet = _clientMethodFlagMap.get(clientFlag);
+ if (versionSet != null)
+ {
+ versionSet.add(version);
+ }
+ else
+ {
+ versionSet = new AmqpVersionSet();
+ versionSet.add(version);
+ _clientMethodFlagMap.put(clientFlag, versionSet);
+ }
+ }
+
+ public AmqpOverloadedParameterMap getOverloadedParameterLists(AmqpVersionSet globalVersionSet,
+ Generator generator)
+ throws AmqpTypeMappingException
+ {
+ AmqpOverloadedParameterMap parameterVersionMap = new AmqpOverloadedParameterMap();
+ for (AmqpVersion thisVersion : globalVersionSet)
+ {
+ AmqpOrdinalFieldMap ordinalFieldMap = _fieldMap.getMapForVersion(thisVersion, true, generator);
+ AmqpVersionSet methodVersionSet = parameterVersionMap.get(ordinalFieldMap);
+ if (methodVersionSet == null)
+ {
+ methodVersionSet = new AmqpVersionSet();
+ methodVersionSet.add(thisVersion);
+ parameterVersionMap.put(ordinalFieldMap, methodVersionSet);
+ }
+ else
+ {
+ methodVersionSet.add(thisVersion);
+ }
+ }
+ return parameterVersionMap;
+ }
+
+ public boolean isVersionInterfaceConsistent()
+ {
+ return isVersionInterfaceConsistent(_generator.getVersionSet());
+ }
+
+ public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (!_versionSet.equals(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_clientMethodFlagMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_serverMethodFlagMap.isVersionConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ if (!_fieldMap.isVersionInterfaceConsistent(globalVersionSet))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isVersionConsistent()
+ {
+ return isVersionConsistent(_generator.getVersionSet());
+ }
+
+
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ return isVersionInterfaceConsistent(globalVersionSet)
+ && _indexMap.isVersionConsistent(globalVersionSet)
+ && _fieldMap.isVersionConsistent(globalVersionSet);
+ }
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public AmqpFieldMap getFieldMap()
+ {
+ return _fieldMap;
+ }
+
+ public AmqpOrdinalVersionMap getIndexMap()
+ {
+ return _indexMap;
+ }
+
+ public AmqpFlagMap getClientMethodFlagMap()
+ {
+ return _clientMethodFlagMap;
+ }
+
+ public AmqpFlagMap getServerMethodFlagMap()
+ {
+ return _serverMethodFlagMap;
+ }
+
+ public Map<AmqpVersion, AmqpFieldMap> getVersionToFieldsMap()
+ {
+ return _versionToFieldsMap;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public LanguageConverter getGenerator()
+ {
+ return _generator;
+ }
+
+ public SingleVersionMethod asSingleVersionMethod(AmqpVersion version)
+ {
+ return new SingleVersionMethod(this, version, _generator);
+ }
+
+ public Collection<AmqpField> getFields()
+ {
+ return _fieldMap.values();
+ }
+
+ public boolean isCommon(AmqpField field)
+ {
+ return field.getVersionSet().equals(getVersionSet()) && field.isTypeAndNameConsistent(_generator);
+ }
+
+ public boolean isConsistentServerMethod()
+ {
+ AmqpVersionSet serverVersions = _serverMethodFlagMap.get(true);
+ return (serverVersions != null) && serverVersions.containsAll(_generator.getVersionSet());
+ }
+
+
+ public boolean isConsistentClientMethod()
+ {
+ AmqpVersionSet clientVersions = _clientMethodFlagMap.get(true);
+ return (clientVersions != null) && clientVersions.containsAll(_generator.getVersionSet());
+ }
+
+ public boolean isServerMethod(AmqpVersion version)
+ {
+ AmqpVersionSet serverVersions = _serverMethodFlagMap.get(true);
+ return (serverVersions != null) && serverVersions.contains(version);
+ }
+
+
+ public boolean isClientMethod(AmqpVersion version)
+ {
+ AmqpVersionSet clientVersions = _clientMethodFlagMap.get(true);
+ return (clientVersions != null) && clientVersions.contains(version);
+ }
+
+ public boolean inAllVersions()
+ {
+ return _versionSet.containsAll(_generator.getVersionSet());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java
index a51f195761..d98dab4a39 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,15 +18,19 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth.manager;
+package org.apache.qpid.gentools;
-import org.apache.qpid.server.plugins.PluginFactory;
+import java.util.TreeMap;
-/**
- * Factory producing authentication producing configured, initialised authentication
- * managers.
- */
-public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S>
+@SuppressWarnings("serial")
+public class AmqpMethodMap extends TreeMap<String, AmqpMethod>
{
+ public void removeVersion(AmqpVersion version)
+ {
+ for (String methodName : keySet())
+ {
+ get(methodName).removeVersion(version);
+ }
+ }
}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpModel.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpModel.java
new file mode 100644
index 0000000000..45f0adb18d
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpModel.java
@@ -0,0 +1,132 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collection;
+
+public class AmqpModel implements Printable, NodeAware
+{
+ private final Generator _generator;
+ private final AmqpClassMap classMap = new AmqpClassMap();
+ private final AmqpVersionSet _versionSet = new AmqpVersionSet();
+
+ private final Map<AmqpVersion, AmqpClassMap> _versionToClassMapMap = new HashMap<AmqpVersion, AmqpClassMap>();
+
+ public AmqpModel(Generator generator)
+ {
+ _generator = generator;
+ }
+
+ public AmqpClassMap getAmqpClassMap(AmqpVersion version)
+ {
+ return _versionToClassMapMap.get(version);
+ }
+
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ public boolean addFromNode(Node n, int o, AmqpVersion version)
+ throws AmqpParseException, AmqpTypeMappingException
+ {
+ _versionSet.add(version);
+ NodeList nList = n.getChildNodes();
+
+ AmqpClassMap versionSpecificClassMap = _versionToClassMapMap.get(version);
+
+ if (versionSpecificClassMap == null)
+ {
+ versionSpecificClassMap = new AmqpClassMap();
+ _versionToClassMapMap.put(version, versionSpecificClassMap);
+ }
+
+ int eCntr = 0;
+ for (int i = 0; i < nList.getLength(); i++)
+ {
+ Node c = nList.item(i);
+ if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0)
+ {
+ String className = _generator.prepareClassName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME));
+ AmqpClass thisClass = classMap.get(className);
+ if (thisClass == null)
+ {
+ thisClass = new AmqpClass(className, _generator);
+ classMap.put(className, thisClass);
+ }
+
+ AmqpClass versionSpecificClass = new AmqpClass(className, _generator);
+ versionSpecificClassMap.put(className, versionSpecificClass);
+
+ versionSpecificClass.addFromNode(c, eCntr, version);
+
+ if (!thisClass.addFromNode(c, eCntr++, version))
+ {
+ System.out.println("INFO: Generation supression tag found for class " + className + " - removing.");
+ thisClass.removeVersion(version);
+ classMap.remove(className);
+ }
+ }
+ }
+ return true;
+ }
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ out.println(Utils.createSpaces(marginSize) +
+ "[C]=class; [M]=method; [F]=field; [D]=domain; [I]=index; [O]=ordinal" + Utils.LINE_SEPARATOR);
+ out.println(Utils.createSpaces(marginSize) + "Model:");
+
+ for (String thisClassName : classMap.keySet())
+ {
+ AmqpClass thisClass = classMap.get(thisClassName);
+ thisClass.print(out, marginSize + tabSize, tabSize);
+ }
+ }
+
+ public LanguageConverter getGenerator()
+ {
+ return _generator;
+ }
+
+ public AmqpClassMap getClassMap()
+ {
+ return classMap;
+ }
+
+
+ public Collection<AmqpClass> getClasses()
+ {
+ return classMap.values();
+ }
+
+ public SingleVersionModel asSingleVersionModel()
+ {
+ return new SingleVersionModel(this, getVersionSet().first(), _generator);
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
new file mode 100644
index 0000000000..0633eff1e1
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> implements Comparable
+{
+
+
+ public int compareTo(Object obj)
+ {
+ AmqpOrdinalFieldMap o = (AmqpOrdinalFieldMap) obj;
+ Set<Integer> thisKeySet = keySet();
+ Set<Integer> oKeySet = o.keySet();
+ if (!thisKeySet.equals(oKeySet)) // Not equal, but why?
+ {
+ // Size difference
+ int sizeDiff = thisKeySet.size() - oKeySet.size(); // -ve if this < other
+ if (sizeDiff != 0)
+ {
+ return sizeDiff;
+ }
+ // Conetent difference
+ Iterator<Integer> itr = thisKeySet.iterator();
+ Iterator<Integer> oItr = oKeySet.iterator();
+ while (itr.hasNext() && oItr.hasNext())
+ {
+ int diff = itr.next() - oItr.next(); // -ve if this < other
+ if (diff != 0)
+ {
+ return diff;
+ }
+ }
+ // We should never get here...
+ System.err.println("AmqpOrdinalFieldMap.compareTo(): " +
+ "WARNING - unable to find cause of keySet difference.");
+ }
+ // Keys are equal, now check the String[]s
+ Iterator<Integer> itr = thisKeySet.iterator();
+ Iterator<Integer> oItr = oKeySet.iterator();
+ while (itr.hasNext() && oItr.hasNext())
+ {
+ String[] thisPair = get(itr.next());
+ String[] oPair = o.get(oItr.next());
+ // Size difference
+ int sizeDiff = thisPair.length - oPair.length; // -ve if this < other
+ if (sizeDiff != 0)
+ {
+ return sizeDiff;
+ }
+ // Conetent difference
+ for (int i = 0; i < thisPair.length; i++)
+ {
+ int diff = thisPair[i].compareTo(oPair[i]);
+ if (diff != 0)
+ {
+ return diff;
+ }
+ }
+ }
+ return 0;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ for (Integer thisOrdinal : keySet())
+ {
+ String[] pair = get(thisOrdinal);
+ sb.append("[" + thisOrdinal + "] " + pair[0] + " : " + pair[1] + Utils.LINE_SEPARATOR);
+ }
+ return sb.toString();
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java
new file mode 100644
index 0000000000..fede88631a
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpOrdinalVersionMap extends TreeMap<Integer, AmqpVersionSet> implements VersionConsistencyCheck
+{
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
+ {
+ if (size() != 1)
+ {
+ return false;
+ }
+ return get(firstKey()).equals(globalVersionSet);
+ }
+
+ public int getOrdinal(AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ for (Integer thisOrdinal : keySet())
+ {
+ AmqpVersionSet versionSet = get(thisOrdinal);
+ if (versionSet.contains(version))
+ {
+ return thisOrdinal;
+ }
+ }
+ throw new AmqpTypeMappingException("Unable to locate version " + version + " in ordianl version map.");
+ }
+
+ public boolean removeVersion(AmqpVersion version)
+ {
+ Boolean res = false;
+ ArrayList<Integer> removeList = new ArrayList<Integer>();
+ for (Integer ordinal : keySet())
+ {
+ AmqpVersionSet versionSet = get(ordinal);
+ if (versionSet.contains(version))
+ {
+ versionSet.remove(version);
+ if (versionSet.isEmpty())
+ {
+ removeList.add(ordinal);
+ }
+ res = true;
+ }
+ }
+ // Get rid of ordinals no longer in use
+ for (Integer ordinal : removeList)
+ {
+ remove(ordinal);
+ }
+ return res;
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
new file mode 100644
index 0000000000..10978d0e4a
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.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.gentools;
+
+import java.util.TreeMap;
+
+@SuppressWarnings("serial")
+public class AmqpOverloadedParameterMap extends TreeMap<AmqpOrdinalFieldMap, AmqpVersionSet>
+{
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpParseException.java
index 6297478883..3f3d4611fc 100644
--- a/java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpParseException.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,14 +18,13 @@
* under the License.
*
*/
-package org.apache.qpid.systest;
+package org.apache.qpid.gentools;
-public class GlobalTopicsTest extends GlobalQueuesTest
+@SuppressWarnings("serial")
+public class AmqpParseException extends RuntimeException
{
- @Override
- public void setUp() throws Exception
+ public AmqpParseException(String msg)
{
- CONFIG_SECTION = ".topics";
- super.setUp();
+ super(msg);
}
}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java
new file mode 100644
index 0000000000..1ac09ea453
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.gentools;
+
+@SuppressWarnings("serial")
+public class AmqpTemplateException extends RuntimeException
+{
+ public AmqpTemplateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java
new file mode 100644
index 0000000000..127a8835b0
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.gentools;
+
+@SuppressWarnings("serial")
+public class AmqpTypeMappingException extends RuntimeException
+{
+ public AmqpTypeMappingException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpVersion.java
index 63b43475aa..dbeef1b895 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpVersion.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,50 +18,55 @@
* under the License.
*
*/
+package org.apache.qpid.gentools;
-package org.apache.qpid.qmf;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class QMFPackage
+public class AmqpVersion implements Comparable<AmqpVersion>
{
- private final String _name;
- private final Map<String, QMFClass> _classes = new HashMap<String, QMFClass>();
+ private final int _major;
+ private final int _minor;
- public QMFPackage(String name)
+ public AmqpVersion(int major, int minor)
{
- _name = name;
+ _major = major;
+ _minor = minor;
}
- public QMFPackage(String name, Collection<QMFClass> classes)
+ public AmqpVersion(AmqpVersion version)
{
- this(name);
- setClasses(classes);
+ _major = version.getMajor();
+ _minor = version.getMinor();
}
- protected void setClasses(Collection<QMFClass> classes)
+ public int getMajor()
{
- for(QMFClass qmfClass : classes)
- {
- qmfClass.setPackage(this);
- _classes.put(qmfClass.getName(), qmfClass);
- }
+ return _major;
}
- public String getName()
+ public int getMinor()
{
- return _name;
+ return _minor;
+ }
+
+ public int compareTo(AmqpVersion v)
+ {
+ if (_major != v.getMajor())
+ {
+ return _major - v.getMajor();
+ }
+ if (_minor != v.getMinor())
+ {
+ return _minor - v.getMinor();
+ }
+ return 0;
}
- public Collection<QMFClass> getClasses()
+ public String namespace()
{
- return _classes.values();
+ return "ver_" + _major + "_" + _minor;
}
- public QMFClass getQMFClass(String className)
+ public String toString()
{
- return _classes.get(className);
+ return _major + "-" + _minor;
}
}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java b/java/common/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java
new file mode 100644
index 0000000000..6419e23a1e
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.PrintStream;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+@SuppressWarnings("serial")
+public class AmqpVersionSet extends TreeSet<AmqpVersion> implements Printable, Comparable<AmqpVersionSet>
+{
+ public AmqpVersionSet()
+ {
+ super();
+ }
+
+ public AmqpVersionSet(AmqpVersion version)
+ {
+ super();
+ add(version);
+ }
+
+ public AmqpVersion find(AmqpVersion version)
+ {
+ for (AmqpVersion v : this)
+ {
+ if (v.compareTo(version) == 0)
+ {
+ return v;
+ }
+ }
+ return null;
+ }
+
+ public void print(PrintStream out, int marginSize, int tabSize)
+ {
+ out.print(Utils.createSpaces(marginSize) + "Version Set: " + toString() + Utils.LINE_SEPARATOR);
+ }
+
+ public int compareTo(AmqpVersionSet other)
+ {
+ int res = size() - other.size();
+ if (res != 0)
+ {
+ return res;
+ }
+ Iterator<AmqpVersion> vItr = iterator();
+ Iterator<AmqpVersion> oItr = other.iterator();
+ while (vItr.hasNext() && oItr.hasNext())
+ {
+ AmqpVersion version = vItr.next();
+ AmqpVersion oVersion = oItr.next();
+ res = version.compareTo(oVersion);
+ if (res != 0)
+ {
+ return res;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java b/java/common/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java
index b2fe6766a6..d85510ee98 100644
--- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java
@@ -18,10 +18,12 @@
* under the License.
*
*/
-package org.apache.qpid.slowconsumerdetection.policies;
+package org.apache.qpid.gentools;
-import org.apache.qpid.server.plugins.PluginFactory;
-public interface SlowConsumerPolicyPluginFactory<P extends SlowConsumerPolicyPlugin> extends PluginFactory<P>
+import java.util.List;
+
+public interface BitFieldGenerateMethod
{
+ String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize);
}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java b/java/common/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java
new file mode 100644
index 0000000000..641f50c3f8
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.gentools;
+
+public interface CommandGenerateMethod
+{
+ String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast);
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java b/java/common/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java
new file mode 100644
index 0000000000..9ab7eb178b
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/ConsolidatedField.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.gentools;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: U146758
+ * Date: 06-Mar-2007
+ * Time: 09:22:21
+ * To change this template use File | Settings | File Templates.
+ */
+public class ConsolidatedField
+{
+ private final String _name;
+ private final String _type;
+ private final List<String> _underlyingFields = new ArrayList<String>();
+ private final Generator _generator;
+ private boolean _isConsolidated;
+
+ public ConsolidatedField(Generator generator, String name, String type)
+ {
+ this(generator,name,type,name,false);
+ }
+
+ public ConsolidatedField(Generator generator, String name, String type, String firstField)
+ {
+ this(generator,name,type,firstField,true);
+ }
+
+ public ConsolidatedField(Generator generator, String name, String type, String firstField, boolean consolidated)
+ {
+
+ _generator = generator;
+ _name = name;
+ _type = type;
+ _isConsolidated = consolidated;
+ _underlyingFields.add(firstField);
+
+ }
+
+
+ public void setConsolidated(boolean consolidated)
+ {
+ _isConsolidated = consolidated;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+
+ public String getNativeType()
+ {
+ return _generator.getNativeType(_type);
+ }
+
+ public String getEncodingType()
+ {
+ return _generator.getEncodingType(_type);
+ }
+
+ public void add(String name)
+ {
+ _underlyingFields.add(name);
+ }
+
+ public Collection<String> getUnderlyingFields()
+ {
+ return Collections.unmodifiableCollection(_underlyingFields);
+ }
+
+ public int getPosition(String fieldName)
+ {
+ return _underlyingFields.indexOf(fieldName);
+ }
+
+ public boolean isConsolidated()
+ {
+ return _isConsolidated;
+ }
+
+ public boolean isFixedSize()
+ {
+ return _generator.isFixedSizeType( getType() );
+ }
+
+ public int getSize()
+ {
+ return _generator.getTypeSize( getType() );
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/java/common/gentools/src/org/apache/qpid/gentools/CppGenerator.java
new file mode 100644
index 0000000000..4f58cba34e
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/CppGenerator.java
@@ -0,0 +1,1716 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.TreeMap;
+
+public class CppGenerator extends Generator
+{
+ protected static final String versionNamespaceStartToken = "${version_namespace_start}";
+ protected static final String versionNamespaceEndToken = "${version_namespace_end}";
+
+ // TODO: Move this to parent class
+ protected static final int FIELD_NAME = 0;
+ protected static final int FIELD_CODE_TYPE = 1;
+
+ /**
+ * A complete list of C++ reserved words. The names of varous XML elements within the AMQP
+ * specification file are used for C++ identifier names in the generated code. Each proposed
+ * name is checked against this list and is modified (by adding an '_' to the end of the
+ * name - see function parseForReservedWords()) if found to be present.
+ */
+ protected static final String[] cppReservedWords = {"and", "and_eq", "asm", "auto", "bitand",
+ "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast",
+ "continue", "default", "delete", "do", "DomainInfo", "double", "dynamic_cast", "else",
+ "enum", "explicit", "extern", "false", "float", "for", "friend", "goto", "if", "inline",
+ "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq",
+ "private", "protected", "public", "register", "reinterpret_cast", "return", "short",
+ "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this",
+ "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using",
+ "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"};
+
+ /**
+ * Although not reserved words, the following list of variable names that may cause compile
+ * problems within a C++ environment because they clash with common #includes. The names of
+ * varous XML elements within the AMQP specification file are used for C++ identifier names
+ * in the generated code. Each proposed name is checked against this list and is modified
+ * (by adding an '_' to the end of the name - see function parseForReservedWords()) if found
+ * to be present. This list is best added to on an as-needed basis.
+ */
+ protected static final String[] cppCommonDefines = {"string"};
+
+ // TODO: Move this to the Generator superclass?
+ protected boolean quietFlag; // Supress warning messages to the console
+
+ private class DomainInfo
+ {
+ public String type;
+ public String size;
+ public String encodeExpression;
+ public String decodeExpression;
+
+ public DomainInfo(String domain, String size, String encodeExpression,
+ String decodeExpression)
+ {
+ this.type = domain;
+ this.size = size;
+ this.encodeExpression = encodeExpression;
+ this.decodeExpression = decodeExpression;
+ }
+ }
+
+ private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>();
+
+ public CppGenerator()
+ {
+ super();
+ quietFlag = true;
+ // Load C++ type and size maps.
+ // Adjust or add to these lists as new types are added/defined.
+ // The char '#' will be replaced by the field variable name (any type).
+ // The char '~' will be replaced by the compacted bit array size (type bit only).
+ typeMap.put("bit", new DomainInfo(
+ "bool", // type
+ "~", // size
+ "", // encodeExpression
+ "")); // decodeExpression
+ typeMap.put("content", new DomainInfo(
+ "Content", // type
+ "#.size()", // size
+ "buffer.putContent(#)", // encodeExpression
+ "buffer.getContent(#)")); // decodeExpression
+ typeMap.put("long", new DomainInfo(
+ "u_int32_t", // type
+ "4", // size
+ "buffer.putLong(#)", // encodeExpression
+ "# = buffer.getLong()")); // decodeExpression
+ typeMap.put("longlong", new DomainInfo(
+ "u_int64_t", // type
+ "8", // size
+ "buffer.putLongLong(#)", // encodeExpression
+ "# = buffer.getLongLong()")); // decodeExpression
+ typeMap.put("longstr", new DomainInfo(
+ "string", // type
+ "4 + #.length()", // size
+ "buffer.putLongString(#)", // encodeExpression
+ "buffer.getLongString(#)")); // decodeExpression
+ typeMap.put("octet", new DomainInfo(
+ "u_int8_t", // type
+ "1", // size
+ "buffer.putOctet(#)", // encodeExpression
+ "# = buffer.getOctet()")); // decodeExpression
+ typeMap.put("short", new DomainInfo(
+ "u_int16_t", // type
+ "2", // size
+ "buffer.putShort(#)", // encodeExpression
+ "# = buffer.getShort()")); // decodeExpression
+ typeMap.put("shortstr", new DomainInfo(
+ "string", // type
+ "1 + #.length()", // size
+ "buffer.putShortString(#)", // encodeExpression
+ "buffer.getShortString(#)")); // decodeExpression
+ typeMap.put("table", new DomainInfo(
+ "FieldTable", // type
+ "#.size()", // size
+ "buffer.putFieldTable(#)", // encodeExpression
+ "buffer.getFieldTable(#)")); // decodeExpression
+ typeMap.put("timestamp", new DomainInfo(
+ "u_int64_t", // type
+ "8", // size
+ "buffer.putLongLong(#)", // encodeExpression
+ "buffer.getLongLong(#)")); // decodeExpression
+ }
+
+
+ public boolean isQuietFlag()
+ {
+ return quietFlag;
+ }
+
+ public void setQuietFlag(boolean quietFlag)
+ {
+ this.quietFlag = quietFlag;
+ }
+
+ // === Start of methods for Interface LanguageConverter ===
+
+ public String prepareClassName(String className)
+ {
+ return camelCaseName(className, true);
+ }
+
+ public String prepareMethodName(String methodName)
+ {
+ return camelCaseName(methodName, false);
+ }
+
+ public String prepareDomainName(String domainName)
+ {
+ return camelCaseName(domainName, false);
+ }
+
+
+ public String getGeneratedType(String domainName, AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ String domainType = getDomainType(domainName, version);
+ if (domainType == null)
+ {
+ throw new AmqpTypeMappingException("Domain type \"" + domainName +
+ "\" not found in C++ typemap.");
+ }
+ DomainInfo info = typeMap.get(domainType);
+ if (info == null)
+ {
+ throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\"");
+ }
+ return info.type;
+ }
+
+ // === Abstract methods from class Generator - C++-specific implementation ===
+
+ @Override
+ protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, AmqpVersion version)
+ {
+ StringBuffer sb = new StringBuffer(filenameTemplate);
+ if (thisClass != null)
+ {
+ replaceToken(sb, "${CLASS}", thisClass.getName());
+ }
+ if (method != null)
+ {
+ replaceToken(sb, "${METHOD}", method.getName());
+ }
+ if (field != null)
+ {
+ replaceToken(sb, "${FIELD}", field.getName());
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected void processModelTemplate(NamedTemplate template)
+ {
+ processTemplate(template, null, null, null, null);
+ }
+
+ @Override
+ protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass)
+ {
+ processTemplate(template, thisClass, null, null, null);
+ }
+
+ @Override
+ protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method)
+ {
+ StringBuffer sb = new StringBuffer(template.getTemplate());
+ String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null, null);
+ boolean templateProcessedFlag = false;
+
+ // If method is not version consistent, create a namespace for each version
+ // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken
+ // once for each namespace.
+ if (method != null)
+ {
+ if (!method.isVersionConsistent(getVersionSet()))
+ {
+ int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken);
+ int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) +
+ versionNamespaceEndToken.length();
+ if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 &&
+ namespaceStartIndex <= namespaceEndIndex)
+ {
+ String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + CR;
+ sb.delete(namespaceStartIndex, namespaceEndIndex);
+ for (AmqpVersion v : method.getVersionSet())
+ {
+ StringBuffer nssb = new StringBuffer(namespaceSpan);
+ processTemplate(nssb, thisClass, method, null, template.getName(), v);
+ sb.insert(namespaceStartIndex, nssb);
+ }
+ // Process all tokens *not* within the namespace span prior to inserting namespaces
+ processTemplate(sb, thisClass, method, null, template.getName(), null);
+ }
+ templateProcessedFlag = true;
+ }
+ }
+ // Remove any remaining namespace tags
+ int nsTokenIndex = sb.indexOf(versionNamespaceStartToken);
+ while (nsTokenIndex > 0)
+ {
+ sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length());
+ nsTokenIndex = sb.indexOf(versionNamespaceStartToken);
+ }
+ nsTokenIndex = sb.indexOf(versionNamespaceEndToken);
+ while (nsTokenIndex > 0)
+ {
+ sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length());
+ nsTokenIndex = sb.indexOf(versionNamespaceEndToken);
+ }
+
+ if (!templateProcessedFlag)
+ {
+ processTemplate(sb, thisClass, method, null, template.getName(), null);
+ }
+ writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename));
+ generatedFileCounter++;
+ }
+
+ @Override
+ protected void processTemplate(NamedTemplate template, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, AmqpVersion version)
+ {
+ StringBuffer sb = new StringBuffer(template.getTemplate());
+ String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version);
+ processTemplate(sb, thisClass, method, field, template.getName(), null);
+ writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename));
+ generatedFileCounter++;
+ }
+
+ protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, String templateFileName, AmqpVersion version)
+ {
+ try
+ {
+ processAllLists(sb, thisClass, method, version);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("ERROR: " + templateFileName + ": " + e.getMessage());
+ }
+ try
+ {
+ processAllTokens(sb, thisClass, method, field, version);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("ERROR: " + templateFileName + ": " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field,
+ AmqpVersion version)
+ {
+ if (token.compareTo("${GENERATOR}") == 0)
+ {
+ return GENERATOR_INFO;
+ }
+ if (token.compareTo("${CLASS}") == 0 && thisClass != null)
+ {
+ return thisClass.getName();
+ }
+ if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null)
+ {
+ if (version == null)
+ {
+ return String.valueOf(thisClass.getIndexMap().firstKey());
+ }
+ return getIndex(thisClass.getIndexMap(), version);
+ }
+ if (token.compareTo("${METHOD}") == 0 && method != null)
+ {
+ return method.getName();
+ }
+ if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null)
+ {
+ if (version == null)
+ {
+ return String.valueOf(method.getIndexMap().firstKey());
+ }
+ return getIndex(method.getIndexMap(), version);
+ }
+ if (token.compareTo("${FIELD}") == 0 && field != null)
+ {
+ return field.getName();
+ }
+ if (token.compareTo(versionNamespaceStartToken) == 0 && version != null)
+ {
+ return "namespace " + version.namespace() + CR + "{";
+ }
+ if (token.compareTo(versionNamespaceEndToken) == 0 && version != null)
+ {
+ return "} // namespace " + version.namespace();
+ }
+ if (token.compareTo("${mb_constructor_with_initializers}") == 0)
+ {
+ return generateConstructor(thisClass, method, version, 4, 4);
+ }
+ if (token.compareTo("${mb_server_operation_invoke}") == 0)
+ {
+ return generateServerOperationsInvoke(thisClass, method, version, 4, 4);
+ }
+ if (token.compareTo("${mb_buffer_param}") == 0)
+ {
+ return method.getFieldMap().size() > 0 ? " buffer" : "";
+ }
+ if (token.compareTo("${hv_latest_major}") == 0)
+ {
+ return String.valueOf(getVersionSet().last().getMajor());
+ }
+ if (token.compareTo("${hv_latest_minor}") == 0)
+ {
+ return String.valueOf(getVersionSet().last().getMinor());
+ }
+
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+
+ @Override
+ protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpModel model, AmqpVersion version)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokxStart = tline.indexOf('$');
+ String token = tline.substring(tokxStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // ClientOperations.h
+ if (token.compareTo("${coh_method_handler_get_method}") == 0)
+ {
+ codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4);
+ }
+ else if (token.compareTo("${coh_inner_class}") == 0)
+ {
+ codeSnippet = generateOpsInnerClasses(model, false, 4, 4);
+ }
+
+ // ServerOperations.h
+ else if (token.compareTo("${soh_method_handler_get_method}") == 0)
+ {
+ codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4);
+ }
+ else if (token.compareTo("${soh_inner_class}") == 0)
+ {
+ codeSnippet = generateOpsInnerClasses(model, true, 4, 4);
+ }
+
+ // ClientProxy.h/cpp
+ else if (token.compareTo("${cph_inner_class_instance}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassInstances(model, false, 4);
+ }
+ else if (token.compareTo("${cph_inner_class_get_method}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4);
+ }
+ else if (token.compareTo("${cph_inner_class_defn}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassDefinitions(model, false, 4, 4);
+ }
+ else if (token.compareTo("${cpc_constructor_initializer}") == 0)
+ {
+ codeSnippet = generateProxyConstructorInitializers(model, false, 4);
+ }
+ else if (token.compareTo("${cpc_inner_class_get_method}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassGetMethodImpls(model, false, 0, 4);
+ }
+ else if (token.compareTo("${cpc_inner_class_impl}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassImpl(model, false, 0, 4);
+ }
+ else if (token.compareTo("${cph_handler_pointer_defn}") == 0)
+ {
+ codeSnippet = generateHandlerPointerDefinitions(model, false, 4);
+ }
+ else if (token.compareTo("${cph_handler_pointer_get_method}") == 0)
+ {
+ codeSnippet = generateHandlerPointerGetMethods(model, false, 4);
+ }
+
+ // SerrverProxy.h/cpp
+ else if (token.compareTo("${sph_inner_class_instance}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassInstances(model, true, 4);
+ }
+ else if (token.compareTo("${sph_inner_class_get_method}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassGetMethodDecls(model, true, 4);
+ }
+ else if (token.compareTo("${sph_inner_class_defn}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassDefinitions(model, true, 4, 4);
+ }
+ else if (token.compareTo("${spc_constructor_initializer}") == 0)
+ {
+ codeSnippet = generateProxyConstructorInitializers(model, true, 4);
+ }
+ else if (token.compareTo("${spc_inner_class_get_method}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassGetMethodImpls(model, true, 0, 4);
+ }
+ else if (token.compareTo("${spc_inner_class_impl}") == 0)
+ {
+ codeSnippet = generateProxyInnerClassImpl(model, true, 0, 4);
+ }
+ else if (token.compareTo("${sph_handler_pointer_defn}") == 0)
+ {
+ codeSnippet = generateHandlerPointerDefinitions(model, true, 4);
+ }
+ else if (token.compareTo("${sph_handler_pointer_get_method}") == 0)
+ {
+ codeSnippet = generateHandlerPointerGetMethods(model, true, 4);
+ }
+
+ // amqp_methods.h/cpp
+ else if (token.compareTo("${mh_method_body_class_indlude}") == 0)
+ {
+ codeSnippet = generateMethodBodyIncludeList(model, 0);
+ }
+ else if (token.compareTo("${mh_method_body_class_instance}") == 0)
+ {
+ codeSnippet = generateMethodBodyInstances(model, 0);
+ }
+ else if (token.compareTo("${mc_create_method_body_map_entry}") == 0)
+ {
+ codeSnippet = generateMethodBodyMapEntry(model, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token \"" + token + "\" unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpClass thisClass)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokxStart = tline.indexOf('$');
+ String token = tline.substring(tokxStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ if (token.compareTo("${cpc_method_body_include}") == 0)
+ {
+ codeSnippet = generateMethodBodyIncludes(thisClass, 0);
+ }
+ else if (token.compareTo("${spc_method_body_include}") == 0)
+ {
+ codeSnippet = generateMethodBodyIncludes(thisClass, 0);
+ }
+ else if (token.compareTo("${mc_method_body_include}") == 0)
+ {
+ codeSnippet = generateMethodBodyIncludes(thisClass, 0);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpFieldMap fieldMap, AmqpVersion version)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokxStart = tline.indexOf('$');
+ String token = tline.substring(tokxStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ if (token.compareTo("${mb_field_declaration}") == 0)
+ {
+ codeSnippet = generateFieldDeclarations(fieldMap, version, 4);
+ }
+ else if (token.compareTo("${mb_field_get_method}") == 0)
+ {
+ codeSnippet = generateFieldGetMethods(fieldMap, version, 4);
+ }
+ else if (token.compareTo("${mb_field_print}") == 0)
+ {
+ codeSnippet = generatePrintMethodContents(fieldMap, version, 8);
+ }
+ else if (token.compareTo("${mb_body_size}") == 0)
+ {
+ codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8);
+ }
+ else if (token.compareTo("${mb_encode}") == 0)
+ {
+ codeSnippet = generateEncodeMethodContents(fieldMap, version, 8);
+ }
+ else if (token.compareTo("${mb_decode}") == 0)
+ {
+ codeSnippet = generateDecodeMethodContents(fieldMap, version, 8);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpConstantSet constantSet)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokxStart = tline.indexOf('$');
+ String token = tline.substring(tokxStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ if (token.compareTo("${ch_get_value_method}") == 0)
+ {
+ codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ // === Protected and private helper functions unique to C++ implementation ===
+
+ // Methods for generation of code snippets for AMQP_Constants.h file
+
+ protected String generateConstantGetMethods(AmqpConstantSet constantSet,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ for (AmqpConstant thisConstant : constantSet.getContstants())
+ {
+ if (thisConstant.isVersionConsistent(getVersionSet()))
+ {
+ // return a constant
+ String value = thisConstant.firstKey();
+ sb.append(indent + "static const char* " + thisConstant.getName() + "() { return \"" +
+ thisConstant.firstKey() + "\"; }" + CR);
+ if (Utils.containsOnlyDigits(value))
+ {
+ sb.append(indent + "static int " + thisConstant.getName() + "AsInt() { return " +
+ thisConstant.firstKey() + "; }" + CR);
+ }
+ if (Utils.containsOnlyDigitsAndDecimal(value))
+ {
+ sb.append(indent + "static double " + thisConstant.getName() + "AsDouble() { return (double)" +
+ thisConstant.firstKey() + "; }" + CR);
+ }
+ sb.append(CR);
+ }
+ else
+ {
+ // Return version-specific constant
+ sb.append(generateVersionDependentGet(thisConstant, "const char*", "", "\"", "\"", indentSize, tabSize));
+ sb.append(generateVersionDependentGet(thisConstant, "int", "AsInt", "", "", indentSize, tabSize));
+ sb.append(generateVersionDependentGet(thisConstant, "double", "AsDouble", "(double)", "", indentSize, tabSize));
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateVersionDependentGet(AmqpConstant constant, String methodReturnType,
+ String methodNameSuffix, String returnPrefix, String returnPostfix, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + methodReturnType + " " + constant.getName() + methodNameSuffix +
+ "() const" + CR);
+ sb.append(indent + "{" + CR);
+ boolean first = true;
+ for (String thisValue : constant.keySet())
+ {
+ AmqpVersionSet versionSet = constant.get(thisValue);
+ sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) +
+ ")" + CR);
+ sb.append(indent + tab + "{" + CR);
+ if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(thisValue))
+ {
+ sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
+ indentSize + (2 * tabSize), tabSize));
+ }
+ else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(thisValue))
+ {
+ sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
+ indentSize + (2 * tabSize), tabSize));
+ }
+ else
+ {
+ sb.append(indent + tab + tab + "return " + returnPrefix + thisValue + returnPostfix + ";" + CR);
+ }
+ sb.append(indent + tab + "}" + CR);
+ first = false;
+ }
+ sb.append(indent + tab + "else" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "std::stringstream ss;" + CR);
+ sb.append(indent + tab + tab + "ss << \"Constant \\\"" + constant.getName() +
+ "\\\" is undefined for AMQP version \" <<" + CR);
+ sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + CR);
+ sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + CR);
+ sb.append(indent + tab + "}" + CR);
+ sb.append(indent + "}" + CR);
+ return sb.toString();
+ }
+
+ protected String generateConstantDeclarationException(String name, String methodReturnType,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "std::stringstream ss;" + CR);
+ sb.append(indent + "ss << \"Constant \\\"" + name + "\\\" cannot be converted to type " +
+ methodReturnType + " for AMQP version \" <<" + CR);
+ sb.append(indent + tab + "version.toString() << \".\";" + CR);
+ sb.append(indent + "throw ProtocolVersionException(ss.str());" + CR);
+ return sb.toString();
+ }
+
+ // Methods used for generation of code snippets for Server/ClientOperations class generation
+
+ protected String generateOpsMethodHandlerGetMethods(AmqpModel model, boolean serverFlag, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ // Only generate for this class if there is at least one method of the
+ // required chassis (server/client flag).
+ boolean chassisFoundFlag = false;
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ boolean clientChassisFlag = method.getClientMethodFlagMap().isSet();
+ boolean serverChassisFlag = method.getServerMethodFlagMap().isSet();
+ if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag))
+ {
+ chassisFoundFlag = true;
+ }
+ }
+ if (chassisFoundFlag)
+ {
+ sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" +
+ thisClass.getName() + "Handler* get" + thisClass.getName() + "Handler() = 0;" + CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize)
+ {
+
+ String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ boolean first = true;
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ String handlerClassName = thisClass.getName() + "Handler";
+ if (!first)
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "// ==================== class " + handlerClassName +
+ " ====================" + CR);
+ sb.append(indent + "class " + handlerClassName);
+ if (thisClass.getVersionSet().size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR);
+ }
+ else
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "{" + CR);
+ sb.append(indent + "private:" + CR);
+ sb.append(indent + tab + proxyClassName + "* parent;" + CR);
+ sb.append(CR);
+ sb.append(indent + tab + "// Constructors and destructors" + CR);
+ sb.append(CR);
+ sb.append(indent + "protected:" + CR);
+ sb.append(indent + tab + handlerClassName + "() {}" + CR);
+ sb.append(indent + "public:" + CR);
+ sb.append(indent + tab + handlerClassName +
+ "(" + proxyClassName + "* _parent) {parent = _parent;}" + CR);
+ sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + CR);
+ sb.append(CR);
+ sb.append(indent + tab + "// Protocol methods" + CR);
+ sb.append(CR);
+ sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize));
+ sb.append(indent + "}; // class " + handlerClassName + CR);
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag,
+ boolean abstractMethodFlag, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations"
+ : "Proxy");
+ boolean first = true;
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ boolean clientChassisFlag = method.getClientMethodFlagMap().isSet();
+ boolean serverChassisFlag = method.getServerMethodFlagMap().isSet();
+ if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag))
+ {
+ String methodName = parseForReservedWords(method.getName(), outerClassName + "." + thisClass.getName());
+ AmqpOverloadedParameterMap overloadededParameterMap =
+ method.getOverloadedParameterLists(thisClass.getVersionSet(), this);
+ for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet())
+ {
+ AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap);
+ if (!first)
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "virtual void " + methodName + "( u_int16_t channel");
+ sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true));
+ sb.append(" )");
+ if (abstractMethodFlag)
+ {
+ sb.append(" = 0");
+ }
+ sb.append(";");
+ if (versionSet.size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + versionSet);
+ }
+ sb.append(CR);
+ first = false;
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ // Methods used for generation of code snippets for Server/ClientProxy class generation
+
+ protected String generateHandlerPointerDefinitions(AmqpModel model, boolean serverFlag,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations";
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ sb.append(indent + outerClassName + "::" + thisClass.getName() + "Handler* " +
+ thisClass.getName() + "HandlerPtr;" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateHandlerPointerGetMethods(AmqpModel model, boolean serverFlag,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations";
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ sb.append(indent + "virtual inline " + outerClassName + "::" + thisClass.getName() + "Handler* get" +
+ thisClass.getName() + "Handler() { return &" + Utils.firstLower(thisClass.getName()) + ";}" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName);
+ String className = parseForReservedWords(thisClass.getName(), null);
+ sb.append(indent + className + " " + instanceName + ";");
+ if (thisClass.getVersionSet().size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR);
+ }
+ else
+ {
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ String className = parseForReservedWords(thisClass.getName(), outerClassName);
+ sb.append(indent + className + "& get" + className + "();");
+ if (thisClass.getVersionSet().size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR);
+ }
+ else
+ {
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyInnerClassDefinitions(AmqpModel model, boolean serverFlag,
+ int indentSize, int tabSize)
+ {
+ String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ boolean first = true;
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ String className = thisClass.getName();
+ String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" +
+ thisClass.getName() + "Handler";
+ if (!first)
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "// ==================== class " + className +
+ " ====================" + CR);
+ sb.append(indent + "class " + className + " : virtual public " + superclassName);
+ if (thisClass.getVersionSet().size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR);
+ }
+ else
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "{" + CR);
+ sb.append(indent + "private:" + CR);
+ sb.append(indent + tab + "OutputHandler* out;" + CR);
+ sb.append(indent + tab + proxyClassName + "* parent;" + CR);
+ sb.append(CR);
+ sb.append(indent + "public:" + CR);
+ sb.append(indent + tab + "// Constructors and destructors" + CR);
+ sb.append(CR);
+ sb.append(indent + tab + className + "(OutputHandler* out, " + proxyClassName + "* _parent) : " + CR);
+ sb.append(indent + tab + tab + "out(out) {parent = _parent;}" + CR);
+ sb.append(indent + tab + "virtual ~" + className + "() {}" + CR);
+ sb.append(CR);
+ sb.append(indent + tab + "// Protocol methods" + CR);
+ sb.append(CR);
+ sb.append(generateInnerClassMethods(thisClass, serverFlag, false, indentSize + tabSize, tabSize));
+ sb.append(indent + "}; // class " + className + CR);
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyConstructorInitializers(AmqpModel model, boolean serverFlag,
+ int indentSize)
+ {
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations";
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer(indent + superclassName + "(major, minor)," + CR);
+ sb.append(indent + "version(major, minor)," + CR);
+ sb.append(indent + "out(out)");
+ Iterator<String> cItr = model.getClassMap().keySet().iterator();
+ while (cItr.hasNext())
+ {
+ AmqpClass thisClass = model.getClassMap().get(cItr.next());
+ String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName);
+ sb.append("," + CR);
+ sb.append(indent + instanceName + "(out, this)");
+ if (!cItr.hasNext())
+ {
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ Iterator<String> cItr = model.getClassMap().keySet().iterator();
+ while (cItr.hasNext())
+ {
+ AmqpClass thisClass = model.getClassMap().get(cItr.next());
+ String className = thisClass.getName();
+ String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName);
+ sb.append(indent + outerClassName + "::" + className + "& " +
+ outerClassName + "::get" + className + "()" + CR);
+ sb.append(indent + "{" + CR);
+ if (thisClass.getVersionSet().size() != getVersionSet().size())
+ {
+ sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.getVersionSet()) + ")" + CR);
+ sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + CR);
+ }
+ sb.append(indent + tab + "return " + instanceName + ";" + CR);
+ sb.append(indent + "}" + CR);
+ if (cItr.hasNext())
+ {
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ boolean firstClassFlag = true;
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ String className = thisClass.getName();
+ if (!firstClassFlag)
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "// ==================== class " + className +
+ " ====================" + CR);
+ sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize));
+ firstClassFlag = false;
+ }
+ return sb.toString();
+ }
+
+ protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String outerclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
+ boolean first = true;
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ String methodBodyClassName = thisClass.getName() + Utils.firstUpper(method.getName()) + "Body";
+ boolean clientChassisFlag = method.getClientMethodFlagMap().isSet();
+ boolean serverChassisFlag = method.getServerMethodFlagMap().isSet();
+ boolean versionConsistentFlag = method.isVersionConsistent(getVersionSet());
+ if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag))
+ {
+ String methodName = parseForReservedWords(method.getName(), outerclassName + "." + thisClass.getName());
+ AmqpOverloadedParameterMap overloadededParameterMap =
+ method.getOverloadedParameterLists(thisClass.getVersionSet(), this);
+ for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet())
+ {
+ AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap);
+ if (!first)
+ {
+ sb.append(CR);
+ }
+ sb.append(indent + "void " + outerclassName + "::" + thisClass.getName() + "::" +
+ methodName + "( u_int16_t channel");
+ sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true));
+ sb.append(" )");
+ if (versionSet.size() != getVersionSet().size())
+ {
+ sb.append(" // AMQP Version(s) " + versionSet);
+ }
+ sb.append(CR);
+ sb.append(indent + "{" + CR);
+ sb.append(generateMethodBodyCallContext(thisFieldMap, outerclassName, methodBodyClassName,
+ versionConsistentFlag, versionSet, indentSize + tabSize, tabSize));
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ first = false;
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateMethodBodyCallContext(AmqpOrdinalFieldMap fieldMap, String outerclassName,
+ String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ if (versionConsistentFlag)
+ {
+ sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, null, indentSize, tabSize));
+ }
+ else
+ {
+ boolean firstOverloadedMethodFlag = true;
+ for (AmqpVersion thisVersion : versionSet)
+ {
+ sb.append(indent);
+ if (!firstOverloadedMethodFlag)
+ {
+ sb.append("else ");
+ }
+ sb.append("if (" + generateVersionCheck(thisVersion) + ")" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, thisVersion,
+ indentSize + tabSize, tabSize));
+ sb.append(indent + "}" + CR);
+ firstOverloadedMethodFlag = false;
+ }
+ sb.append(indent + "else" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "std::stringstream ss;" + CR);
+ sb.append(indent + tab + "ss << \"Call to " + outerclassName + "::" + methodBodyClassName +
+ "(u_int16_t" + generateMethodParameterList(fieldMap, 0, true, true, false) + ")\"" + CR);
+ sb.append(indent + tab + tab + "<< \" is invalid for AMQP version \" << version.toString() << \".\";" + CR);
+ sb.append(indent + tab + "throw new ProtocolVersionException(ss.str());" + CR);
+ sb.append(indent + "}" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateMethodBodyCall(AmqpOrdinalFieldMap fieldMap, String methodBodyClassName,
+ AmqpVersion version, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ String namespace = version != null ? version.namespace() + "::" : "";
+ StringBuffer sb = new StringBuffer(indent + "out->send( new AMQFrame(parent->getProtocolVersion(), channel," + CR);
+ sb.append(indent + tab + "new " + namespace + methodBodyClassName + "( parent->getProtocolVersion()");
+ sb.append(generateMethodParameterList(fieldMap, indentSize + (5 * tabSize), true, false, true));
+ sb.append(" )));" + CR);
+ return sb.toString();
+ }
+
+ protected String generateMethodBodyIncludes(AmqpClass thisClass, int indentSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ if (thisClass != null)
+ {
+ sb.append(generateClassMethodBodyInclude(thisClass, indentSize));
+ }
+ else
+ {
+ for (String thisClassName : getModel().getClassMap().keySet())
+ {
+ thisClass = getModel().getClassMap().get(thisClassName);
+ sb.append(generateClassMethodBodyInclude(thisClass, indentSize));
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateClassMethodBodyInclude(AmqpClass thisClass, int indentSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ String indent = Utils.createSpaces(indentSize);
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ sb.append(indent + "#include <" + thisClass.getName() +
+ Utils.firstUpper(method.getName()) + "Body.h>" + CR);
+ }
+ return sb.toString();
+ }
+
+ // Methods used for generation of code snippets for MethodBody class generation
+
+ protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version)
+ {
+ for (Integer thisIndex : indexMap.keySet())
+ {
+ AmqpVersionSet versionSet = indexMap.get(thisIndex);
+ if (versionSet.contains(version))
+ {
+ return String.valueOf(thisIndex);
+ }
+ }
+ throw new AmqpTemplateException("Unable to find index for version " + version);
+ }
+
+ protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ if (version == null)
+ {
+ version = getVersionSet().first();
+ }
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this);
+ for (Integer thisOrdinal : ordinalFieldMap.keySet())
+ {
+ String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal);
+ sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ if (version == null)
+ {
+ version = getVersionSet().first();
+ }
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this);
+ for (Integer thisOrdinal : ordinalFieldMap.keySet())
+ {
+ String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal);
+ sb.append(indent + "inline " + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" +
+ Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() { return " +
+ fieldDomainPair[FIELD_NAME] + "; }" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ if (version == null)
+ {
+ version = getVersionSet().first();
+ }
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this);
+ boolean firstFlag = true;
+ for (Integer thisOrdinal : ordinalFieldMap.keySet())
+ {
+ String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal);
+ String cast = fieldDomainPair[FIELD_CODE_TYPE].compareTo("u_int8_t") == 0 ? "(int)" : "";
+ sb.append(indent + "out << \"");
+ if (!firstFlag)
+ {
+ sb.append("; ");
+ }
+ sb.append(fieldDomainPair[FIELD_NAME] + "=\" << " + cast + fieldDomainPair[FIELD_NAME] + ";" + CR);
+ firstFlag = false;
+ }
+ return sb.toString();
+ }
+
+ protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ ArrayList<String> bitFieldList = new ArrayList<String>();
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this);
+ Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator();
+ int ordinal = 0;
+ while (oItr.hasNext())
+ {
+ ordinal = oItr.next();
+ String[] fieldDomainPair = ordinalFieldMap.get(ordinal);
+ AmqpVersion thisVersion = version == null ? getVersionSet().first() : version;
+ String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion);
+
+ // Defer bit types by adding them to an array. When the first subsequent non-bit
+ // type is encountered, then handle the bits. This allows consecutive bits to be
+ // placed into the same byte(s) - 8 bits to the byte.
+ if (domainType.compareTo("bit") == 0)
+ {
+ bitFieldList.add(fieldDomainPair[FIELD_NAME]);
+ }
+ else
+ {
+ if (bitFieldList.size() > 0) // Handle accumulated bit types (if any)
+ {
+ sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+ sb.append(indent + "size += " +
+ typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) +
+ "; /* " + fieldDomainPair[FIELD_NAME] + ": " +
+ domainType + " */" + CR);
+ }
+ }
+ if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types
+ {
+ sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+ return sb.toString();
+ }
+
+ protected String generateBitArrayBodySizeMethodContents(ArrayList<String> bitFieldList,
+ int ordinal, int indentSize)
+ {
+ int numBytes = ((bitFieldList.size() - 1) / 8) + 1;
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ String comment = bitFieldList.size() == 1 ?
+ bitFieldList.get(0) + ": bit" :
+ "Combinded bits: " + bitFieldList;
+ sb.append(indent + "size += " +
+ typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) +
+ "; /* " + comment + " */" + CR);
+ bitFieldList.clear();
+ return sb.toString();
+ }
+
+ protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ ArrayList<String> bitFieldList = new ArrayList<String>();
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this);
+ Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator();
+ int ordinal = 0;
+ while (oItr.hasNext())
+ {
+ ordinal = oItr.next();
+ String[] fieldDomainPair = ordinalFieldMap.get(ordinal);
+ AmqpVersion thisVersion = version == null ? getVersionSet().first() : version;
+ String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion);
+
+ // Defer bit types by adding them to an array. When the first subsequent non-bit
+ // type is encountered, then handle the bits. This allows consecutive bits to be
+ // placed into the same byte(s) - 8 bits to the byte.
+ if (domainType.compareTo("bit") == 0)
+ {
+ bitFieldList.add(fieldDomainPair[FIELD_NAME]);
+ }
+ else
+ {
+ if (bitFieldList.size() > 0) // Handle accumulated bit types (if any)
+ {
+ sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+ sb.append(indent +
+ typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) +
+ "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR);
+ }
+ }
+ if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types
+ {
+ sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+
+ return sb.toString();
+ }
+
+ protected String generateBitEncodeMethodContents(ArrayList<String> bitFieldList, int ordinal,
+ int indentSize)
+ {
+ int numBytes = ((bitFieldList.size() - 1) / 8) + 1;
+ String indent = Utils.createSpaces(indentSize);
+ String bitArrayName = "flags_" + ordinal;
+ StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName +
+ "[" + numBytes + "] = {0};" +
+ (numBytes != 1 ? " /* All array elements will be initialized to 0 */" : "") +
+ CR);
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ int bitIndex = i % 8;
+ int byteIndex = i / 8;
+ sb.append(indent + bitArrayName + "[" + byteIndex + "] |= " + bitFieldList.get(i) +
+ " << " + bitIndex + "; /* " + bitFieldList.get(i) + ": bit */" + CR);
+ }
+ for (int i = 0; i < numBytes; i++)
+ {
+ sb.append(indent + "buffer.putOctet(" + bitArrayName + "[" + i + "]);" + CR);
+ }
+ bitFieldList.clear();
+ return sb.toString();
+ }
+
+ protected String generateDecodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version,
+ int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ ArrayList<String> bitFieldList = new ArrayList<String>();
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this);
+ Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator();
+ int ordinal = 0;
+ while (oItr.hasNext())
+ {
+ ordinal = oItr.next();
+ String[] fieldDomainPair = ordinalFieldMap.get(ordinal);
+ AmqpVersion thisVersion = version == null ? getVersionSet().first() : version;
+ String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion);
+
+ // Defer bit types by adding them to an array. When the first subsequent non-bit
+ // type is encountered, then handle the bits. This allows consecutive bits to be
+ // placed into the same byte(s) - 8 bits to the byte.
+ if (domainType.compareTo("bit") == 0)
+ {
+ bitFieldList.add(fieldDomainPair[FIELD_NAME]);
+ }
+ else
+ {
+ if (bitFieldList.size() > 0) // Handle accumulated bit types (if any)
+ {
+ sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+ sb.append(indent +
+ typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) +
+ "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR);
+ }
+ }
+ if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types
+ {
+ sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize));
+ }
+
+ return sb.toString();
+ }
+
+ protected String generateBitDecodeMethodContents(ArrayList<String> bitFieldList, int ordinal,
+ int indentSize)
+ {
+ int numBytes = ((bitFieldList.size() - 1) / 8) + 1;
+ String indent = Utils.createSpaces(indentSize);
+ String bitArrayName = "flags_" + ordinal;
+ StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName +
+ "[" + numBytes + "];" + CR);
+ for (int i = 0; i < numBytes; i++)
+ {
+ sb.append(indent + bitArrayName + "[" + i + "] = buffer.getOctet();" + CR);
+ }
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ int bitIndex = i % 8;
+ int byteIndex = i / 8;
+ sb.append(indent + bitFieldList.get(i) + " = (1 << " + bitIndex + ") & " +
+ bitArrayName + "[" + byteIndex + "]; /* " + bitFieldList.get(i) +
+ ": bit */" + CR);
+ }
+ bitFieldList.clear();
+ return sb.toString();
+ }
+
+ protected String generateFieldList(AmqpFieldMap fieldMap, AmqpVersion version, boolean defineFlag,
+ boolean initializerFlag, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this);
+ Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator();
+ while (oItr.hasNext())
+ {
+ int ordinal = oItr.next();
+ String[] fieldDomainPair = ordinalFieldMap.get(ordinal);
+ sb.append(indent + (defineFlag ? setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " " : "") +
+ fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") +
+ (oItr.hasNext() ? "," : "") + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize,
+ boolean leadingCommaFlag, boolean fieldTypeFlag, boolean fieldNameFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ boolean first = true;
+ Iterator<Integer> pItr = fieldMap.keySet().iterator();
+ while (pItr.hasNext())
+ {
+ String[] field = fieldMap.get(pItr.next());
+ if (first && leadingCommaFlag)
+ {
+ sb.append("," + (fieldNameFlag ? CR : " "));
+ }
+ if (!first || leadingCommaFlag)
+ {
+ sb.append(indent);
+ }
+ sb.append(
+ (fieldTypeFlag ? setRef(field[FIELD_CODE_TYPE]) : "") +
+ (fieldNameFlag ? " " + field[FIELD_NAME] : "") +
+ (pItr.hasNext() ? "," + (fieldNameFlag ? CR : " ") : ""));
+ first = false;
+ }
+ return sb.toString();
+ }
+
+ protected String generateConstructor(AmqpClass thisClass, AmqpMethod method,
+ AmqpVersion version, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ if (method.getFieldMap().size() > 0)
+ {
+ sb.append(indent + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body(ProtocolVersion& version," + CR);
+ sb.append(generateFieldList(method.getFieldMap(), version, true, false, 8));
+ sb.append(indent + tab + ") :" + CR);
+ sb.append(indent + tab + "AMQMethodBody(version)," + CR);
+ sb.append(generateFieldList(method.getFieldMap(), version, false, true, 8));
+ sb.append(indent + "{ }" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateServerOperationsInvoke(AmqpClass thisClass, AmqpMethod method,
+ AmqpVersion version, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+
+ if (method.getServerMethodFlagMap().size() > 0) // At least one AMQP version defines this method as a server method
+ {
+ Iterator<Boolean> bItr = method.getServerMethodFlagMap().keySet().iterator();
+ while (bItr.hasNext())
+ {
+ if (bItr.next()) // This is a server operation
+ {
+ boolean fieldMapNotEmptyFlag = method.getFieldMap().size() > 0;
+ sb.append(indent + "inline void invoke(AMQP_ServerOperations& target, u_int16_t channel)" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "target.get" + thisClass.getName() + "Handler()->" +
+ parseForReservedWords(Utils.firstLower(method.getName()),
+ thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.invoke()") + "(channel");
+ if (fieldMapNotEmptyFlag)
+ {
+ sb.append("," + CR);
+ sb.append(generateFieldList(method.getFieldMap(), version, false, false, indentSize + 4 * tabSize));
+ sb.append(indent + tab + tab + tab + tab);
+ }
+ sb.append(");" + CR);
+ sb.append(indent + "}" + CR);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ // Methods for generation of code snippets for amqp_methods.h/cpp files
+
+ protected String generateMethodBodyIncludeList(AmqpModel model, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ sb.append(indent + "#include \"" + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.h\"" + CR);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ protected String generateMethodBodyInstances(AmqpModel model, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ sb.append(indent + "const " + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body " +
+ Utils.firstLower(thisClass.getName()) + "_" + method.getName() + ";" + CR);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ protected String generateMethodBodyMapEntry(AmqpModel model, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (AmqpVersion version : getVersionSet())
+ {
+ for (String thisClassName : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(thisClassName);
+ for (String thisMethodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
+ String namespace = method.isVersionConsistent(getVersionSet()) ? "" : version.namespace() + "::";
+ try
+ {
+ int classOrdinal = thisClass.getIndexMap().getOrdinal(version);
+ int methodOrdinal = method.getIndexMap().getOrdinal(version);
+ String methodModyClassName = namespace + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body";
+ sb.append(indent + "insert(std::make_pair(createMapKey(" + classOrdinal + ", " +
+ methodOrdinal + ", " + version.getMajor() + ", " + version.getMinor() +
+ "), &createMethodBodyFn<" + methodModyClassName + ">));" + CR);
+ }
+ catch (AmqpTypeMappingException e)
+ {
+ } // ignore
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ // Helper functions
+
+ private String generateVersionCheck(AmqpVersion version)
+ {
+ return "version.equals(" + version.getMajor() + ", " + version.getMinor() + ")";
+ }
+
+ private String generateVersionCheck(AmqpVersionSet versionSet)
+ {
+ StringBuffer sb = new StringBuffer();
+ for (AmqpVersion v : versionSet)
+ {
+ if (!v.equals(versionSet.first()))
+ {
+ sb.append(" || ");
+ }
+ if (versionSet.size() > 1)
+ {
+ sb.append("(");
+ }
+ sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")");
+ if (versionSet.size() > 1)
+ {
+ sb.append(")");
+ }
+ }
+ return sb.toString();
+ }
+
+ private String parseForReservedWords(String name, String context)
+ {
+ for (String cppReservedWord : cppReservedWords)
+ {
+ if (name.compareTo(cppReservedWord) == 0)
+ {
+ if (!quietFlag)
+ {
+ System.out.println("WARNING: " + (context == null ? "" : context + ": ") +
+ "Found XML method \"" + name + "\", which is a C++ reserved word. " +
+ "Changing generated name to \"" + name + "_\".");
+ }
+ return name + "_";
+ }
+ }
+
+ for (String cppCommonDefine : cppCommonDefines)
+ {
+ if (name.compareTo(cppCommonDefine) == 0)
+ {
+ if (!quietFlag)
+ {
+ System.out.println("WARNING: " + (context == null ? "" : context + ": ") +
+ "Found XML method \"" + name + "\", which may clash with commonly used defines within C++. " +
+ "Changing generated name to \"" + name + "_\".");
+ }
+ return name + "_";
+ }
+ }
+
+ return name;
+ }
+
+ private String setRef(String codeType)
+ {
+ if (codeType.compareTo("string") == 0 ||
+ codeType.compareTo("FieldTable") == 0)
+ {
+ return "const " + codeType + "&";
+ }
+ return codeType;
+ }
+
+ private String camelCaseName(String name, boolean upperFirstFlag)
+ {
+ StringBuffer ccn = new StringBuffer();
+ String[] toks = name.split("[-_.\\ ]");
+ for (int i = 0; i < toks.length; i++)
+ {
+ StringBuffer b = new StringBuffer(toks[i]);
+ if (upperFirstFlag || i > 0)
+ {
+ b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0)));
+ }
+ ccn.append(b);
+ }
+ return ccn.toString();
+ }
+
+ public static Factory<CppGenerator> _factoryInstance = new Factory<CppGenerator>()
+ {
+
+ public CppGenerator newInstance()
+ {
+ return new CppGenerator();
+ }
+ };
+
+ public static Factory<CppGenerator> getFactory()
+ {
+ return _factoryInstance;
+ }
+
+ void processModelTemplate(NamedTemplate template, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+ public String getNativeType(String type)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getEncodingType(String type)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java b/java/common/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java
new file mode 100644
index 0000000000..9fc81dd428
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java
@@ -0,0 +1,382 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.File;
+import java.util.TreeMap;
+
+public class DotnetGenerator extends Generator
+{
+ private class DomainInfo
+ {
+ public String type;
+ public String size;
+ public String encodeExpression;
+ public String decodeExpression;
+
+ public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression)
+ {
+ this.type = domain;
+ this.size = size;
+ this.encodeExpression = encodeExpression;
+ this.decodeExpression = decodeExpression;
+ }
+ }
+
+ private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>();
+
+ public String getNativeType(String type)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getEncodingType(String type)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public DotnetGenerator()
+ {
+ super();
+ // Load .NET type and size maps.
+ // Adjust or add to these lists as new types are added/defined.
+ // The char '#' will be replaced by the field variable name (any type).
+ // The char '~' will be replaced by the compacted bit array size (type bit only).
+ // TODO: I have left a copy of the Java typeMap here - replace with appropriate .NET values.
+ typeMap.put("bit", new DomainInfo(
+ "boolean", // .NET code type
+ "~", // size
+ "EncodingUtils.writeBooleans(buffer, #)", // encode expression
+ "# = EncodingUtils.readBooleans(buffer)")); // decode expression
+ typeMap.put("content", new DomainInfo(
+ "Content", // .NET code type
+ "EncodingUtils.encodedContentLength(#)", // size
+ "EncodingUtils.writeContentBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readContent(buffer)")); // decode expression
+ typeMap.put("long", new DomainInfo(
+ "long", // .NET code type
+ "4", // size
+ "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression
+ "# = buffer.getUnsignedInt()")); // decode expression
+ typeMap.put("longlong", new DomainInfo(
+ "long", // .NET code type
+ "8", // size
+ "buffer.putLong(#)", // encode expression
+ "# = buffer.getLong()")); // decode expression
+ typeMap.put("longstr", new DomainInfo(
+ "byte[]", // .NET code type
+ "EncodingUtils.encodedLongstrLength(#)", // size
+ "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readLongstr(buffer)")); // decode expression
+ typeMap.put("octet", new DomainInfo(
+ "short", // .NET code type
+ "1", // size
+ "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression
+ "# = buffer.getUnsigned()")); // decode expression
+ typeMap.put("short", new DomainInfo(
+ "int", // .NET code type
+ "2", // size
+ "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression
+ "# = buffer.getUnsignedShort()")); // decode expression
+ typeMap.put("shortstr", new DomainInfo(
+ "AMQShortString", // .NET code type
+ "EncodingUtils.encodedShortStringLength(#)", // size
+ "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression
+ typeMap.put("table", new DomainInfo(
+ "FieldTable", // .NET code type
+ "EncodingUtils.encodedFieldTableLength(#)", // size
+ "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readFieldTable(buffer)")); // decode expression
+ typeMap.put("timestamp", new DomainInfo(
+ "long", // .NET code type
+ "8", // size
+ "EncodingUtils.writeTimestamp(buffer, #)", // encode expression
+ "# = EncodingUtils.readTimestamp(buffer)")); // decode expression
+ }
+
+ void processModelTemplate(NamedTemplate template, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ protected String prepareFilename(String filenameTemplate,
+ AmqpClass thisClass, AmqpMethod method, AmqpField field, AmqpVersion version)
+ {
+ StringBuffer sb = new StringBuffer(filenameTemplate);
+ if (thisClass != null)
+ {
+ replaceToken(sb, "${CLASS}", thisClass.getName());
+ }
+ if (method != null)
+ {
+ replaceToken(sb, "${METHOD}", method.getName());
+ }
+ if (field != null)
+ {
+ replaceToken(sb, "${FIELD}", field.getName());
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected void processClassList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpModel model, AmqpVersion version)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = generateRegistry(model, 8, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processConstantList(StringBuffer sb,
+ int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpConstantSet constantSet) throws AmqpTemplateException,
+ AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processFieldList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod,
+// mangledDeclarationGenerateMethod, 4, 4, this);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processMethodList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpClass thisClass)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processModelTemplate(NamedTemplate template)
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplate(template, null, null, null, null);
+ }
+
+ @Override
+ protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass)
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplate(template, thisClass, null, null, null);
+ }
+
+ @Override
+ protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method)
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplate(template, thisClass, method, null, null);
+ }
+
+ @Override
+ protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field, AmqpVersion version)
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ StringBuffer sb = new StringBuffer(template.getTemplate());
+ String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version);
+ try
+ {
+ processAllLists(sb, thisClass, method, null);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + template.getName() + ": " + e.getMessage());
+ }
+ try
+ {
+ processAllTokens(sb, thisClass, method, field, null);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + template.getName() + ": " + e.getMessage());
+ }
+ writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename));
+ generatedFileCounter++;
+ }
+
+ @Override
+ protected String processToken(String token, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field, AmqpVersion version)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getGeneratedType(String domainName, AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ String domainType = getDomainType(domainName, version);
+ if (domainType == null)
+ {
+ throw new AmqpTypeMappingException("Domain type \"" + domainName +
+ "\" not found in Java typemap.");
+ }
+ DomainInfo info = typeMap.get(domainType);
+ if (info == null)
+ {
+ throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\"");
+ }
+ return info.type;
+ }
+
+ public String prepareClassName(String className)
+ {
+ return camelCaseName(className, true);
+ }
+
+ public String prepareDomainName(String domainName)
+ {
+ return camelCaseName(domainName, false);
+ }
+
+ public String prepareMethodName(String methodName)
+ {
+ return camelCaseName(methodName, false);
+ }
+
+ private String camelCaseName(String name, boolean upperFirstFlag)
+ {
+ StringBuffer ccn = new StringBuffer();
+ String[] toks = name.split("[-_.\\ ]");
+ for (int i = 0; i < toks.length; i++)
+ {
+ StringBuffer b = new StringBuffer(toks[i]);
+ if (upperFirstFlag || i > 0)
+ {
+ b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0)));
+ }
+ ccn.append(b);
+ }
+ return ccn.toString();
+ }
+
+
+ public static Factory<DotnetGenerator> _factoryInstance = new Factory<DotnetGenerator>()
+ {
+
+ public DotnetGenerator newInstance()
+ {
+ return new DotnetGenerator();
+ }
+ };
+
+ public static Factory<DotnetGenerator> getFactory()
+ {
+ return _factoryInstance;
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/GenerateMethod.java b/java/common/gentools/src/org/apache/qpid/gentools/GenerateMethod.java
new file mode 100644
index 0000000000..8b0bb99b41
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/GenerateMethod.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.gentools;
+
+
+public interface GenerateMethod
+{
+ String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize);
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/Generator.java b/java/common/gentools/src/org/apache/qpid/gentools/Generator.java
new file mode 100644
index 0000000000..5d6e7be527
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/Generator.java
@@ -0,0 +1,857 @@
+/*
+ *
+ * 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.gentools;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.w3c.dom.Node;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class Generator implements LanguageConverter
+{
+ protected static String CR = Utils.LINE_SEPARATOR;
+
+
+ private static final Map<String, Integer> FIXED_SIZE_TYPES = new HashMap<String, Integer>();
+
+ static
+ {
+ FIXED_SIZE_TYPES.put("bit", 1);
+ FIXED_SIZE_TYPES.put("bitfield", 1);
+ FIXED_SIZE_TYPES.put("long", 4);
+ FIXED_SIZE_TYPES.put("longlong", 8);
+ FIXED_SIZE_TYPES.put("octet", 1);
+ FIXED_SIZE_TYPES.put("short", 2);
+ FIXED_SIZE_TYPES.put("timestamp", 8);
+
+ }
+
+ private String _templateDirectory;
+ private String _outputDirectory;
+
+ public AmqpDomainMap getDomainMap()
+ {
+ return _domainMap;
+ }
+
+ public AmqpConstantSet getConstantSet()
+ {
+ return _constantSet;
+ }
+
+ public AmqpModel getModel()
+ {
+ return _model;
+ }
+
+ abstract public String getNativeType(String type);
+
+ abstract public String getEncodingType(String type);
+
+
+
+ protected static enum EnumConstOutputTypes
+ {
+ OUTPUT_STRING,
+ OUTPUT_INTEGER,
+ OUTPUT_DOUBLE;
+ }
+
+ ;
+
+ public static enum TemplateType
+ {
+ model("model"),
+ clazz("class"),
+ method("method"),
+ field("field");
+
+ private final String _name;
+
+ private TemplateType(String name)
+ {
+ _name = name;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+ }
+
+ ;
+
+
+ public static interface Factory<X extends Generator>
+ {
+ public X newInstance();
+ }
+
+
+ protected static final class NamedTemplate
+ {
+ private final String _name;
+ private final String _template;
+ private final File _file;
+
+
+ public NamedTemplate(String relativePath, File templateFile)
+ {
+ _file = templateFile;
+ _name = relativePath + Utils.FILE_SEPARATOR + templateFile.getName();
+
+ _template = loadTemplate(templateFile);
+ }
+
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getTemplate()
+ {
+ return _template;
+ }
+
+
+ public File getFile()
+ {
+ return _file;
+ }
+
+ }
+
+
+ private static final String VELOCITY_TEMPLATE_SUFFIX = ".vm";
+ private static final String STANDARD_TEMPLATE_SUFFIX = ".tmpl";
+ private static FilenameFilter _tmplFileFilter = new FilenameFilter()
+ {
+
+ public boolean accept(File dir, String name)
+ {
+ return name.endsWith(STANDARD_TEMPLATE_SUFFIX) || name.endsWith(VELOCITY_TEMPLATE_SUFFIX);
+ }
+ };
+
+
+ // This string is reproduced in every generated file as a comment
+ // TODO: Tie the version info into the build system.
+ protected static final String GENERATOR_INFO = "Qpid Gentools v.0.1";
+
+
+ private final Map<TemplateType, Collection<NamedTemplate>> _templates =
+ new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
+
+ private final Map<TemplateType, Collection<NamedTemplate>> _versionSpecificTemplates =
+ new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class);
+
+
+ private final AmqpVersionSet _versionSet;
+
+ private final AmqpDomainMap _domainMap;
+ private final Map<AmqpVersion, AmqpDomainMap> _versionToDomainMapMap = new HashMap<AmqpVersion, AmqpDomainMap>();
+
+ private final AmqpConstantSet _constantSet;
+ private final Map<AmqpVersion, AmqpConstantSet> _versionToConstantSetMap = new HashMap<AmqpVersion, AmqpConstantSet>();
+
+
+ public AmqpVersionSet getVersionSet()
+ {
+ return _versionSet;
+ }
+
+ private final AmqpModel _model;
+ private final Map<AmqpVersion, AmqpModel> _versionToModelMap = new HashMap<AmqpVersion, AmqpModel>();
+
+ protected int generatedFileCounter;
+
+ public Generator()
+ {
+ _versionSet = new AmqpVersionSet();
+ _model = new AmqpModel(this);
+ _constantSet = new AmqpConstantSet(this);
+ _domainMap = new AmqpDomainMap(this);
+
+ generatedFileCounter = 0;
+ }
+
+// public final AmqpVersionSet getVersionSet()
+// {
+// return _versionSet;
+// }
+
+
+ public void addVersion(AmqpVersion version)
+ {
+ _versionSet.add(version);
+ if (!_versionToModelMap.containsKey(version))
+ {
+ _versionToModelMap.put(version, new AmqpModel(this));
+ }
+ if (!_versionToDomainMapMap.containsKey(version))
+ {
+ _versionToDomainMapMap.put(version, new AmqpDomainMap(this));
+ }
+ if (!_versionToConstantSetMap.containsKey(version))
+ {
+ _versionToConstantSetMap.put(version, new AmqpConstantSet(this));
+ }
+ }
+
+ public int getNumberGeneratedFiles()
+ {
+ return generatedFileCounter;
+ }
+
+// public AmqpDomainMap getDomainMap()
+// {
+// return _domainMap;
+// }
+//
+// public AmqpConstantSet getConstantSet()
+// {
+// return _constantSet;
+// }
+//
+//
+// public AmqpModel getModel()
+// {
+// return _model;
+// }
+
+ public void initializeTemplates() throws IOException
+ {
+
+ for (TemplateType type : EnumSet.allOf(TemplateType.class))
+ {
+ ArrayList<NamedTemplate> typeTemplates = new ArrayList<NamedTemplate>();
+ _templates.put(type, typeTemplates);
+ ArrayList<NamedTemplate> versionSpecificTypeTemplates = new ArrayList<NamedTemplate>();
+ _versionSpecificTemplates.put(type, versionSpecificTypeTemplates);
+
+ File templateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName());
+ File versionTemplateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName() + Utils.FILE_SEPARATOR + "version");
+
+ System.out.println("Looking for template files in directory: " + templateDirectory.getAbsoluteFile());
+
+ File[] templateFiles = templateDirectory.listFiles(_tmplFileFilter);
+
+ File[] versionTemplateFiles = new File[0];
+
+ System.out.println("Looking for version specific template files in directory: " + versionTemplateDirectory.getAbsoluteFile());
+
+ if (versionTemplateDirectory.exists())
+ {
+ versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter);
+ }
+
+ if(templateFiles != null)
+ {
+ for (File templateFile : templateFiles)
+ {
+ System.out.println(type.getName() + " template file(s):");
+ System.out.println(" " + templateFile.getCanonicalPath());
+ typeTemplates.add(new NamedTemplate(type.getName(), templateFile));
+ }
+ }
+
+ if(versionTemplateFiles != null)
+ {
+ for (File versionTemplateFile : versionTemplateFiles)
+ {
+ System.out.println(type.getName() + " template file(s):");
+ System.out.println(" " + versionTemplateFile.getCanonicalPath());
+ versionSpecificTypeTemplates.add(new NamedTemplate(type.getName() + Utils.FILE_SEPARATOR + "version", versionTemplateFile));
+ }
+ }
+
+ }
+ }
+
+ public String getTemplateDirectory()
+ {
+ return _templateDirectory;
+ }
+
+
+ public void setTemplateDirectory(String templateDirectory)
+ {
+ _templateDirectory = templateDirectory;
+ }
+
+
+ public void setOutputDirectory(String outputDirectory)
+ {
+ _outputDirectory = outputDirectory;
+ }
+
+ public void generate()
+ {
+ prepareTargetDirectory(new File(_outputDirectory), true);
+ System.out.println("Generation directory: " + _outputDirectory);
+
+
+ processModelTemplates(_templates);
+
+ for (AmqpClass amqpClass : _model.getClassMap().values())
+ {
+ processClassTemplates(_templates, amqpClass);
+
+ for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
+ {
+ processMethodTemplates(_templates, amqpClass, amqpMethod);
+
+ for (AmqpField amqpField : amqpMethod.getFieldMap().values())
+ {
+ processFieldTemplates(_templates, amqpClass, amqpMethod, amqpField, null);
+ }
+ }
+ }
+
+
+ for (AmqpVersion version : _versionSet)
+ {
+ AmqpModel model = _versionToModelMap.get(version);
+ processModelTemplates(_versionSpecificTemplates, version);
+
+ for (AmqpClass amqpClass : model.getClassMap().values())
+ {
+ processClassTemplates(_versionSpecificTemplates, amqpClass, version);
+
+ for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values())
+ {
+ processMethodTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, version);
+
+ for (AmqpField amqpField : amqpMethod.getFieldMap().values())
+ {
+ processFieldTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, amqpField, version);
+ }
+ }
+ }
+
+ }
+ }
+
+ private void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.method))
+ {
+ if(isVelocityTemplate(template))
+ {
+ processVelocityTemplate(template,version,amqpClass,amqpMethod,null);
+ }
+ else
+ {
+ processMethodTemplate(template, amqpClass, amqpMethod);
+ }
+ }
+
+ }
+
+ private void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpVersion version)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.clazz))
+ {
+ if(isVelocityTemplate(template))
+ {
+ processVelocityTemplate(template,version,amqpClass,null,null);
+ }
+ else
+ {
+ processClassTemplate(template, amqpClass);
+ }
+ }
+
+ }
+
+
+ private void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpVersion version)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.model))
+ {
+ if (isVelocityTemplate(template))
+ {
+ processModelVelocityTemplate(template, version);
+ }
+ else
+ {
+ processModelTemplate(template, version);
+ }
+ }
+ }
+
+ abstract void processModelTemplate(NamedTemplate template, AmqpVersion version);
+
+
+ protected void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.model))
+ {
+ if (isVelocityTemplate(template))
+ {
+ processModelVelocityTemplate(template, null);
+ }
+ else
+ {
+ processModelTemplate(template);
+ }
+ }
+ }
+
+ private boolean isVelocityTemplate(NamedTemplate template)
+ {
+ return template.getName().endsWith(VELOCITY_TEMPLATE_SUFFIX);
+ }
+
+ private void processModelVelocityTemplate(NamedTemplate template, AmqpVersion version)
+ {
+ processVelocityTemplate(template,version,null,null,null);
+ }
+
+ private void processVelocityTemplate(NamedTemplate template, AmqpVersion version,
+ AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField)
+ {
+
+ VelocityContext context = new VelocityContext();
+
+ AmqpModel model = _model;
+ if(version != null)
+ {
+ model = _versionToModelMap.get(version);
+ }
+ context.put("model", model);
+ context.put("generator", GENERATOR_INFO);
+
+ if (version != null)
+ {
+ context.put("version", version);
+ }
+ if(amqpClass != null)
+ {
+ context.put("amqpClass", amqpClass);
+ }
+
+ if(amqpClass != null)
+ {
+ context.put("amqpMethod", amqpMethod);
+ }
+
+
+ StringWriter sw = new StringWriter();
+
+
+ try
+ {
+ Template velocityTemplate = Velocity.getTemplate(template.getName());
+ velocityTemplate.merge(context, sw);
+ String filename = String.valueOf(context.get("filename"));
+
+ File outputFile = new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename);
+ outputFile.getParentFile().mkdirs();
+ FileWriter outputFileWriter = new FileWriter(outputFile);
+
+ outputFileWriter.append(sw.toString());
+ outputFileWriter.close();
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+
+ }
+
+
+ protected void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.clazz))
+ {
+ if(isVelocityTemplate(template))
+ {
+ processVelocityTemplate(template,null,amqpClass,null,null);
+ }
+ else
+ {
+ processClassTemplate(template, amqpClass);
+ }
+ }
+ }
+
+ protected void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.method))
+ {
+ if(isVelocityTemplate(template))
+ {
+ processVelocityTemplate(template,null,amqpClass,amqpMethod,null);
+ }
+ else
+ {
+ processMethodTemplate(template, amqpClass, amqpMethod);
+ }
+ }
+ }
+
+
+ protected void processFieldTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion amqpVersion)
+ {
+ for (NamedTemplate template : templates.get(TemplateType.field))
+ {
+ if(isVelocityTemplate(template))
+ {
+ processVelocityTemplate(template,amqpVersion,amqpClass,amqpMethod,amqpField);
+ }
+ else
+ {
+ processTemplate(template, amqpClass, amqpMethod, amqpField, amqpVersion);
+ }
+ }
+ }
+
+
+ protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd)
+ {
+ int lend = sb.indexOf(Utils.LINE_SEPARATOR, tokStart) + 1; // Include cr at end of line
+ String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr
+ sb.delete(tokStart, lend);
+
+ for (AmqpVersion v : _versionSet)
+ {
+ // Insert copy of target line
+ StringBuffer isb = new StringBuffer(tline);
+ if (isb.indexOf("${protocol-version-list-entry}") >= 0)
+ {
+ String versionListEntry = " { ${major}, ${minor} }" +
+ (v.equals(_versionSet.last()) ? "" : ",");
+ replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry));
+ }
+ if (isb.indexOf("${major}") >= 0)
+ {
+ replaceToken(isb, "${major}", String.valueOf(v.getMajor()));
+ }
+ if (isb.indexOf("${minor}") >= 0)
+ {
+ replaceToken(isb, "${minor}", String.valueOf(v.getMinor()));
+ }
+ sb.insert(tokStart, isb.toString());
+ tokStart += isb.length();
+ }
+ }
+
+ // Helper functions common to all generators
+
+ protected static void prepareTargetDirectory(File dir, boolean createFlag)
+ {
+ if (dir.exists())
+ {
+ if (!dir.isDirectory())
+ {
+ throw new TargetDirectoryException("\"" + dir.getAbsolutePath() +
+ "\" exists, but is not a directory.");
+ }
+ }
+ else if (createFlag) // Create dir
+ {
+ if (!dir.mkdirs())
+ {
+ throw new TargetDirectoryException("Unable to create directory \"" +
+ dir.getAbsolutePath() + "\".");
+ }
+ }
+ else
+ {
+ throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() +
+ "\" not found.");
+ }
+
+ }
+
+ protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version)
+ {
+ AmqpModel model = (version == null) ? _model : _versionToModelMap.get(version);
+
+
+ int lstart = sb.indexOf("%{");
+ while (lstart != -1)
+ {
+ int lend = sb.indexOf("}", lstart + 2);
+ if (lend > 0)
+ {
+ String listToken = sb.substring(lstart + 2, lend);
+ if (listToken.compareTo("VLIST") == 0)
+ {
+ processVersionList(sb, lstart, lend + 1);
+ }
+ else if (listToken.compareTo("CLIST") == 0)
+ {
+ processClassList(sb, lstart, lend + 1, model, version);
+ }
+ else if (listToken.compareTo("MLIST") == 0)
+ {
+ processMethodList(sb, lstart, lend + 1, thisClass);
+ }
+ else if (listToken.compareTo("FLIST") == 0)
+ {
+ // Pass the FieldMap from either a class or a method.
+ // If this is called from a class-level template, we assume that the
+ // class field list is required. In this case, method will be null.
+ processFieldList(sb, lstart, lend + 1,
+ (method == null ? thisClass.getFieldMap() : method.getFieldMap()),
+ version);
+ }
+ else if (listToken.compareTo("TLIST") == 0)
+ {
+ processConstantList(sb, lstart, lend + 1, _constantSet);
+ }
+ else
+ {
+ throw new AmqpTemplateException("Unknown list token \"%{" + listToken +
+ "}\" found in template at index " + lstart + ".");
+ }
+ }
+ lstart = sb.indexOf("%{", lstart + 1);
+ }
+ }
+
+ protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field,
+ AmqpVersion version)
+ {
+ int lstart = sb.indexOf("${");
+ while (lstart != -1)
+ {
+ int lend = sb.indexOf("}", lstart + 2);
+ if (lend > 0)
+ {
+ String token = sb.substring(lstart, lend + 1);
+ replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version));
+ }
+ lstart = sb.indexOf("${", lstart);
+ }
+ }
+
+ protected static void writeTargetFile(StringBuffer sb, File f)
+ {
+ try
+ {
+ f.getParentFile().mkdirs();
+ FileWriter fw = new FileWriter(f);
+ fw.write(sb.toString().toCharArray());
+ fw.flush();
+ fw.close();
+ }
+ catch (IOException e)
+ {
+ throw new AmqpTemplateException(e.getMessage());
+ }
+ }
+
+
+ protected static String getTemplateFileName(StringBuffer sb)
+ {
+ if (sb.charAt(0) != '&')
+ {
+ throw new AmqpTemplateException("No filename marker &{filename} found at start of template.");
+ }
+ int cr = sb.indexOf(Utils.LINE_SEPARATOR);
+ if (cr < 0)
+ {
+ throw new AmqpTemplateException("Bad template structure - unable to find first line.");
+ }
+ String fileName = sb.substring(2, cr - 1);
+ sb.delete(0, cr + 1);
+ return fileName;
+ }
+
+ protected static void replaceToken(StringBuffer sb, String token, String replacement)
+ {
+ replaceToken(sb, 0, token, replacement);
+ }
+
+ protected static void replaceToken(StringBuffer sb, int index, String token, String replacement)
+ {
+ if (replacement != null)
+ {
+ int start = sb.indexOf(token, index);
+ if (start != -1)
+ {
+ int len = token.length();
+ // Find first letter in token and determine if it is capitalized
+ char firstTokenLetter = getFirstLetter(token);
+ if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter))
+ {
+ sb.replace(start, start + len, Utils.firstUpper(replacement));
+ }
+ else
+ {
+ sb.replace(start, start + len, replacement);
+ }
+ }
+ }
+ }
+
+ private static char getFirstLetter(String str)
+ {
+ int len = str.length();
+ int index = 0;
+ char tokChar = str.charAt(index);
+ while (!Character.isLetter(tokChar) && index < len - 1)
+ {
+ tokChar = str.charAt(++index);
+ }
+ if (Character.isLetter(tokChar))
+ {
+ return tokChar;
+ }
+ return 0;
+ }
+
+ private static String loadTemplate(File f)
+ {
+ try
+ {
+ StringBuffer sb = new StringBuffer();
+ FileReader fr = new FileReader(f);
+ LineNumberReader lnr = new LineNumberReader(fr);
+ String line = lnr.readLine();
+ while (line != null)
+ {
+
+ sb.append(line);
+ sb.append(Utils.LINE_SEPARATOR);
+
+ line = lnr.readLine();
+ }
+ lnr.close();
+ fr.close();
+ return sb.toString();
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new AmqpTemplateException("File not found: " + e.getMessage());
+ }
+ catch (IOException e)
+ {
+ throw new AmqpTemplateException("IOException: " + e.getMessage());
+ }
+ }
+
+ public String getDomainType(String domainName, AmqpVersion version)
+ {
+ if (version == null)
+ {
+ version = _versionSet.first();
+ }
+ return getDomainMap().getDomainType(domainName, version);
+ }
+
+
+ public void addFromNode(Node amqpNode, AmqpVersion version)
+ {
+ // 1c. Extract domains
+ getConstantSet().addFromNode(amqpNode, 0, version);
+ _versionToConstantSetMap.get(version).addFromNode(amqpNode, 0, version);
+
+ // 1d. Extract domains
+ getDomainMap().addFromNode(amqpNode, 0, version);
+ _versionToDomainMapMap.get(version).addFromNode(amqpNode, 0, version);
+
+ // 1e. Extract class/method/field heirarchy
+ getModel().addFromNode(amqpNode, 0, version);
+ _versionToModelMap.get(version).addFromNode(amqpNode, 0, version);
+ }
+
+
+ public String getOutputDirectory()
+ {
+ return _outputDirectory;
+ }
+
+ public String prepareConstantName(String constantName)
+ {
+ return prepareDomainName(constantName);
+ }
+
+
+ public boolean isFixedSizeType(String type)
+ {
+ return FIXED_SIZE_TYPES.containsKey(type);
+ }
+
+
+ public int getTypeSize(String type)
+ {
+ return FIXED_SIZE_TYPES.get(type);
+ }
+
+
+
+ // Model-level template processing
+ abstract protected void processModelTemplate(NamedTemplate template);
+
+ // Class-level template processing
+ abstract protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass);
+
+ // Method-level template processing
+ abstract protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method);
+
+ // Field-level template processing
+ abstract protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field, AmqpVersion version);
+
+ abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, AmqpVersion version);
+
+ abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, AmqpVersion version);
+
+ abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpModel model, AmqpVersion version);
+
+ abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpClass thisClass);
+
+
+ abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpFieldMap fieldMap, AmqpVersion version);
+
+ abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpConstantSet constantSet);
+
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/java/common/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
new file mode 100644
index 0000000000..7730fca1bd
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
@@ -0,0 +1,1826 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+public class JavaGenerator extends Generator
+{
+ // TODO: Move this to parent class
+ protected static final int FIELD_NAME = 0;
+ protected static final int FIELD_CODE_TYPE = 1;
+
+ private class DomainInfo
+ {
+ final public String type;
+ final public String size;
+ final public String encodingType;
+ final public String encodeExpression;
+ final public String decodeExpression;
+
+ public DomainInfo(String domain, String size, String encodingType, String encodeExpression, String decodeExpression)
+ {
+ this.type = domain;
+ this.size = size;
+ this.encodeExpression = encodeExpression;
+ this.decodeExpression = decodeExpression;
+ this.encodingType = encodingType;
+ }
+ }
+
+ private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>();
+
+ // Methods used for generation of code snippets called from the field map parsers
+
+ // Common methods
+ private final CommandGenerateMethod declarationGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateFieldDeclaration(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+
+ private MangledGenerateMethod mangledDeclarationGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMangledFieldDeclaration(field, indentSize, tabSize, notLast);
+ }
+ };
+
+ // Methods for MessageBody classes
+ private CommandGenerateMethod mbGetGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); //To change body of implemented methods use File | Settings | File Templates.
+ }
+ };
+
+ private MangledGenerateMethod mbMangledGetGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbMangledGetMethod(field, indentSize, tabSize, notLast);
+ }
+ };
+ private CommandGenerateMethod mbParamListGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbParamList(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private CommandGenerateMethod mbPassedParamListGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbPassedParamList(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod mbMangledParamListGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbMangledParamList(field, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod mbMangledPassedParamListGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbMangledPassedParamList(field, indentSize, tabSize, notLast);
+ }
+ };
+ private CommandGenerateMethod mbBodyInitGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbBodyInit(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod mbMangledBodyInitGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generateMbMangledBodyInit(field, indentSize, tabSize, notLast);
+ }
+ };
+ private GenerateMethod mbSizeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbFieldSize(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod mbBitSizeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod mbEncodeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod mbBitEncodeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod mbDecodeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod mbBitDecodeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod mbToStringGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbFieldToString(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod mbBitToStringGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generateMbBitFieldToString(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+
+ // Methods for PropertyContentHeader classes
+ private CommandGenerateMethod pchClearGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchClearMethod(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod pchMangledClearGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchMangledClearMethod(field, indentSize, tabSize, notLast);
+ }
+ };
+ private CommandGenerateMethod pchGetGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod pchMangledGetGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchMangledGetMethod(field, indentSize, tabSize, notLast);
+ }
+ };
+ private CommandGenerateMethod pchSetGenerateMethod = new CommandGenerateMethod()
+ {
+ public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchSetMethod(codeType, field, versionSet, indentSize, tabSize, notLast);
+ }
+ };
+ private MangledGenerateMethod pchMangledSetGenerateMethod = new MangledGenerateMethod()
+ {
+ public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast)
+ {
+ return generatePchMangledSetMethod(field, indentSize, tabSize, notLast);
+ }
+ };
+ private GenerateMethod pchSizeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchFieldSize(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod pchBitSizeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod pchEncodeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod pchBitEncodeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod pchDecodeGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod pchBitDecodeGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod pchGetPropertyFlagsGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchGetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod pchBitGetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchBitGetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+ private GenerateMethod pchSetPropertyFlagsGenerateMethod = new GenerateMethod()
+ {
+ public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchSetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize);
+ }
+ };
+ private BitFieldGenerateMethod pchBitSetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod()
+ {
+ public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize)
+ {
+ return generatePchBitSetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize);
+ }
+ };
+
+
+ public String getNativeType(String type)
+ {
+ return typeMap.get(type).type;
+ }
+
+ public String getEncodingType(String type)
+ {
+ return typeMap.get(type).encodingType;
+ }
+
+
+ public JavaGenerator()
+ {
+ super();
+ // Load Java type and size maps.
+ // Adjust or add to these lists as new types are added/defined.
+ // The char '#' will be replaced by the field variable name (any type).
+ // The char '~' will be replaced by the compacted bit array size (type bit only).
+ typeMap.put("bit", new DomainInfo(
+ "boolean", // Java code type
+ "~", // size
+ "Boolean", // Java code type
+ "EncodingUtils.writeBooleans(buffer, #)", // encode expression
+ "# = EncodingUtils.readBooleans(buffer)")); // decode expression
+ typeMap.put("bitfield", new DomainInfo(
+ "byte", // Java code type
+ "~", // size
+ "Bitfield",
+ "EncodingUtils.writeBooleans(buffer, #)", // encode expression
+ "# = EncodingUtils.readBooleans(buffer)")); // decode expression
+
+ typeMap.put("content", new DomainInfo(
+ "Content", // Java code type
+ "EncodingUtils.encodedContentLength(#)", // size
+ "Content", // Java code type
+ "EncodingUtils.writeContentBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readContent(buffer)")); // decode expression
+ typeMap.put("long", new DomainInfo(
+ "long", // Java code type
+ "4", // size
+ "UnsignedInteger", // Java code type
+ "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression
+ "# = buffer.getUnsignedInt()")); // decode expression
+ typeMap.put("longlong", new DomainInfo(
+ "long", // Java code type
+ "8", // size
+ "Long",
+ "buffer.putLong(#)", // encode expression
+ "# = buffer.getLong()")); // decode expression
+ typeMap.put("longstr", new DomainInfo(
+ "byte[]", // Java code type
+ "EncodingUtils.encodedLongstrLength(#)", // size
+ "Bytes",
+ "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readLongstr(buffer)")); // decode expression
+ typeMap.put("octet", new DomainInfo(
+ "short", // Java code type
+ "1", // size
+ "UnsignedByte",
+ "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression
+ "# = buffer.getUnsigned()")); // decode expression
+ typeMap.put("short", new DomainInfo(
+ "int", // Java code type
+ "2", // size
+ "UnsignedShort",
+ "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression
+ "# = buffer.getUnsignedShort()")); // decode expression
+ typeMap.put("shortstr", new DomainInfo(
+ "AMQShortString", // Java code type
+ "EncodingUtils.encodedShortStringLength(#)", // size
+ "AMQShortString", // Java code type
+ "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression
+ typeMap.put("table", new DomainInfo(
+ "FieldTable", // Java code type
+ "EncodingUtils.encodedFieldTableLength(#)", // size
+ "FieldTable", // Java code type
+ "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readFieldTable(buffer)")); // decode expression
+ typeMap.put("timestamp", new DomainInfo(
+ "long", // Java code type
+ "8", // size
+ "Timestamp",
+ "EncodingUtils.writeTimestamp(buffer, #)", // encode expression
+ "# = EncodingUtils.readTimestamp(buffer)")); // decode expression
+ }
+
+ // === Start of methods for Interface LanguageConverter ===
+
+ public String prepareClassName(String className)
+ {
+ return camelCaseName(className, true);
+ }
+
+ public String prepareMethodName(String methodName)
+ {
+ return camelCaseName(methodName, false);
+ }
+
+ public String prepareDomainName(String domainName)
+ {
+ return camelCaseName(domainName, false);
+ }
+
+
+ public String getGeneratedType(String domainName, AmqpVersion version)
+ {
+ String domainType = getDomainType(domainName, version);
+ if (domainType == null)
+ {
+ throw new AmqpTypeMappingException("Domain type \"" + domainName +
+ "\" not found in Java typemap.");
+ }
+ DomainInfo info = typeMap.get(domainType);
+ if (info == null)
+ {
+ throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\"");
+ }
+ return info.type;
+ }
+
+ // === Abstract methods from class Generator - Java-specific implementations ===
+
+ @Override
+ protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, AmqpVersion version)
+ {
+ StringBuffer sb = new StringBuffer(filenameTemplate);
+ if (thisClass != null)
+ {
+ replaceToken(sb, "${CLASS}", thisClass.getName());
+ }
+ if (method != null)
+ {
+ replaceToken(sb, "${METHOD}", method.getName());
+ }
+ if (field != null)
+ {
+ replaceToken(sb, "${FIELD}", field.getName());
+ }
+ if (version != null)
+ {
+ replaceToken(sb, "${MAJOR}", String.valueOf(version.getMajor()));
+ replaceToken(sb, "${MINOR}", String.valueOf(version.getMinor()));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected void processModelTemplate(NamedTemplate template)
+ {
+ processTemplate(template, null, null, null, null);
+ }
+
+ @Override
+ protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass)
+ {
+ processTemplate(template, thisClass, null, null,
+ thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null);
+ }
+
+ @Override
+ protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method)
+ {
+ processTemplate(template, thisClass, method, null,
+ thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null);
+ }
+
+ protected void processFieldTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field)
+ {
+ processTemplate(template, thisClass, method, field,
+ thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null);
+ }
+
+ @Override
+ protected void processTemplate(NamedTemplate template, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field, AmqpVersion version)
+ {
+ StringBuffer sb = new StringBuffer(template.getTemplate());
+ String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version);
+ processTemplate(sb, thisClass, method, field, template.getName(), version);
+ writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename));
+ generatedFileCounter++;
+ }
+
+ protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method,
+ AmqpField field, String templateFileName, AmqpVersion version)
+ {
+ try
+ {
+ processAllLists(sb, thisClass, method, version);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + templateFileName + ": " + e.getMessage());
+ }
+ try
+ {
+ processAllTokens(sb, thisClass, method, field, version);
+ }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + templateFileName + ": " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field,
+ AmqpVersion version)
+ {
+ if (token.compareTo("${GENERATOR}") == 0)
+ {
+ return GENERATOR_INFO;
+ }
+ if (token.compareTo("${CLASS}") == 0 && thisClass != null)
+ {
+ return thisClass.getName();
+ }
+ if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null)
+ {
+ return generateIndexInitializer("registerClassId", thisClass.getIndexMap(), 8);
+ }
+ if (token.compareTo("${METHOD}") == 0 && method != null)
+ {
+ return method.getName();
+ }
+ if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null)
+ {
+ return generateIndexInitializer("registerMethodId", method.getIndexMap(), 8);
+ }
+ if (token.compareTo("${FIELD}") == 0 && field != null)
+ {
+ return field.getName();
+ }
+
+ // This token is used only with class or method-level templates
+ if (token.compareTo("${pch_property_flags_declare}") == 0)
+ {
+ return generatePchPropertyFlagsDeclare();
+ }
+ else if (token.compareTo("${pch_property_flags_initializer}") == 0)
+ {
+ int mapSize = method == null ? thisClass.getFieldMap().size() : method.getFieldMap().size();
+ return generatePchPropertyFlagsInitializer(mapSize);
+ }
+ else if (token.compareTo("${pch_compact_property_flags_initializer}") == 0)
+ {
+ return generatePchCompactPropertyFlagsInitializer(thisClass, 8, 4);
+ }
+ else if (token.compareTo("${pch_compact_property_flags_check}") == 0)
+ {
+ return generatePchCompactPropertyFlagsCheck(thisClass, 8, 4);
+ }
+
+ // Oops!
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+
+ @Override
+ protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpModel model, AmqpVersion version)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ if (token.compareTo("${reg_map_put_method}") == 0)
+ {
+ codeSnippet = generateRegistry(model, 8, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpClass thisClass)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ //TODO - we don't have any cases of this (yet).
+ if (token.compareTo("${???}") == 0)
+ {
+ codeSnippet = token;
+ }
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpFieldMap fieldMap, AmqpVersion version)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // Field declarations - common to MethodBody and PropertyContentHeader classes
+ if (token.compareTo("${field_declaration}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod,
+ mangledDeclarationGenerateMethod, 4, 4, this);
+ }
+
+ // MethodBody classes
+ else if (token.compareTo("${mb_field_get_method}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod,
+ mbMangledGetGenerateMethod, 4, 4, this);
+ }
+ else if (token.compareTo("${mb_field_parameter_list}") == 0)
+ {
+ // <cringe> The code generated by this is ugly... It puts a comma on a line by itself!
+ // TODO: Find a more elegant solution here sometime...
+ codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + CR : "";
+ // </cringe>
+ codeSnippet += fieldMap.parseFieldMap(mbParamListGenerateMethod,
+ mbMangledParamListGenerateMethod, 42, 4, this);
+ }
+
+ else if (token.compareTo("${mb_field_passed_parameter_list}") == 0)
+ {
+ // <cringe> The code generated by this is ugly... It puts a comma on a line by itself!
+ // TODO: Find a more elegant solution here sometime...
+ codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + CR : "";
+ // </cringe>
+ codeSnippet += fieldMap.parseFieldMap(mbPassedParamListGenerateMethod,
+ mbMangledPassedParamListGenerateMethod, 42, 4, this);
+ }
+ else if (token.compareTo("${mb_field_body_initialize}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(mbBodyInitGenerateMethod,
+ mbMangledBodyInitGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${mb_field_size}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(mbSizeGenerateMethod,
+ mbBitSizeGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${mb_field_encode}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(mbEncodeGenerateMethod,
+ mbBitEncodeGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${mb_field_decode}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(mbDecodeGenerateMethod,
+ mbBitDecodeGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${mb_field_to_string}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(mbToStringGenerateMethod,
+ mbBitToStringGenerateMethod, 8, 4, this);
+ }
+
+ // PropertyContentHeader classes
+ else if (token.compareTo("${pch_field_list_size}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(pchSizeGenerateMethod,
+ pchBitSizeGenerateMethod, 12, 4, this);
+ }
+ else if (token.compareTo("${pch_field_list_payload}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(pchEncodeGenerateMethod,
+ pchBitEncodeGenerateMethod, 12, 4, this);
+ }
+ else if (token.compareTo("${pch_field_list_decode}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(pchDecodeGenerateMethod,
+ pchBitDecodeGenerateMethod, 12, 4, this);
+ }
+ else if (token.compareTo("${pch_get_compact_property_flags}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(pchGetPropertyFlagsGenerateMethod,
+ pchBitGetPropertyFlagsGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${pch_set_compact_property_flags}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMapOrdinally(pchSetPropertyFlagsGenerateMethod,
+ pchBitSetPropertyFlagsGenerateMethod, 8, 4, this);
+ }
+ else if (token.compareTo("${pch_field_clear_methods}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(pchClearGenerateMethod,
+ pchMangledClearGenerateMethod, 4, 4, this);
+ }
+ else if (token.compareTo("${pch_field_get_methods}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(pchGetGenerateMethod,
+ pchMangledGetGenerateMethod, 4, 4, this);
+ }
+ else if (token.compareTo("${pch_field_set_methods}") == 0)
+ {
+ codeSnippet = fieldMap.parseFieldMap(pchSetGenerateMethod,
+ pchMangledSetGenerateMethod, 4, 4, this);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpConstantSet constantSet)
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ if (token.compareTo("${const_get_method}") == 0)
+ {
+ codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ // === Protected and private helper functions unique to Java implementation ===
+
+ // Methods used for generation of code snippets called from the field map parsers
+
+ // Common methods
+
+ protected String generateFieldDeclaration(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ return Utils.createSpaces(indentSize) + "public " + codeType + " " + field.getName() +
+ "; // AMQP version(s): " + versionSet + CR;
+ }
+
+ protected String generateMangledFieldDeclaration(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ StringBuffer sb = new StringBuffer();
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = getGeneratedType(domainName, versionSet.first());
+ sb.append(Utils.createSpaces(indentSize) + "public " + codeType + " " +
+ field.getName() + "_" + (domainCntr++) + "; // AMQP Version(s): " + versionSet +
+ CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, int indentSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ Iterator<Integer> iItr = indexMap.keySet().iterator();
+ while (iItr.hasNext())
+ {
+ int index = iItr.next();
+ AmqpVersionSet versionSet = indexMap.get(index);
+ Iterator<AmqpVersion> vItr = versionSet.iterator();
+ while (vItr.hasNext())
+ {
+ AmqpVersion version = vItr.next();
+ sb.append(indent + mapName + "( (byte) " + version.getMajor() + ", (byte) " + version.getMinor() + ", " + index + ");" + CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateRegistry(AmqpModel model, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (String className : model.getClassMap().keySet())
+ {
+ AmqpClass thisClass = model.getClassMap().get(className);
+ for (String methodName : thisClass.getMethodMap().keySet())
+ {
+ AmqpMethod method = thisClass.getMethodMap().get(methodName);
+ for (AmqpVersion version : model.getVersionSet())
+ {
+ // Find class and method index for this version (if it exists)
+ try
+ {
+ int classIndex = findIndex(thisClass.getIndexMap(), version);
+ int methodIndex = findIndex(method.getIndexMap(), version);
+ sb.append(indent + "registerMethod(" + CR);
+ sb.append(indent + tab + "(short)" + classIndex +
+ ", (short)" + methodIndex + ", (byte)" + version.getMajor() +
+ ", (byte)" + version.getMinor() + ", " + CR);
+ sb.append(indent + tab + Utils.firstUpper(thisClass.getName()) +
+ Utils.firstUpper(method.getName()) + "Body.getFactory());" + CR);
+ }
+ catch (Exception e)
+ {
+ } // Ignore
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ protected int findIndex(TreeMap<Integer, AmqpVersionSet> map, AmqpVersion version)
+ {
+ Iterator<Integer> iItr = map.keySet().iterator();
+ while (iItr.hasNext())
+ {
+ int index = iItr.next();
+ AmqpVersionSet versionSet = map.get(index);
+ if (versionSet.contains(version))
+ {
+ return index;
+ }
+ }
+ throw new IllegalArgumentException("Index not found");
+ }
+
+ // Methods for AmqpConstants class
+
+
+ public String prepareConstantName(String constantName)
+ {
+ return upperCaseName(constantName);
+ }
+
+
+ protected String generateConstantGetMethods(AmqpConstantSet constantSet,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (AmqpConstant constant : constantSet.getContstants())
+ {
+
+ if (constant.isVersionConsistent(constantSet.getVersionSet()))
+ {
+ // return a constant
+ String value = constant.firstKey();
+ if (Utils.containsOnlyDigits(value))
+ {
+ sb.append(indent + "public static final int " + constant.getName() + " = " +
+ constant.firstKey() + ";" + CR);
+ }
+ else if (Utils.containsOnlyDigitsAndDecimal(value))
+ {
+ sb.append(indent + "public static double " + constant.getName() + " = " +
+ constant.firstKey() + "; " + CR);
+ }
+ else
+ {
+ sb.append(indent + "public static String " + constant.getName() + " = " +
+ constant.firstKey() + "\"; " + CR);
+
+ }
+ sb.append(CR);
+ }
+ else
+ {
+ // Return version-specific constant
+ sb.append(generateVersionDependentGet(constant, "String", "", "\"", "\"", indentSize, tabSize));
+ sb.append(generateVersionDependentGet(constant, "int", "AsInt", "", "", indentSize, tabSize));
+ sb.append(generateVersionDependentGet(constant, "double", "AsDouble", "(double)", "", indentSize, tabSize));
+ sb.append(CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateVersionDependentGet(AmqpConstant constant,
+ String methodReturnType, String methodNameSuffix, String returnPrefix, String returnPostfix,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "public static " + methodReturnType + " " + constant.getName() +
+ methodNameSuffix + "(byte major, byte minor) throws AMQProtocolVersionException" + CR);
+ sb.append(indent + "{" + CR);
+ boolean first = true;
+ Iterator<String> sItr = constant.keySet().iterator();
+ while (sItr.hasNext())
+ {
+ String value = sItr.next();
+ AmqpVersionSet versionSet = constant.get(value);
+ sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) +
+ ")" + CR);
+ sb.append(indent + tab + "{" + CR);
+ if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(value))
+ {
+ sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
+ indentSize + (2 * tabSize), tabSize));
+ }
+ else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value))
+ {
+ sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
+ indentSize + (2 * tabSize), tabSize));
+ }
+ else
+ {
+ sb.append(indent + tab + tab + "return " + returnPrefix + value + returnPostfix + ";" + CR);
+ }
+ sb.append(indent + tab + "}" + CR);
+ first = false;
+ }
+ sb.append(indent + tab + "else" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "throw new AMQProtocolVersionException(\"Constant \\\"" +
+ constant.getName() + "\\\" \" +" + CR);
+ sb.append(indent + tab + tab + tab +
+ "\"is undefined for AMQP version \" + major + \"-\" + minor + \".\");" + CR);
+ sb.append(indent + tab + "}" + CR);
+ sb.append(indent + "}" + CR);
+ return sb.toString();
+ }
+
+ protected String generateConstantDeclarationException(String name, String methodReturnType,
+ int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "throw new AMQProtocolVersionException(\"Constant \\\"" +
+ name + "\\\" \" +" + CR);
+ sb.append(indent + tab + "\"cannot be converted to type " + methodReturnType +
+ " for AMQP version \" + major + \"-\" + minor + \".\");" + CR);
+ return sb.toString();
+ }
+
+ // Methods for MessageBody classes
+ protected String generateMbGetMethod(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ return Utils.createSpaces(indentSize) + "public " + codeType + " get" +
+ Utils.firstUpper(field.getName()) + "() { return " + field.getName() + "; }" +
+ CR;
+ }
+
+ protected String generateMbMangledGetMethod(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer(CR);
+ sb.append(indent + "public <T> T get" + Utils.firstUpper(field.getName()) +
+ "(Class<T> classObj) throws AMQProtocolVersionException" + CR);
+ sb.append(indent + "{" + CR);
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = getGeneratedType(domainName, versionSet.first());
+ sb.append(indent + tab + "if (classObj.equals(" + codeType +
+ ".class)) // AMQP Version(s): " + versionSet + CR);
+ sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" +
+ (domainCntr++) + ";" + CR);
+ }
+ sb.append(indent + tab +
+ "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" +
+ CR + " \"field \\\"" + field.getName() +
+ "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generateMbParamList(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ return Utils.createSpaces(indentSize) + codeType + " " + field.getName() +
+ (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR;
+ }
+
+
+ protected String generateMbPassedParamList(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ return Utils.createSpaces(indentSize) + field.getName() +
+ (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR;
+ }
+
+
+ protected String generateMbMangledParamList(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ StringBuffer sb = new StringBuffer();
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = getGeneratedType(domainName, versionSet.first());
+ sb.append(Utils.createSpaces(indentSize) + codeType + " " + field.getName() + "_" +
+ (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " +
+ versionSet + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateMbMangledPassedParamList(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ StringBuffer sb = new StringBuffer();
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ sb.append(Utils.createSpaces(indentSize) + field.getName() + "_" +
+ (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " +
+ versionSet + CR);
+ }
+ return sb.toString();
+ }
+
+
+ protected String generateMbBodyInit(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ return Utils.createSpaces(indentSize) + "this." + field.getName() + " = " + field.getName() +
+ ";" + CR;
+ }
+
+ protected String generateMbMangledBodyInit(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ StringBuffer sb = new StringBuffer();
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ dItr.next();
+ sb.append(Utils.createSpaces(indentSize) + "this." + field.getName() + "_" + domainCntr +
+ " = " + field.getName() + "_" + (domainCntr++) + ";" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateMbFieldSize(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(Utils.createSpaces(indentSize) + "size += " +
+ typeMap.get(domainType).size.replaceAll("#", fieldName) +
+ "; // " + fieldName + ": " + domainType + CR);
+ return sb.toString();
+ }
+
+ protected String generateMbBitArrayFieldSize(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ int numBytes = ((bitFieldList.size() - 1) / 8) + 1;
+ String comment = bitFieldList.size() == 1 ?
+ bitFieldList.get(0) + ": bit" :
+ "Combinded bits: " + bitFieldList;
+ sb.append(Utils.createSpaces(indentSize) + "size += " +
+ typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) +
+ "; // " + comment + CR);
+ return sb.toString();
+ }
+
+ protected String generateMbFieldEncode(String domain, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(Utils.createSpaces(indentSize) +
+ typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) +
+ "; // " + fieldName + ": " + domain + CR);
+ return sb.toString();
+ }
+
+ protected String generateMbBitFieldEncode(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ while (i < bitFieldList.size())
+ {
+
+ StringBuilder line = new StringBuilder();
+
+ for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++)
+ {
+ if (j != 0)
+ {
+ line.append(", ");
+ }
+ line.append(bitFieldList.get(i));
+ }
+
+ sb.append(indent +
+ typeMap.get("bit").encodeExpression.replaceAll("#", line.toString()) + ";" + CR);
+ }
+ return sb.toString();
+ }
+
+ protected String generateMbFieldDecode(String domain, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(Utils.createSpaces(indentSize) +
+ typeMap.get(domain).decodeExpression.replaceAll("#", fieldName) +
+ "; // " + fieldName + ": " + domain + CR);
+ return sb.toString();
+ }
+
+ protected String generateMbBitFieldDecode(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+
+ StringBuilder sb = new StringBuilder(indent);
+ sb.append("byte packedValue;");
+ sb.append(CR);
+
+ // RG HERE!
+
+ int i = 0;
+ while (i < bitFieldList.size())
+ {
+ sb.append(indent + "packedValue = EncodingUtils.readByte(buffer);" + CR);
+
+ for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++)
+ {
+ sb.append(indent + bitFieldList.get(i) + " = ( packedValue & (byte) (1 << " + j + ") ) != 0;" + CR);
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generateMbFieldToString(String domain, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(Utils.createSpaces(indentSize) +
+ "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + CR);
+ return sb.toString();
+ }
+
+ protected String generateMbBitFieldToString(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ String bitFieldName = bitFieldList.get(i);
+ sb.append(indent + "buf.append(\" " + bitFieldName + ": \" + " + bitFieldName +
+ ");" + CR);
+ }
+ return sb.toString();
+ }
+
+ // Methods for PropertyContentHeader classes
+
+ protected String generatePchClearMethod(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ // This is one case where the ordinal info is the only significant factor,
+ // the domain info plays no part. Defer to the mangled version; the code would be
+ // identical anyway...
+ return generatePchMangledClearMethod(field, indentSize, tabSize, nextFlag);
+ }
+
+ protected String generatePchMangledClearMethod(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "public void clear" + Utils.firstUpper(field.getName()) +
+ "()" + CR);
+ sb.append(indent + "{" + CR);
+
+ // If there is more than one ordinal for this field or the ordinal does not
+ // apply to all known versions, then we need to generate version checks so
+ // we know which fieldProperty to clear.
+ if (field.getOrdinalMap().size() == 1 &&
+ field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size())
+ {
+ int ordinal = field.getOrdinalMap().firstKey();
+ sb.append(indent + tab + "clearEncodedForm();" + CR);
+ sb.append(indent + tab + "propertyFlags[" + ordinal + "] = false;" + CR);
+ }
+ else
+ {
+ Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator();
+ while (oItr.hasNext())
+ {
+ int ordinal = oItr.next();
+ AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal);
+ sb.append(indent + tab);
+ if (ordinal != field.getOrdinalMap().firstKey())
+ {
+ sb.append("else ");
+ }
+ sb.append("if (");
+ sb.append(generateVersionCheck(versionSet));
+ sb.append(")" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "clearEncodedForm();" + CR);
+ sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = false;" + CR);
+ sb.append(indent + tab + "}" + CR);
+ }
+ }
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchGetMethod(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer(indent + "public " + codeType + " get" +
+ Utils.firstUpper(field.getName()) + "()" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "decodeIfNecessary();" + CR);
+ sb.append(indent + tab + "return " + field.getName() + ";" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchMangledGetMethod(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer(indent + "public <T> T get" +
+ Utils.firstUpper(field.getName()) +
+ "(Class<T> classObj) throws AMQProtocolVersionException" + CR);
+ sb.append(indent + "{" + CR);
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = getGeneratedType(domainName, versionSet.first());
+ sb.append(indent + tab + "if (classObj.equals(" + codeType +
+ ".class)) // AMQP Version(s): " + versionSet + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "decodeIfNecessary();" + CR);
+ sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" +
+ (domainCntr++) + ";" + CR);
+ sb.append(indent + tab + "}" + CR);
+ }
+ sb.append(indent + tab +
+ "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" +
+ CR + " \"field \\\"" + field.getName() +
+ "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchSetMethod(String codeType, AmqpField field,
+ AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) +
+ "(" + codeType + " " + field.getName() + ")" + CR);
+ sb.append(indent + "{" + CR);
+
+ // If there is more than one ordinal for this field or the ordinal does not
+ // apply to all known versions, then we need to generate version checks so
+ // we know which fieldProperty to clear.
+ if (field.getOrdinalMap().size() == 1 &&
+ field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size())
+ {
+ int ordinal = field.getOrdinalMap().firstKey();
+ sb.append(indent + tab + "clearEncodedForm();" + CR);
+ sb.append(indent + tab + "propertyFlags[" + ordinal + "] = true;" + CR);
+ sb.append(indent + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR);
+ }
+ else
+ {
+ Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator();
+ while (oItr.hasNext())
+ {
+ int ordinal = oItr.next();
+ AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal);
+ sb.append(indent + tab);
+ if (ordinal != field.getOrdinalMap().firstKey())
+ {
+ sb.append("else ");
+ }
+ sb.append("if (");
+ sb.append(generateVersionCheck(oVersionSet));
+ sb.append(")" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "clearEncodedForm();" + CR);
+ sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR);
+ sb.append(indent + tab + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR);
+ sb.append(indent + tab + "}" + CR);
+ }
+ }
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchMangledSetMethod(AmqpField field, int indentSize,
+ int tabSize, boolean nextFlag)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+
+ Iterator<String> dItr = field.getDomainMap().keySet().iterator();
+ int domainCntr = 0;
+ while (dItr.hasNext())
+ {
+ String domainName = dItr.next();
+ AmqpVersionSet versionSet = field.getDomainMap().get(domainName);
+ String codeType = getGeneratedType(domainName, versionSet.first());
+
+ // Find ordinal with matching version
+ AmqpVersionSet commonVersionSet = new AmqpVersionSet();
+ Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator();
+ while (oItr.hasNext())
+ {
+ int ordinal = oItr.next();
+ AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal);
+ Iterator<AmqpVersion> vItr = oVersionSet.iterator();
+ boolean first = true;
+ while (vItr.hasNext())
+ {
+ AmqpVersion thisVersion = vItr.next();
+ if (versionSet.contains(thisVersion))
+ {
+ commonVersionSet.add(thisVersion);
+ }
+ }
+ if (!commonVersionSet.isEmpty())
+ {
+ sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) +
+ "(" + codeType + " " + field.getName() + ")" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab);
+ if (!first)
+ {
+ sb.append("else ");
+ }
+ sb.append("if (");
+ sb.append(generateVersionCheck(commonVersionSet));
+ sb.append(")" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "clearEncodedForm();" + CR);
+ sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR);
+ sb.append(indent + tab + tab + "this." + field.getName() + "_" + (domainCntr++) +
+ " = " + field.getName() + ";" + CR);
+ sb.append(indent + tab + "}" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(CR);
+ first = false;
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ protected String generatePchFieldSize(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer(indent + "if (propertyFlags[" + ordinal + "]) // " +
+ fieldName + ": " + domainType + CR);
+ sb.append(indent + Utils.createSpaces(tabSize) + "size += " +
+ typeMap.get(domainType).size.replaceAll("#", fieldName) + ";" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchBitArrayFieldSize(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ String comment = bitFieldList.size() == 1 ?
+ bitFieldList.get(0) + ": bit" :
+ "Combinded bits: " + bitFieldList;
+ StringBuffer sb = new StringBuffer();
+
+ if (bitFieldList.size() == 1) // single bit
+ {
+ sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + comment + CR);
+ sb.append(indent + tab + "size += " +
+ typeMap.get("bit").size.replaceAll("~", "1") + ";" + CR);
+ }
+ else // multiple bits - up to 8 are combined into one byte
+ {
+ String bitCntrName = "bitCntr_" + ordinal;
+ int startOrdinal = ordinal - bitFieldList.size();
+ sb.append(indent + "// " + comment + CR);
+ sb.append(indent + "int " + bitCntrName + " = 0;" + CR);
+ sb.append(indent + "for (int i=" + startOrdinal + "; i<" + ordinal + "; i++)" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "if (propertyFlags[i])" + CR);
+ sb.append(indent + tab + tab + bitCntrName + "++;" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(indent + "size += " +
+ typeMap.get("bit").size.replaceAll("~", bitCntrName +
+ " > 0 ? ((" + bitCntrName + " - 1) / 8) + 1 : 0") + ";" + CR);
+ }
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchFieldEncode(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " +
+ domainType + CR);
+ sb.append(indent + Utils.createSpaces(tabSize) +
+ typeMap.get(domainType).encodeExpression.replaceAll("#", fieldName) + ";" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchBitFieldEncode(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ String comment = bitFieldList.size() == 1 ?
+ bitFieldList.get(0) + ": bit" :
+ "Combinded bits: " + bitFieldList;
+ StringBuffer sb = new StringBuffer();
+
+ if (bitFieldList.size() == 1) // single bit
+ {
+ sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " +
+ bitFieldList.get(0) + ": bit" + CR);
+ sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#",
+ "new boolean[] {" + bitFieldList.get(0) + "}") + ";" + CR);
+ }
+ else // multiple bits - up to 8 are combined into one byte
+ {
+ int startOrdinal = ordinal - bitFieldList.size();
+ String bitCntrName = "bitCntr" + startOrdinal;
+ sb.append(indent + "// " + comment + CR);
+ sb.append(indent + "int " + bitCntrName + " = 0;" + CR);
+ sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "if (propertyFlags[i])" + CR);
+ sb.append(indent + tab + tab + bitCntrName + "++;" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(indent + "if (" + bitCntrName + " > 0) // Are any of the property bits set?" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "boolean[] fullBitArray = new boolean[] { ");
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ if (i != 0)
+ {
+ sb.append(", ");
+ }
+ sb.append(bitFieldList.get(i));
+ }
+ sb.append(" };" + CR);
+ sb.append(indent + tab + "boolean[] flaggedBitArray = new boolean[" + bitCntrName +
+ "];" + CR);
+ sb.append(indent + tab + bitCntrName + " = 0;" + CR);
+ sb.append(indent + tab + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) +
+ "; i++)" + CR);
+ sb.append(indent + tab + "{" + CR);
+ sb.append(indent + tab + tab + "if (propertyFlags[i])" + CR);
+ sb.append(indent + tab + tab + tab + "flaggedBitArray[" + bitCntrName +
+ "++] = fullBitArray[i];" + CR);
+ sb.append(indent + tab + "}" + CR);
+ sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#",
+ "flaggedBitArray") + ";" + CR);
+ sb.append(indent + "}" + CR);
+ }
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchFieldDecode(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " +
+ domainType + CR);
+ sb.append(indent + Utils.createSpaces(tabSize) +
+ typeMap.get(domainType).decodeExpression.replaceAll("#", fieldName) + ";" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchBitFieldDecode(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ String comment = bitFieldList.size() == 1 ?
+ bitFieldList.get(0) + ": bit" :
+ "Combinded bits: " + bitFieldList;
+ StringBuffer sb = new StringBuffer();
+
+ if (bitFieldList.size() == 1) // single bit
+ {
+ sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " +
+ bitFieldList.get(0) + ": bit" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#",
+ "boolean[] flaggedBitArray") + ";" + CR);
+ sb.append(indent + tab + bitFieldList.get(0) + " = flaggedBitArray[0];" + CR);
+ sb.append(indent + "}" + CR);
+ }
+ else // multiple bits - up to 8 are combined into one byte
+ {
+ int startOrdinal = ordinal - bitFieldList.size();
+ String bitCntr = "bitCntr" + startOrdinal;
+ sb.append(indent + "// " + comment + CR);
+ sb.append(indent + "int " + bitCntr + " = 0;" + CR);
+ sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + "if (propertyFlags[i])" + CR);
+ sb.append(indent + tab + tab + bitCntr + "++;" + CR);
+ sb.append(indent + "}" + CR);
+ sb.append(indent + "if (" + bitCntr + " > 0) // Are any of the property bits set?" + CR);
+ sb.append(indent + "{" + CR);
+ sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#",
+ "boolean[] flaggedBitArray") + ";" + CR);
+ sb.append(indent + tab + bitCntr + " = 0;" + CR);
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ sb.append(indent + tab + "if (propertyFlags[" + (startOrdinal + i) + "])" + CR);
+ sb.append(indent + tab + tab + bitFieldList.get(i) + " = flaggedBitArray[" +
+ bitCntr + "++];" + CR);
+ }
+ sb.append(indent + "}" + CR);
+ }
+
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchGetPropertyFlags(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ int word = ordinal / 15;
+ int bit = 15 - (ordinal % 15);
+ sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " +
+ domainType + CR);
+ sb.append(indent + tab + "compactPropertyFlags[" + word + "] |= (1 << " +
+ bit + ");" + CR);
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchBitGetPropertyFlags(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ int startOrdinal = ordinal - bitFieldList.size();
+
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ int thisOrdinal = startOrdinal + i;
+ int word = thisOrdinal / 15;
+ int bit = 15 - (thisOrdinal % 15);
+ sb.append(indent + "if (propertyFlags[" + thisOrdinal + "])" + CR);
+ sb.append(indent + tab + "compactPropertyFlags[" + word +
+ "] |= (1 << " + bit + ");" + CR);
+ }
+
+ sb.append(CR);
+ return sb.toString();
+ }
+
+ protected String generatePchSetPropertyFlags(String domainType, String fieldName,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ int word = ordinal / 15;
+ int bit = 15 - (ordinal % 15);
+ sb.append(indent + "propertyFlags[" + ordinal + "] = (compactPropertyFlags[" +
+ word + "] & (1 << " + bit + ")) > 0;" + CR);
+ return sb.toString();
+ }
+
+ protected String generatePchBitSetPropertyFlags(List<String> bitFieldList,
+ int ordinal, int indentSize, int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ StringBuffer sb = new StringBuffer();
+ int startOrdinal = ordinal - bitFieldList.size();
+
+ for (int i = 0; i < bitFieldList.size(); i++)
+ {
+ int thisOrdinal = startOrdinal + i;
+ int word = thisOrdinal / 15;
+ int bit = 15 - (thisOrdinal % 15);
+ sb.append(indent + "propertyFlags[" + thisOrdinal + "] = (compactPropertyFlags[" +
+ word + "] & (1 << " + bit + ")) > 0;" + CR);
+ }
+ return sb.toString();
+ }
+
+ private String generatePchPropertyFlagsDeclare()
+ {
+ return "private boolean[] propertyFlags;";
+ }
+
+ private String generatePchPropertyFlagsInitializer(int totNumFields)
+ {
+ return "propertyFlags = new boolean[" + totNumFields + "];";
+ }
+
+ private String generatePchCompactPropertyFlagsInitializer(AmqpClass thisClass, int indentSize,
+ int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ Iterator<AmqpVersion> vItr = thisClass.getVersionSet().iterator();
+ while (vItr.hasNext())
+ {
+ AmqpVersion version = vItr.next();
+ int numBytes = ((thisClass.getFieldMap().getNumFields(version) - 1) / 15) + 1;
+
+ sb.append(indent);
+ if (!version.equals(thisClass.getVersionSet().first()))
+ {
+ sb.append("else ");
+ }
+ sb.append("if ( major == " + version.getMajor() + " && minor == " +
+ version.getMinor() + " )" + CR);
+ sb.append(indent + tab + "compactPropertyFlags = new int[] { ");
+ for (int i = 0; i < numBytes; i++)
+ {
+ if (i != 0)
+ {
+ sb.append(", ");
+ }
+ sb.append(i < numBytes - 1 ? "1" : "0"); // Set the "continue" flag where required
+ }
+ sb.append(" };" + CR);
+ }
+ return sb.toString();
+ }
+
+ private String generatePchCompactPropertyFlagsCheck(AmqpClass thisClass, int indentSize,
+ int tabSize)
+ {
+ String indent = Utils.createSpaces(indentSize);
+ String tab = Utils.createSpaces(tabSize);
+ StringBuffer sb = new StringBuffer();
+ Iterator<AmqpVersion> vItr = thisClass.getVersionSet().iterator();
+ while (vItr.hasNext())
+ {
+ AmqpVersion version = vItr.next();
+ int numFields = thisClass.getFieldMap().getNumFields(version);
+ int numBytes = ((numFields - 1) / 15) + 1;
+
+ sb.append(indent);
+ if (!version.equals(thisClass.getVersionSet().first()))
+ {
+ sb.append("else ");
+ }
+ sb.append("if ( major == " + version.getMajor() + " && minor == " +
+ version.getMinor() + " && compactPropertyFlags.length != " + numBytes + " )" + CR);
+ sb.append(indent + tab +
+ "throw new AMQProtocolVersionException(\"Property flag array size mismatch:\" +" + CR);
+ sb.append(indent + tab + tab + "\"(Size found: \" + compactPropertyFlags.length +" + CR);
+ sb.append(indent + tab + tab + "\") Version " + version + " has " + numFields +
+ " fields which requires an int array of size " + numBytes + ".\");" + CR);
+ }
+ return sb.toString();
+ }
+
+ private String generateVersionCheck(AmqpVersionSet v)
+ {
+ StringBuffer sb = new StringBuffer();
+ AmqpVersion[] versionArray = new AmqpVersion[v.size()];
+ v.toArray(versionArray);
+ for (int i = 0; i < versionArray.length; i++)
+ {
+ if (i != 0)
+ {
+ sb.append(" || ");
+ }
+ if (versionArray.length > 1)
+ {
+ sb.append("(");
+ }
+ sb.append("major == (byte)" + versionArray[i].getMajor() + " && minor == (byte)" +
+ versionArray[i].getMinor());
+ if (versionArray.length > 1)
+ {
+ sb.append(")");
+ }
+ }
+ return sb.toString();
+ }
+
+ private String camelCaseName(String name, boolean upperFirstFlag)
+ {
+ StringBuffer ccn = new StringBuffer();
+ String[] toks = name.split("[-_.\\ ]");
+ for (int i = 0; i < toks.length; i++)
+ {
+ StringBuffer b = new StringBuffer(toks[i]);
+ if (upperFirstFlag || i > 0)
+ {
+ b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0)));
+ }
+ ccn.append(b);
+ }
+ return ccn.toString();
+ }
+
+
+ private String upperCaseName(String name)
+ {
+ StringBuffer ccn = new StringBuffer();
+ String[] toks = name.split("[-_.\\ ]");
+ for (int i = 0; i < toks.length; i++)
+ {
+ if (i != 0)
+ {
+ ccn.append('_');
+ }
+ ccn.append(toks[i].toUpperCase());
+
+
+ }
+ return ccn.toString();
+ }
+
+
+ public static Factory<JavaGenerator> _factoryInstance = new Factory<JavaGenerator>()
+ {
+
+ public JavaGenerator newInstance()
+ {
+ return new JavaGenerator();
+ }
+ };
+
+ public static Factory<JavaGenerator> getFactory()
+ {
+ return _factoryInstance;
+ }
+
+
+ void processModelTemplate(NamedTemplate template, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java b/java/common/gentools/src/org/apache/qpid/gentools/LanguageConverter.java
index 0dd36fe1fe..5e692d86e7 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/LanguageConverter.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,32 +18,25 @@
* under the License.
*
*/
+package org.apache.qpid.gentools;
-package org.apache.qpid.server.configuration;
-
-public interface ConnectionConfig extends ConfiguredObject<ConnectionConfigType, ConnectionConfig>
+public interface LanguageConverter
{
- VirtualHostConfig getVirtualHost();
-
- String getAddress();
-
- Boolean isIncoming();
- Boolean isSystemConnection();
+// public AmqpDomainMap getDomainMap();
+// public AmqpConstantSet getConstantSet();
+// public AmqpModel getModel();
- Boolean isFederationLink();
+ //
+ public String prepareClassName(String className);
- String getAuthId();
+ public String prepareMethodName(String methodName);
- String getRemoteProcessName();
+ public String prepareDomainName(String domainName);
- Integer getRemotePID();
+ public String getDomainType(String domainName, AmqpVersion version);
- Integer getRemoteParentPID();
+ public String getGeneratedType(String domainName, AmqpVersion version);
- ConfigStore getConfigStore();
-
- Boolean isShadow();
-
- void mgmtClose();
-} \ No newline at end of file
+ public String prepareConstantName(String constantName);
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/Main.java b/java/common/gentools/src/org/apache/qpid/gentools/Main.java
new file mode 100644
index 0000000000..c0584f7ca7
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/Main.java
@@ -0,0 +1,301 @@
+/*
+ *
+ * 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.gentools;
+
+import org.apache.velocity.app.Velocity;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+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.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Properties;
+
+public class Main
+{
+ private static final String DEFAULT_OUTPUT_DIR = ".." + Utils.FILE_SEPARATOR + "gen";
+ private static final String DEFAULT_TEMPLATE_DIR_BASE = ".." + Utils.FILE_SEPARATOR;
+
+ private enum GeneratedLanguage
+ {
+ CPP(".cpp", CppGenerator.getFactory()),
+ DOTNET(".net", DotnetGenerator.getFactory()),
+ JAVA(".java", JavaGenerator.getFactory());
+
+ private final String _suffix;
+ private final Generator.Factory _factory;
+
+
+ private final String _defaultTemplateDirectory;
+
+ GeneratedLanguage(String suffix, Generator.Factory factory)
+ {
+ _suffix = suffix;
+ _factory = factory;
+ _defaultTemplateDirectory = DEFAULT_TEMPLATE_DIR_BASE + "templ" + _suffix;
+ }
+
+ public String getSuffix()
+ {
+ return _suffix;
+ }
+
+ public Generator newGenerator()
+ {
+ return _factory.newInstance();
+ }
+
+ public String getDefaultTemplateDirectory()
+ {
+ return _defaultTemplateDirectory;
+ }
+ }
+
+ private Generator generator;
+
+ private String outDir;
+ private String tmplDir;
+ private GeneratedLanguage _generatorLang;
+ private ArrayList<String> xmlFiles;
+
+ public Main()
+ {
+ xmlFiles = new ArrayList<String>();
+ }
+
+ public void run(String[] args)
+ throws Exception,
+ SAXException,
+ AmqpParseException,
+ AmqpTypeMappingException,
+ AmqpTemplateException,
+ TargetDirectoryException,
+ IllegalAccessException,
+ InvocationTargetException, ParserConfigurationException
+ {
+
+ // 0. Initialize
+ outDir = DEFAULT_OUTPUT_DIR;
+ tmplDir = null;
+ _generatorLang = GeneratedLanguage.CPP; // Default generation language
+ xmlFiles.clear();
+ processArgs(args);
+
+ if (tmplDir == null)
+ {
+ tmplDir = _generatorLang.getDefaultTemplateDirectory();
+ }
+
+
+ generator = _generatorLang.newGenerator();
+ generator.setTemplateDirectory(tmplDir);
+ generator.setOutputDirectory(outDir);
+
+ // 1. Suck in all the XML spec files provided on the command line
+ analyzeXML();
+
+ Properties p = new Properties();
+ p.setProperty("file.resource.loader.path", tmplDir);
+
+ Velocity.init(p);
+
+ // 2. Load up all templates
+ generator.initializeTemplates();
+
+ // 3. Generate output
+ generator.generate();
+
+ System.out.println("Files generated: " + generator.getNumberGeneratedFiles());
+ System.out.println("Done.");
+ }
+
+ private void processArgs(String[] args)
+ {
+ // Crude but simple...
+ for (int i = 0; i < args.length; i++)
+ {
+ String arg = args[i];
+ if (arg.charAt(0) == '-')
+ {
+ switch (arg.charAt(1))
+ {
+ case'c':
+ case'C':
+ _generatorLang = GeneratedLanguage.CPP;
+ break;
+ case'j':
+ case'J':
+ _generatorLang = GeneratedLanguage.JAVA;
+ break;
+ case'n':
+ case'N':
+ _generatorLang = GeneratedLanguage.DOTNET;
+ break;
+ case'o':
+ case'O':
+ if (++i < args.length)
+ {
+ outDir = args[i];
+ }
+ break;
+ case't':
+ case'T':
+ if (++i < args.length)
+ {
+ tmplDir = args[i];
+ }
+ break;
+ }
+ }
+ else
+ {
+ xmlFiles.add(args[i]);
+ }
+ }
+ }
+
+ private void analyzeXML()
+ throws IOException, SAXException, AmqpParseException, AmqpTypeMappingException, ParserConfigurationException
+ {
+ DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+
+ System.out.println("XML files: " + xmlFiles);
+ for (String filename : xmlFiles)
+ {
+ File f = new File(filename);
+ if (f.exists())
+ {
+ // 1a. Initialize dom
+ System.out.print(" \"" + filename + "\":");
+ Document doc = docBuilder.parse(new File(filename));
+ Node amqpNode = Utils.findChild(doc, Utils.ELEMENT_AMQP);
+
+ // 1b. Extract version (major and minor) from the XML file
+ int major = Utils.getNamedIntegerAttribute(amqpNode, Utils.ATTRIBUTE_MAJOR);
+ int minor = Utils.getNamedIntegerAttribute(amqpNode, Utils.ATTRIBUTE_MINOR);
+ AmqpVersion version = new AmqpVersion(major, minor);
+ System.out.println(" Found version " + version.toString() + ".");
+ generator.addVersion(version);
+ generator.addFromNode(amqpNode, version);
+
+
+ }
+ else
+ {
+ System.err.println("ERROR: AMQP XML file \"" + filename + "\" not found.");
+ }
+ }
+// *** DEBUG INFO *** Uncomment bits from this block to see lots of stuff....
+// System.out.println();
+// System.out.println("*** Debug output ***");
+// System.out.println();
+// versionSet.print(System.out, 0, 2); // List of loaded versions
+// System.out.println();
+// constants.print(System.out, 0, 2); // List of constants
+// System.out.println();
+// domainMap.print(System.out, 0, 2); // List of domains
+// System.out.println();
+// model.print(System.out, 0, 2); // Internal version map model
+// System.out.println();
+// System.out.println("*** End debug output ***");
+// System.out.println();
+ }
+
+ public static void main(String[] args)
+ {
+ int exitCode = 1;
+ // TODO: This is a simple and klunky way of hangling command-line args, and could be improved upon.
+ if (args.length < 2)
+ {
+ usage();
+ }
+ else
+ {
+ try
+ {
+ new Main().run(args);
+ exitCode = 0;
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ catch (ParserConfigurationException e)
+ {
+ e.printStackTrace();
+ }
+ catch (SAXException e)
+ {
+ e.printStackTrace();
+ }
+ catch (AmqpParseException e)
+ {
+ e.printStackTrace();
+ }
+ catch (AmqpTypeMappingException e)
+ {
+ e.printStackTrace();
+ }
+ catch (AmqpTemplateException e)
+ {
+ e.printStackTrace();
+ }
+ catch (TargetDirectoryException e)
+ {
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ catch (InvocationTargetException e)
+ {
+ e.printStackTrace();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ System.exit(exitCode);
+ }
+
+ public static void usage()
+ {
+ System.out.println("AMQP XML generator v.0.0");
+ System.out.println("Usage: Main -c|-j [-o outDir] [-t tmplDir] XMLfile [XMLfile ...]");
+ System.out.println(" where -c: Generate C++.");
+ System.out.println(" -j: Generate Java.");
+ System.out.println(" -n: Generate .NET.");
+ System.out.println(" -o outDir: Use outDir as the output dir (default=\"" + DEFAULT_OUTPUT_DIR + "\").");
+ System.out.println(" -t tmplDir: Find templates in tmplDir.");
+ System.out.println(" Defaults: \"" + GeneratedLanguage.CPP.getDefaultTemplateDirectory() + "\" for C++;");
+ System.out.println(" \"" + GeneratedLanguage.JAVA.getDefaultTemplateDirectory() + "\" for java.;");
+ System.out.println(" \"" + GeneratedLanguage.DOTNET.getDefaultTemplateDirectory() + "\" for .NET.");
+ System.out.println(" XMLfile is a space-separated list of AMQP XML files to be parsed.");
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java b/java/common/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java
index 5348c2783f..ffeefed900 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java
+++ b/java/common/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java
@@ -18,9 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.qmf;
+package org.apache.qpid.gentools;
-public interface QMFMethodInvocation<T extends QMFObject>
+public interface MangledGenerateMethod
{
- QMFMethodResponseCommand execute(T obj, QMFMethodRequestCommand cmd);
+ String generate(AmqpField field, int indentSize, int tabSize, boolean notLast);
}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/NodeAware.java b/java/common/gentools/src/org/apache/qpid/gentools/NodeAware.java
new file mode 100644
index 0000000000..f832da75ad
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/NodeAware.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Node;
+
+/**
+ * @author kpvdr
+ * Interface allowing the addition of elements from a node in the
+ * DOM of the AMQP specification. It is used by each of the model
+ * elements in a recursive fashion to build the model.
+ */
+public interface NodeAware
+{
+ /**
+ * Add a model element from the current DOM node. All model elements must implement
+ * this interface. If the node contains children that are also a part of the model,
+ * then this method is called on new instances of those model elements.
+ *
+ * @param n Node from which the current model element is to be added.
+ * @param o Ordinal value of the current model elemet.
+ * @param v Verion of the DOM from which the node comes.
+ * @throws AmqpParseException
+ * @throws AmqpTypeMappingException
+ * @returns true if a node was added, false if not
+ */
+ public boolean addFromNode(Node n, int o, AmqpVersion v)
+ throws AmqpParseException, AmqpTypeMappingException;
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/Printable.java b/java/common/gentools/src/org/apache/qpid/gentools/Printable.java
new file mode 100644
index 0000000000..aa13df7b68
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/Printable.java
@@ -0,0 +1,28 @@
+/*
+ *
+ * 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.gentools;
+
+import java.io.PrintStream;
+
+public interface Printable
+{
+ public void print(PrintStream out, int marginSize, int tabSize);
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java
new file mode 100644
index 0000000000..8e1af1c551
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map.Entry;
+
+
+public class SingleVersionClass
+{
+ private final int _classId;
+
+
+ private final AmqpClass _amqpClass;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+ private final List<SingleVersionMethod> _methodList = new ArrayList<SingleVersionMethod>();
+
+ public SingleVersionClass(AmqpClass amqpClass, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpClass = amqpClass;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+ AmqpOrdinalVersionMap indexMap = amqpClass.getIndexMap();
+ int classId = 0;
+ for(Entry<Integer, AmqpVersionSet> entry : indexMap.entrySet())
+ {
+ if(entry.getValue().contains(_amqpVersion))
+ {
+ classId = entry.getKey();
+ break;
+ }
+ }
+ _classId = classId;
+
+
+ Collection<AmqpMethod> methods = _amqpClass.getMethodMap().values();
+
+ for(AmqpMethod amqpMethod : methods)
+ {
+ _methodList.add(new SingleVersionMethod(amqpMethod, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_methodList, new Comparator<SingleVersionMethod>(){
+ public int compare(SingleVersionMethod method1, SingleVersionMethod method2)
+ {
+ return method1.getMethodId() - method2.getMethodId();
+ }
+ });
+
+
+ }
+
+ public int getClassId()
+ {
+ return _classId;
+ }
+
+ public String getName()
+ {
+ return _amqpClass.getName();
+ }
+
+
+
+
+
+ public List<SingleVersionMethod> getMethodList()
+ {
+ return _methodList;
+ }
+
+
+ public int getMaximumMethodId()
+ {
+ return _methodList.get(_methodList.size()-1).getMethodId();
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionField.java b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionField.java
new file mode 100644
index 0000000000..b795663d15
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionField.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * 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.gentools;
+
+
+public class SingleVersionField
+{
+ private final AmqpField _field;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+
+ public SingleVersionField(AmqpField field, AmqpVersion amqpVersion, Generator generator)
+ {
+ _field = field;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+ }
+
+ public String getName()
+ {
+ return _field.getName();
+ }
+
+ public String getDomain()
+ {
+ return _field.getDomain(_amqpVersion);
+ }
+
+
+ public String getDomainType()
+ {
+ return _generator.getDomainType(_field.getDomain(_amqpVersion),_amqpVersion);
+ }
+
+ public String getNativeType()
+ {
+ return _generator.getNativeType(getDomainType());
+ }
+
+ public String getEncodingType()
+ {
+ return _generator.getEncodingType(getDomainType());
+ }
+
+
+ public int getPosition()
+ {
+ return _field.getOrdinal(_amqpVersion);
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java
new file mode 100644
index 0000000000..59a6d9e28a
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java
@@ -0,0 +1,154 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+import java.util.Map.Entry;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+public class SingleVersionMethod
+{
+ private final AmqpMethod _amqpMethod;
+ private final AmqpVersion _amqpVersion;
+ private final int _methodId;
+ private final List<SingleVersionField> _fieldList = new ArrayList<SingleVersionField>();
+ private final Generator _generator;
+ private final List<ConsolidatedField> _consolidatedFields = new ArrayList<ConsolidatedField>();
+ private final Map<String, ConsolidatedField> _fieldNameToConsolidatedFieldMap = new HashMap<String, ConsolidatedField>();
+
+
+ public SingleVersionMethod(AmqpMethod amqpMethod, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpMethod = amqpMethod;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+ AmqpOrdinalVersionMap indexMap = amqpMethod.getIndexMap();
+ int methodId = 0;
+ for(Entry<Integer, AmqpVersionSet> entry : indexMap.entrySet())
+ {
+ if(entry.getValue().contains(_amqpVersion))
+ {
+ methodId = entry.getKey();
+ break;
+ }
+ }
+ _methodId = methodId;
+
+ Collection<AmqpField> fields = _amqpMethod.getFieldMap().values();
+
+ for(AmqpField field : fields)
+ {
+ _fieldList.add(new SingleVersionField(field, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_fieldList, new Comparator<SingleVersionField>(){
+ public int compare(SingleVersionField field1, SingleVersionField field2)
+ {
+ return field1.getPosition() - field2.getPosition();
+ }
+ });
+
+
+
+ ConsolidatedField lastField = null;
+ int bitfieldNum = 0;
+ for(SingleVersionField field : _fieldList)
+ {
+ String domainType = field.getDomainType();
+ if(!domainType.equals("bit"))
+ {
+ lastField = new ConsolidatedField(_generator,
+ field.getName(),
+ field.getDomainType());
+ _consolidatedFields.add(lastField);
+ }
+ else if(lastField == null || !lastField.getType().equals("bitfield"))
+ {
+ lastField = new ConsolidatedField(_generator,
+ domainType.equals("bit") ? "bitfield"+bitfieldNum++ : field.getName(),
+ domainType.equals("bit") ? "bitfield" : field.getDomainType(),
+ field.getName());
+ _consolidatedFields.add(lastField);
+ }
+ else
+ {
+ lastField.add(field.getName());
+ }
+ _fieldNameToConsolidatedFieldMap.put(field.getName(), lastField);
+
+ }
+ }
+
+ public int getMethodId()
+ {
+ return _methodId;
+ }
+
+ public String getName()
+ {
+ return _amqpMethod.getName();
+ }
+
+ public Collection<SingleVersionField> getFieldList()
+ {
+ return Collections.unmodifiableCollection(_fieldList);
+ }
+
+ public List<ConsolidatedField> getConsolidatedFields()
+ {
+ return _consolidatedFields;
+ }
+
+ public String getConsolidatedFieldName(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).getName();
+ }
+
+ public boolean isConsolidated(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).isConsolidated();
+ }
+
+ public int getPositionInBitField(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).getPosition(fieldName);
+ }
+
+
+ public boolean isServerMethod()
+ {
+ return _amqpMethod.isServerMethod(_amqpVersion);
+ }
+
+
+ public boolean isClientMethod()
+ {
+ return _amqpMethod.isClientMethod(_amqpVersion);
+ }
+
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java
new file mode 100644
index 0000000000..22b416e45a
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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.gentools;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+
+public class SingleVersionModel
+{
+ private final AmqpModel _amqpModel;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+ private final List<SingleVersionClass> _classList = new ArrayList<SingleVersionClass>();
+
+ public SingleVersionModel(AmqpModel amqpModel, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpModel = amqpModel;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+
+ Collection<AmqpClass> originalClasses = _amqpModel.getClassMap().values();
+
+ for(AmqpClass amqpClass : originalClasses)
+ {
+ _classList.add(new SingleVersionClass(amqpClass, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_classList, new Comparator<SingleVersionClass>(){
+ public int compare(SingleVersionClass amqpClass1, SingleVersionClass amqpClass2)
+ {
+ return amqpClass1.getClassId() - amqpClass2.getClassId();
+ }
+ });
+
+
+ }
+
+ public Collection<SingleVersionClass> getClassList()
+ {
+ return Collections.unmodifiableCollection(_classList);
+ }
+
+ public int getMaximumClassId()
+ {
+ return _classList.get(_classList.size()-1).getClassId();
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java b/java/common/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java
new file mode 100644
index 0000000000..39ce666288
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.gentools;
+
+@SuppressWarnings("serial")
+public class TargetDirectoryException extends RuntimeException
+{
+ public TargetDirectoryException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/Utils.java b/java/common/gentools/src/org/apache/qpid/gentools/Utils.java
new file mode 100644
index 0000000000..1cedaeea12
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/Utils.java
@@ -0,0 +1,159 @@
+/*
+ *
+ * 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.gentools;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class Utils
+{
+ public final static String FILE_SEPARATOR = System.getProperty("file.separator");
+ public final static String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ public final static String ATTRIBUTE_NAME = "name";
+ public final static String ATTRIBUTE_MAJOR = "major";
+ public final static String ATTRIBUTE_MINOR = "minor";
+ public final static String ATTRIBUTE_INDEX = "index";
+ public final static String ATTRIBUTE_LABEL = "label";
+ public final static String ATTRIBUTE_SYNCHRONOUS = "synchronous";
+ public final static String ATTRIBUTE_CONTENT = "content";
+ public final static String ATTRIBUTE_HANDLER = "handler";
+ public final static String ATTRIBUTE_DOMAIN = "domain";
+ public final static String ATTRIBUTE_VALUE = "value";
+ public final static String ATTRIBUTE_TYPE = "type"; // For compatibility with AMQP 8.0
+
+ public final static String ELEMENT_AMQP = "amqp";
+ public final static String ELEMENT_CHASSIS = "chassis";
+ public final static String ELEMENT_CLASS = "class";
+ public final static String ELEMENT_CODEGEN = "codegen";
+ public final static String ELEMENT_CONSTANT = "constant";
+ public final static String ELEMENT_DOMAIN = "domain";
+ public final static String ELEMENT_METHOD = "method";
+ public final static String ELEMENT_FIELD = "field";
+ public final static String ELEMENT_VERSION = "version";
+
+ // Attribute functions
+
+ public static String getNamedAttribute(Node n, String attrName) throws AmqpParseException
+ {
+ NamedNodeMap nnm = n.getAttributes();
+ if (nnm == null)
+ {
+ throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attributes.");
+ }
+ Attr a = (Attr) nnm.getNamedItem(attrName);
+ if (a == null)
+ {
+ throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attribute \"" + attrName + "\".");
+ }
+ return a.getNodeValue();
+ }
+
+ public static int getNamedIntegerAttribute(Node n, String attrName) throws AmqpParseException
+ {
+ return Integer.parseInt(getNamedAttribute(n, attrName));
+ }
+
+ // Element functions
+
+ public static Node findChild(Node n, String eltName) throws AmqpParseException
+ {
+ NodeList nl = n.getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++)
+ {
+ Node cn = nl.item(i);
+ if (cn.getNodeName().compareTo(eltName) == 0)
+ {
+ return cn;
+ }
+ }
+ throw new AmqpParseException("Node \"" + n.getNodeName() +
+ "\" does not contain child element \"" + eltName + "\".");
+ }
+
+ // String functions
+
+ public static String firstUpper(String str)
+ {
+ if (!Character.isLetter(str.charAt(0)) || !Character.isLowerCase(str.charAt(0)))
+ {
+ return str;
+ }
+ StringBuffer sb = new StringBuffer(str);
+ sb.setCharAt(0, Character.toUpperCase(str.charAt(0)));
+ return sb.toString();
+ }
+
+ public static String firstLower(String str)
+ {
+ if (!Character.isUpperCase(str.charAt(0)))
+ {
+ return str;
+ }
+ StringBuffer sb = new StringBuffer(str);
+ sb.setCharAt(0, Character.toLowerCase(str.charAt(0)));
+ return sb.toString();
+ }
+
+ public static String createSpaces(int cnt)
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < cnt; i++)
+ {
+ sb.append(' ');
+ }
+ return sb.toString();
+ }
+
+ public static boolean containsOnlyDigits(String str)
+ {
+ boolean foundNonDigit = false;
+ for (int i = 0; i < str.length() && !foundNonDigit; i++)
+ {
+ if (!Character.isDigit(str.charAt(i)))
+ {
+ foundNonDigit = true;
+ }
+ }
+ return !foundNonDigit;
+ }
+
+ public static boolean containsOnlyDigitsAndDecimal(String str)
+ {
+ boolean foundNonDigit = false;
+ int decimalCntr = 0;
+ for (int i = 0; i < str.length() && !foundNonDigit && decimalCntr < 2; i++)
+ {
+ char ch = str.charAt(i);
+ if (!(Character.isDigit(ch) || ch == '.'))
+ {
+ foundNonDigit = true;
+ }
+ else if (ch == '.')
+ {
+ decimalCntr++;
+ }
+ }
+ return !foundNonDigit && decimalCntr < 2;
+ }
+}
diff --git a/java/common/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java b/java/common/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java
new file mode 100644
index 0000000000..a9cdd56e88
--- /dev/null
+++ b/java/common/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.gentools;
+
+public interface VersionConsistencyCheck
+{
+ public boolean isVersionConsistent(AmqpVersionSet globalVersionSet);
+}
diff --git a/java/common/protocol-version.xml b/java/common/protocol-version.xml
deleted file mode 100644
index 5435a0a582..0000000000
--- a/java/common/protocol-version.xml
+++ /dev/null
@@ -1,70 +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.
- -
- -->
-<project name="Qpid Common Protocol Versions" default="generate">
- <property name="topDirectoryLocation" location=".." />
- <property name="project.build.directory" location="target" />
- <property name="gentools.home" location="${topDirectoryLocation}/../gentools" />
- <property name="generated.path" location="${project.build.directory}/generated-sources/gentools" />
- <property name="generated.package" value="org/apache/qpid/framing" />
- <property name="generated.dir" location="${generated.path}/${generated.package}" />
- <property name="generated.timestamp" location="${generated.dir}/timestamp" />
- <property name="xml.spec.dir" location="${topDirectoryLocation}/../specs" />
- <property name="xml.spec.deps" value="amqp.0-8.xml amqp.0-9.xml amqp0-9-1.stripped.xml" />
- <property name="xml.spec.list" value="${xml.spec.dir}/amqp.0-8.xml ${xml.spec.dir}/amqp.0-9.xml ${xml.spec.dir}/amqp0-9-1.stripped.xml" />
- <property name="template.dir" value="${topDirectoryLocation}/common/templates" />
-
-
- <!--<target name="generate" depends="compile_generator,check_generate_deps" unless="generation.notRequired">-->
- <target name="generate" depends="compile_generator" unless="generation.notRequired">
- <mkdir dir="${generated.dir}"/>
- <java classname="org.apache.qpid.gentools.Main" fork="true" dir="${gentools.home}/src" failonerror="true">
- <arg line="-j -o ${generated.dir} -t ${template.dir} ${xml.spec.list}" />
- <classpath>
- <pathelement path="${gentools.home}/src" />
- <fileset dir="${gentools.home}/lib">
- <include name="**/*.jar"/>
- </fileset>
- <pathelement path="${gentools.home}/lib/velocity-1.4.jar" />
- <pathelement path="${gentools.home}/lib/velocity-dep-1.4.jar" />
- </classpath>
- </java>
- <touch file="${generated.timestamp}" />
- </target>
-
- <target name="check_generate_deps">
- <uptodate property="generation.notRequired" targetfile="${generated.timestamp}">
- <srcfiles dir="${xml.spec.dir}" includes="${xml.spec.deps}" />
- <srcfiles dir="${template.dir}" includes="**/*.vm **/*.tmpl" />
- </uptodate>
- </target>
-
- <target name="compile_generator">
- <ant dir="${gentools.home}" />
- </target>
-
- <target name="precompile" depends="generate"/>
-
- <target name="clean">
- <delete dir="${generated.path}" />
- </target>
-
-</project>
-
diff --git a/java/common/src/main/java/common.bnd b/java/common/src/main/java/common.bnd
index b34f8deacc..84350fdc75 100755
--- a/java/common/src/main/java/common.bnd
+++ b/java/common/src/main/java/common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.19.0
+ver: 0.21.0
Bundle-SymbolicName: qpid-common
Bundle-Version: ${ver}
diff --git a/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
index 5268ce9bc2..7aa280ce02 100644
--- a/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
+++ b/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
@@ -87,6 +87,8 @@ public class ClientProperties
public static final String USE_LEGACY_MAP_MESSAGE_FORMAT = "qpid.use_legacy_map_message";
+ public static final String USE_LEGACY_STREAM_MESSAGE_FORMAT = "qpid.use_legacy_stream_message";
+
public static final String AMQP_VERSION = "qpid.amqp.version";
public static final String QPID_VERIFY_CLIENT_ID = "qpid.verify_client_id";
@@ -190,6 +192,19 @@ public class ClientProperties
*/
public static final long DEFAULT_FLOW_CONTROL_WAIT_NOTIFY_PERIOD = 5000L;
+ /**
+ * System property to control whether the client will declare queues during
+ * consumer creation when using BindingURLs.
+ */
+ public static final String QPID_DECLARE_QUEUES_PROP_NAME = "qpid.declare_queues";
+
+ /**
+ * System property to control whether the client will declare exchanges during
+ * producer/consumer creation when using BindingURLs.
+ */
+ public static final String QPID_DECLARE_EXCHANGES_PROP_NAME = "qpid.declare_exchanges";
+ public static final String VERIFY_QUEUE_ON_SEND = "qpid.verify_queue_on_send";
+
private ClientProperties()
{
diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index fdc71e31f9..1381390640 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -110,7 +110,7 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
return new LinkedHashMap<AMQShortString, AMQShortString>()
{
-
+ @Override
protected boolean removeEldestEntry(Map.Entry<AMQShortString, AMQShortString> eldest)
{
return size() > LOCAL_INTERN_CACHE_SIZE;
@@ -845,22 +845,15 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return internString;
}
-
- public static void main(String args[])
+ public static String toString(AMQShortString amqShortString)
{
- AMQShortString s = new AMQShortString("a.b.c.d.e.f.g.h.i.j.k");
- AMQShortString s2 = s.substring(2, 7);
-
- AMQShortStringTokenizer t = s2.tokenize((byte) '.');
- while(t.hasMoreTokens())
- {
- System.err.println(t.nextToken());
- }
+ return amqShortString == null ? null : amqShortString.asString();
}
- public static String toString(AMQShortString amqShortString)
+ public static void clearLocalCache()
{
- return amqShortString == null ? null : amqShortString.asString();
+ _localInternMap.remove();
+ _localStringMap.remove();
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
index 57f2c638a2..b9ed1b2154 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java
@@ -855,6 +855,7 @@ public class FieldTable
public void addAll(FieldTable fieldTable)
{
initMapIfNecessary();
+ fieldTable.initMapIfNecessary();
if (fieldTable._properties != null)
{
_encodedForm = null;
diff --git a/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java b/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
index 15c144b0eb..59a1b6c5b0 100644
--- a/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
+++ b/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
@@ -49,7 +49,11 @@ public class ConnectionStartProperties
public static final String SESSION_FLOW = "qpid.session_flow";
- public static int getPID()
+ public static int _pid;
+
+ public static final String _platformInfo;
+
+ static
{
RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean();
String processName = rtb.getName();
@@ -57,23 +61,20 @@ public class ConnectionStartProperties
{
try
{
- return Integer.parseInt(processName.substring(0,processName.indexOf('@')));
+ _pid = Integer.parseInt(processName.substring(0,processName.indexOf('@')));
}
catch(Exception e)
{
LOGGER.warn("Unable to get the PID due to error",e);
- return -1;
+ _pid = -1;
}
}
else
{
LOGGER.warn("Unable to get the PID due to unsupported format : " + processName);
- return -1;
+ _pid = -1;
}
- }
- public static String getPlatformInfo()
- {
StringBuilder fullSystemInfo = new StringBuilder(System.getProperty("java.runtime.name"));
fullSystemInfo.append(", ");
fullSystemInfo.append(System.getProperty("java.runtime.version"));
@@ -88,6 +89,16 @@ public class ConnectionStartProperties
fullSystemInfo.append(", ");
fullSystemInfo.append(System.getProperty("sun.os.patch.level"));
- return fullSystemInfo.toString();
+ _platformInfo = fullSystemInfo.toString();
+ }
+
+ public static int getPID()
+ {
+ return _pid;
+ }
+
+ public static String getPlatformInfo()
+ {
+ return _platformInfo;
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
index 7ca588946b..6774d0a45a 100644
--- a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
+++ b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
@@ -23,6 +23,7 @@ package org.apache.qpid.protocol;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.network.TransportActivity;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
@@ -31,7 +32,7 @@ import java.nio.ByteBuffer;
* A ProtocolEngine is a Receiver for java.nio.ByteBuffers. It takes the data passed to it in the received
* decodes it and then process the result.
*/
-public interface ProtocolEngine extends Receiver<java.nio.ByteBuffer>
+public interface ProtocolEngine extends Receiver<java.nio.ByteBuffer>, TransportActivity
{
// Returns the remote address of the NetworkDriver
SocketAddress getRemoteAddress();
@@ -56,6 +57,6 @@ public interface ProtocolEngine extends Receiver<java.nio.ByteBuffer>
void readerIdle();
- public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender);
+ public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender);
} \ No newline at end of file
diff --git a/java/common/src/main/java/org/apache/qpid/transport/Connection.java b/java/common/src/main/java/org/apache/qpid/transport/Connection.java
index e87851cf7d..cdca726148 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/Connection.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/Connection.java
@@ -21,12 +21,7 @@
package org.apache.qpid.transport;
import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.transport.network.Assembler;
-import org.apache.qpid.transport.network.Disassembler;
-import org.apache.qpid.transport.network.InputHandler;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
+import org.apache.qpid.transport.network.*;
import org.apache.qpid.transport.network.security.SecurityLayer;
import org.apache.qpid.transport.network.security.SecurityLayerFactory;
import org.apache.qpid.transport.util.Logger;
@@ -73,6 +68,8 @@ public class Connection extends ConnectionInvoker
//Usable channels are numbered 0 to <ChannelMax> - 1
public static final int MAX_CHANNEL_MAX = 0xFFFF;
public static final int MIN_USABLE_CHANNEL_NUM = 0;
+ private long _lastSendTime;
+ private long _lastReadTime;
public enum State { NEW, CLOSED, OPENING, OPEN, CLOSING, CLOSE_RCVD, RESUMING }
@@ -89,15 +86,15 @@ public class Connection extends ConnectionInvoker
public static interface SessionFactory
{
- Session newSession(Connection conn, Binary name, long expiry);
+ Session newSession(Connection conn, Binary name, long expiry, boolean isNoReplay);
}
private static final class DefaultSessionFactory implements SessionFactory
{
- public Session newSession(final Connection conn, final Binary name, final long expiry)
+ public Session newSession(final Connection conn, final Binary name, final long expiry, final boolean isNoReplay)
{
- return new Session(conn, name, expiry);
+ return new Session(conn, name, expiry, isNoReplay);
}
}
@@ -232,9 +229,10 @@ public class Connection extends ConnectionInvoker
addConnectionListener((ConnectionListener)secureReceiver);
}
- NetworkConnection network = transport.connect(settings, secureReceiver, null);
- _remoteAddress = network.getRemoteAddress();
- _localAddress = network.getLocalAddress();
+ NetworkConnection network = transport.connect(settings, secureReceiver, new ConnectionActivity());
+
+ setRemoteAddress(network.getRemoteAddress());
+ setLocalAddress(network.getLocalAddress());
final Sender<ByteBuffer> secureSender = securityLayer.sender(network.getSender());
if(secureSender instanceof ConnectionListener)
@@ -298,7 +296,12 @@ public class Connection extends ConnectionInvoker
public Session createSession(long expiry)
{
- return createSession(UUID.randomUUID().toString(), expiry);
+ return createSession(expiry, false);
+ }
+
+ public Session createSession(long expiry, boolean isNoReplay)
+ {
+ return createSession(UUID.randomUUID().toString(), expiry, isNoReplay);
}
public Session createSession(String name)
@@ -311,6 +314,11 @@ public class Connection extends ConnectionInvoker
return createSession(Strings.toUTF8(name), expiry);
}
+ public Session createSession(String name, long expiry,boolean isNoReplay)
+ {
+ return createSession(new Binary(Strings.toUTF8(name)), expiry, isNoReplay);
+ }
+
public Session createSession(byte[] name, long expiry)
{
return createSession(new Binary(name), expiry);
@@ -318,6 +326,11 @@ public class Connection extends ConnectionInvoker
public Session createSession(Binary name, long expiry)
{
+ return createSession(name, expiry, false);
+ }
+
+ public Session createSession(Binary name, long expiry, boolean isNoReplay)
+ {
synchronized (lock)
{
Waiter w = new Waiter(lock, timeout);
@@ -331,7 +344,7 @@ public class Connection extends ConnectionInvoker
throw new ConnectionException("Timed out waiting for connection to be ready. Current state is :" + state);
}
- Session ssn = _sessionFactory.newSession(this, name, expiry);
+ Session ssn = _sessionFactory.newSession(this, name, expiry, isNoReplay);
registerSession(ssn);
map(ssn);
ssn.attach();
@@ -369,6 +382,7 @@ public class Connection extends ConnectionInvoker
public void received(ProtocolEvent event)
{
+ _lastReadTime = System.currentTimeMillis();
if(log.isDebugEnabled())
{
log.debug("RECV: [%s] %s", this, event);
@@ -378,6 +392,7 @@ public class Connection extends ConnectionInvoker
public void send(ProtocolEvent event)
{
+ _lastSendTime = System.currentTimeMillis();
if(log.isDebugEnabled())
{
log.debug("SEND: [%s] %s", this, event);
@@ -728,6 +743,17 @@ public class Connection extends ConnectionInvoker
return _localAddress;
}
+ protected void setRemoteAddress(SocketAddress remoteAddress)
+ {
+ _remoteAddress = remoteAddress;
+ }
+
+ protected void setLocalAddress(SocketAddress localAddress)
+ {
+ _localAddress = localAddress;
+ }
+
+
private void invokeSessionDetached(int channel, SessionDetachCode sessionDetachCode)
{
SessionDetached sessionDetached = new SessionDetached();
@@ -735,4 +761,38 @@ public class Connection extends ConnectionInvoker
sessionDetached.setCode(sessionDetachCode);
invoke(sessionDetached);
}
+
+
+ protected void doHeartBeat()
+ {
+ connectionHeartbeat();
+ }
+
+ private class ConnectionActivity implements TransportActivity
+ {
+ @Override
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _lastSendTime;
+ }
+
+ @Override
+ public void writerIdle()
+ {
+ connectionHeartbeat();
+ }
+
+ @Override
+ public void readerIdle()
+ {
+ // TODO
+
+ }
+ }
}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java b/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
index 20d6f98fa6..12f8d801dc 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
@@ -38,14 +38,6 @@ public interface NetworkTransportConfiguration
// The amount of memory in bytes to allocate to the outgoing buffer
Integer getSendBufferSize();
- Integer getPort();
-
- String getHost();
-
- String getTransport();
-
- Integer getConnectorProcessors();
-
InetSocketAddress getAddress();
boolean needClientAuth();
diff --git a/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java b/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
index e9a7d51456..1e0d5b9698 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
@@ -71,7 +71,8 @@ public class ServerDelegate extends ConnectionDelegate
if (mechanism == null || mechanism.length() == 0)
{
- tuneAuthorizedConnection(conn);
+ conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED,
+ "No Sasl mechanism was specified");
return;
}
@@ -82,7 +83,7 @@ public class ServerDelegate extends ConnectionDelegate
if (ss == null)
{
conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED,
- "null SASL mechanism: " + mechanism);
+ "No SaslServer could be created for mechanism: " + mechanism);
return;
}
conn.setSaslServer(ss);
diff --git a/java/common/src/main/java/org/apache/qpid/transport/Session.java b/java/common/src/main/java/org/apache/qpid/transport/Session.java
index 95c3e4669f..8b29d6e424 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/Session.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/Session.java
@@ -25,7 +25,6 @@ import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.transport.network.Frame;
import org.apache.qpid.transport.util.Logger;
import org.apache.qpid.transport.util.Waiter;
-
import static org.apache.qpid.transport.Option.COMPLETED;
import static org.apache.qpid.transport.Option.SYNC;
import static org.apache.qpid.transport.Option.TIMELY_REPLY;
@@ -132,19 +131,31 @@ public class Session extends SessionInvoker
private final Object stateLock = new Object();
private final AtomicBoolean _failoverRequired = new AtomicBoolean(false);
+ private boolean _isNoReplay = false;
protected Session(Connection connection, Binary name, long expiry)
{
this(connection, new SessionDelegate(), name, expiry);
}
+ protected Session(Connection connection, Binary name, long expiry, boolean noReplay)
+ {
+ this(connection, new SessionDelegate(), name, expiry, noReplay);
+ }
+
protected Session(Connection connection, SessionDelegate delegate, Binary name, long expiry)
{
+ this(connection, delegate, name, expiry,false);
+ }
+
+ protected Session(Connection connection, SessionDelegate delegate, Binary name, long expiry, boolean noReplay)
+ {
this.connection = connection;
this.delegate = delegate;
this.name = name;
this.expiry = expiry;
this.closing = false;
+ this._isNoReplay = noReplay;
initReceiver();
}
@@ -282,6 +293,7 @@ public class Session extends SessionInvoker
void resume()
{
_failoverRequired.set(false);
+
synchronized (commandsLock)
{
attach();
@@ -414,7 +426,7 @@ public class Session extends SessionInvoker
if(log.isDebugEnabled())
{
- log.debug("ID: [%s] %s", this.channel, id);
+ log.debug("identify: ch=%s, commandId=%s", this.channel, id);
}
if ((id & 0xff) == 0)
@@ -443,7 +455,7 @@ public class Session extends SessionInvoker
{
if(log.isDebugEnabled())
{
- log.debug("%s processed([%d,%d]) %s %s", this, lower, upper, syncPoint, maxProcessed);
+ log.debug("%s ch=%s processed([%d,%d]) %s %s", this, channel, lower, upper, syncPoint, maxProcessed);
}
boolean flush;
@@ -451,7 +463,7 @@ public class Session extends SessionInvoker
{
if(log.isDebugEnabled())
{
- log.debug("%s", processed);
+ log.debug("%s processed: %s", this, processed);
}
if (ge(upper, commandsIn))
@@ -740,7 +752,7 @@ public class Session extends SessionInvoker
sessionCommandPoint(0, 0);
}
- boolean replayTransfer = !closing && !transacted &&
+ boolean replayTransfer = !_isNoReplay && !closing && !transacted &&
m instanceof MessageTransfer &&
! m.isUnreliable();
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java b/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
index 4d4274278f..8437ef1a94 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
@@ -27,5 +27,7 @@ import javax.net.ssl.SSLContext;
public interface IncomingNetworkTransport extends NetworkTransport
{
- public void accept(NetworkTransportConfiguration config, ProtocolEngineFactory factory, SSLContext sslContext);
+ public void accept(NetworkTransportConfiguration config,
+ ProtocolEngineFactory factory,
+ SSLContext sslContext);
} \ No newline at end of file
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
index 12c42d6643..050d194c47 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
@@ -50,4 +50,8 @@ public interface NetworkConnection
void setPeerPrincipal(Principal principal);
Principal getPeerPrincipal();
+
+ int getMaxReadIdle();
+
+ int getMaxWriteIdle();
}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java b/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
index 854d76430b..45231aa05d 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
@@ -23,12 +23,13 @@ package org.apache.qpid.transport.network;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.Receiver;
-import javax.net.ssl.SSLContext;
import java.nio.ByteBuffer;
public interface OutgoingNetworkTransport extends NetworkTransport
{
public NetworkConnection getConnection();
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContext sslContext);
+ public NetworkConnection connect(ConnectionSettings settings,
+ Receiver<ByteBuffer> delegate,
+ TransportActivity transportActivity);
} \ No newline at end of file
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/Ticker.java b/java/common/src/main/java/org/apache/qpid/transport/network/Ticker.java
new file mode 100644
index 0000000000..210b014a57
--- /dev/null
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/Ticker.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.transport.network;
+
+public interface Ticker
+{
+ int getTimeToNextTick(long currentTime);
+
+ int tick(long currentTime);
+}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/TransportActivity.java b/java/common/src/main/java/org/apache/qpid/transport/network/TransportActivity.java
new file mode 100644
index 0000000000..2ee336d9b2
--- /dev/null
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/TransportActivity.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.transport.network;
+
+public interface TransportActivity
+{
+ long getLastReadTime();
+
+ long getLastWriteTime();
+
+ void writerIdle();
+
+ void readerIdle();
+}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IdleTimeoutTicker.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IdleTimeoutTicker.java
new file mode 100644
index 0000000000..54a2a360bb
--- /dev/null
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IdleTimeoutTicker.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * 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.transport.network.io;
+
+import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.network.Ticker;
+import org.apache.qpid.transport.network.TransportActivity;
+
+class IdleTimeoutTicker implements Ticker
+{
+ private final TransportActivity _transport;
+ private final int _defaultTimeout;
+ private NetworkConnection _connection;
+
+ public IdleTimeoutTicker(TransportActivity transport, int defaultTimeout)
+ {
+ _transport = transport;
+ _defaultTimeout = defaultTimeout;
+ }
+
+ @Override
+ public int getTimeToNextTick(long currentTime)
+ {
+ long nextTime = -1;
+ final long maxReadIdle = 1000l * _connection.getMaxReadIdle();
+
+ if(maxReadIdle > 0)
+ {
+ nextTime = _transport.getLastReadTime() + maxReadIdle;
+ }
+
+ long maxWriteIdle = 1000l * _connection.getMaxWriteIdle();
+
+ if(maxWriteIdle > 0)
+ {
+ long writeTime = _transport.getLastWriteTime() + maxWriteIdle;
+ if(nextTime == -1l || writeTime < nextTime)
+ {
+ nextTime = writeTime;
+ }
+ }
+ return nextTime == -1 ? _defaultTimeout : (int) (nextTime - currentTime);
+ }
+
+ @Override
+ public int tick(long currentTime)
+ {
+ // writer Idle
+ long maxWriteIdle = 1000l * _connection.getMaxWriteIdle();
+ if(maxWriteIdle > 0 && maxWriteIdle+ _transport.getLastWriteTime() <= currentTime)
+ {
+ _transport.writerIdle();
+ }
+ // reader Idle
+ final long maxReadIdle = 1000l * _connection.getMaxReadIdle();
+ if(maxReadIdle > 0 && maxReadIdle+ _transport.getLastReadTime() <= currentTime)
+ {
+
+ _transport.readerIdle();
+ }
+ return getTimeToNextTick(currentTime);
+ }
+
+ public void setConnection(NetworkConnection connection)
+ {
+ _connection = connection;
+ }
+}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
index 2658296c5f..f5c09ac2cc 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
@@ -26,7 +26,9 @@ import java.nio.ByteBuffer;
import java.security.Principal;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.network.Ticker;
import org.apache.qpid.transport.network.NetworkConnection;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,14 +40,23 @@ public class IoNetworkConnection implements NetworkConnection
private final IoSender _ioSender;
private final IoReceiver _ioReceiver;
private Principal _principal;
+ private int _maxReadIdle;
+ private int _maxWriteIdle;
public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
- int sendBufferSize, int receiveBufferSize, long timeout)
+ int sendBufferSize, int receiveBufferSize, long timeout)
+ {
+ this(socket,delegate,sendBufferSize,receiveBufferSize,timeout,null);
+ }
+
+ public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
+ int sendBufferSize, int receiveBufferSize, long timeout, Ticker ticker)
{
_socket = socket;
_timeout = timeout;
_ioReceiver = new IoReceiver(_socket, delegate, receiveBufferSize,_timeout);
+ _ioReceiver.setTicker(ticker);
_ioSender = new IoSender(_socket, 2 * sendBufferSize, _timeout);
@@ -88,14 +99,12 @@ public class IoNetworkConnection implements NetworkConnection
public void setMaxWriteIdle(int sec)
{
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
+ _maxWriteIdle = sec;
}
public void setMaxReadIdle(int sec)
{
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
+ _maxReadIdle = sec;
}
@Override
@@ -109,4 +118,16 @@ public class IoNetworkConnection implements NetworkConnection
{
return _principal;
}
+
+ @Override
+ public int getMaxReadIdle()
+ {
+ return _maxReadIdle;
+ }
+
+ @Override
+ public int getMaxWriteIdle()
+ {
+ return _maxWriteIdle;
+ }
}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
index 9b6f0a0b1b..c8027e143e 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
@@ -41,9 +41,8 @@ import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.NetworkTransportConfiguration;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
+import org.apache.qpid.transport.network.*;
+
import org.slf4j.LoggerFactory;
public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNetworkTransport
@@ -56,7 +55,9 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
private IoNetworkConnection _connection;
private AcceptingThread _acceptor;
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContext sslContext)
+ public NetworkConnection connect(ConnectionSettings settings,
+ Receiver<ByteBuffer> delegate,
+ TransportActivity transportActivity)
{
int sendBufferSize = settings.getWriteBufferSize();
int receiveBufferSize = settings.getReadBufferSize();
@@ -91,7 +92,9 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
try
{
- _connection = new IoNetworkConnection(_socket, delegate, sendBufferSize, receiveBufferSize, TIMEOUT);
+ IdleTimeoutTicker ticker = new IdleTimeoutTicker(transportActivity, TIMEOUT);
+ _connection = new IoNetworkConnection(_socket, delegate, sendBufferSize, receiveBufferSize, TIMEOUT, ticker);
+ ticker.setConnection(_connection);
_connection.start();
}
catch(Exception e)
@@ -128,9 +131,10 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
return _connection;
}
- public void accept(NetworkTransportConfiguration config, ProtocolEngineFactory factory, SSLContext sslContext)
+ public void accept(NetworkTransportConfiguration config,
+ ProtocolEngineFactory factory,
+ SSLContext sslContext)
{
-
try
{
_acceptor = new AcceptingThread(config, factory, sslContext);
@@ -141,8 +145,6 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
{
throw new TransportException("Unable to start server socket", e);
}
-
-
}
private class AcceptingThread extends Thread
@@ -152,15 +154,16 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
private ProtocolEngineFactory _factory;
private SSLContext _sslContext;
private ServerSocket _serverSocket;
+ private int _timeout;
private AcceptingThread(NetworkTransportConfiguration config,
ProtocolEngineFactory factory,
- SSLContext sslContext)
- throws IOException
+ SSLContext sslContext) throws IOException
{
_config = config;
_factory = factory;
_sslContext = sslContext;
+ _timeout = TIMEOUT;
InetSocketAddress address = config.getAddress();
@@ -172,15 +175,19 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
{
SSLServerSocketFactory socketFactory = _sslContext.getServerSocketFactory();
_serverSocket = socketFactory.createServerSocket();
- ((SSLServerSocket)_serverSocket).setNeedClientAuth(config.needClientAuth());
- ((SSLServerSocket)_serverSocket).setWantClientAuth(config.wantClientAuth());
+ if(config.needClientAuth())
+ {
+ ((SSLServerSocket)_serverSocket).setNeedClientAuth(true);
+ }
+ else if(config.wantClientAuth())
+ {
+ ((SSLServerSocket)_serverSocket).setWantClientAuth(true);
+ }
}
_serverSocket.setReuseAddress(true);
_serverSocket.bind(address);
-
-
}
@@ -217,6 +224,7 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
{
socket = _serverSocket.accept();
socket.setTcpNoDelay(_config.getTcpNoDelay());
+ socket.setSoTimeout(_timeout);
final Integer sendBufferSize = _config.getSendBufferSize();
final Integer receiveBufferSize = _config.getReceiveBufferSize();
@@ -224,10 +232,12 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
socket.setSendBufferSize(sendBufferSize);
socket.setReceiveBufferSize(receiveBufferSize);
-
ProtocolEngine engine = _factory.newProtocolEngine();
- NetworkConnection connection = new IoNetworkConnection(socket, engine, sendBufferSize, receiveBufferSize, TIMEOUT);
+ final IdleTimeoutTicker ticker = new IdleTimeoutTicker(engine, TIMEOUT);
+ NetworkConnection connection = new IoNetworkConnection(socket, engine, sendBufferSize, receiveBufferSize, _timeout,
+ ticker);
+ ticker.setConnection(connection);
if(_sslContext != null)
{
@@ -248,14 +258,14 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
}
catch(RuntimeException e)
{
- LOGGER.error("Error in Acceptor thread on port " + _config.getPort(), e);
+ LOGGER.error("Error in Acceptor thread on address " + _config.getAddress(), e);
closeSocketIfNecessary(socket);
}
catch(IOException e)
{
if(!_closed)
{
- LOGGER.error("Error in Acceptor thread on port " + _config.getPort(), e);
+ LOGGER.error("Error in Acceptor thread on address " + _config.getAddress(), e);
closeSocketIfNecessary(socket);
try
{
@@ -275,7 +285,7 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
{
if(LOGGER.isDebugEnabled())
{
- LOGGER.debug("Acceptor exiting, no new connections will be accepted on port " + _config.getPort());
+ LOGGER.debug("Acceptor exiting, no new connections will be accepted on address " + _config.getAddress());
}
}
}
@@ -294,6 +304,7 @@ public class IoNetworkTransport implements OutgoingNetworkTransport, IncomingNet
}
}
}
+
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
index 7e63071c16..06a43e21c6 100644
--- a/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
+++ b/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
@@ -24,6 +24,7 @@ import org.apache.qpid.common.Closeable;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.transport.network.Ticker;
import org.apache.qpid.transport.util.Logger;
import javax.net.ssl.SSLSocket;
@@ -31,6 +32,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketException;
+import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -51,6 +53,8 @@ final class IoReceiver implements Runnable, Closeable
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Thread receiverThread;
private static final boolean shutdownBroken;
+
+ private Ticker _ticker;
static
{
String osName = System.getProperty("os.name");
@@ -136,7 +140,7 @@ final class IoReceiver implements Runnable, Closeable
{
final int threshold = bufferSize / 2;
- // I set the read buffer size simillar to SO_RCVBUF
+ // I set the read buffer size similar to SO_RCVBUF
// Haven't tested with a lower value to see if it's better or worse
byte[] buffer = new byte[bufferSize];
try
@@ -144,27 +148,71 @@ final class IoReceiver implements Runnable, Closeable
InputStream in = socket.getInputStream();
int read = 0;
int offset = 0;
- while ((read = in.read(buffer, offset, bufferSize-offset)) != -1)
+ long currentTime;
+ while(read != -1)
{
- if (read > 0)
+ try
+ {
+ while ((read = in.read(buffer, offset, bufferSize-offset)) != -1)
+ {
+ if (read > 0)
+ {
+ ByteBuffer b = ByteBuffer.wrap(buffer,offset,read);
+ receiver.received(b);
+ offset+=read;
+ if (offset > threshold)
+ {
+ offset = 0;
+ buffer = new byte[bufferSize];
+ }
+ }
+ currentTime = System.currentTimeMillis();
+
+ if(_ticker != null)
+ {
+ int tick = _ticker.getTimeToNextTick(currentTime);
+ if(tick <= 0)
+ {
+ tick = _ticker.tick(currentTime);
+ }
+ try
+ {
+ if(!socket.isClosed())
+ {
+ socket.setSoTimeout(tick <= 0 ? 1 : tick);
+ }
+ }
+ catch(SocketException e)
+ {
+ // ignore - closed socket
+ }
+ }
+ }
+ }
+ catch (SocketTimeoutException e)
{
- ByteBuffer b = ByteBuffer.wrap(buffer,offset,read);
- receiver.received(b);
- offset+=read;
- if (offset > threshold)
+ currentTime = System.currentTimeMillis();
+ if(_ticker != null)
{
- offset = 0;
- buffer = new byte[bufferSize];
+ final int tick = _ticker.tick(currentTime);
+ if(!socket.isClosed())
+ {
+ try
+ {
+ socket.setSoTimeout(tick <= 0 ? 1 : tick );
+ }
+ catch(SocketException ex)
+ {
+ // ignore - closed socket
+ }
+ }
}
}
}
}
catch (Throwable t)
{
- if (!(shutdownBroken &&
- t instanceof SocketException &&
- t.getMessage().equalsIgnoreCase("socket closed") &&
- closed.get()))
+ if (shouldReport(t))
{
receiver.exception(t);
}
@@ -183,4 +231,30 @@ final class IoReceiver implements Runnable, Closeable
}
}
+ private boolean shouldReport(Throwable t)
+ {
+ boolean brokenClose = closed.get() &&
+ shutdownBroken &&
+ t instanceof SocketException &&
+ "socket closed".equalsIgnoreCase(t.getMessage());
+
+ boolean sslSocketClosed = closed.get() &&
+ socket instanceof SSLSocket &&
+ t instanceof SocketException &&
+ "Socket is closed".equalsIgnoreCase(t.getMessage());
+
+ return !brokenClose && !sslSocketClosed;
+ }
+
+ public Ticker getTicker()
+ {
+ return _ticker;
+ }
+
+ public void setTicker(Ticker ticker)
+ {
+ _ticker = ticker;
+ }
+
+
}
diff --git a/java/common/src/main/java/org/apache/qpid/url/BindingURL.java b/java/common/src/main/java/org/apache/qpid/url/BindingURL.java
index 0e6c865a16..61585443b1 100644
--- a/java/common/src/main/java/org/apache/qpid/url/BindingURL.java
+++ b/java/common/src/main/java/org/apache/qpid/url/BindingURL.java
@@ -36,6 +36,9 @@ public interface BindingURL
public static final String OPTION_SUBSCRIPTION = "subscription";
public static final String OPTION_ROUTING_KEY = "routingkey";
public static final String OPTION_BINDING_KEY = "bindingkey";
+ public static final String OPTION_EXCHANGE_AUTODELETE = "exchangeautodelete";
+ public static final String OPTION_EXCHANGE_DURABLE = "exchangedurable";
+ public static final String OPTION_EXCHANGE_INTERNAL = "exchangeinternal";
/**
* This option is only applicable for 0-8/0-9/0-9-1 protocols connection
diff --git a/java/common/src/main/java/org/apache/qpid/util/FileUtils.java b/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
index 2d3e321812..7362099070 100644
--- a/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
+++ b/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
@@ -220,6 +220,19 @@ public class FileUtils
public static void copyCheckedEx(File src, File dst) throws IOException
{
InputStream in = new FileInputStream(src);
+ copy(in, dst);
+ }
+
+ /**
+ * Copies the specified InputStream to the specified destination file. If the destination file does not exist,
+ * it is created.
+ *
+ * @param in The InputStream
+ * @param dst The destination file name.
+ * @throws IOException
+ */
+ public static void copy(InputStream in, File dst) throws IOException
+ {
try
{
if (!dst.exists())
diff --git a/java/common/src/main/java/org/apache/qpid/util/NetMatcher.java b/java/common/src/main/java/org/apache/qpid/util/NetMatcher.java
deleted file mode 100644
index 971dd3fe2a..0000000000
--- a/java/common/src/main/java/org/apache/qpid/util/NetMatcher.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2000-2006 The Apache Software Foundation. *
- * All rights reserved. *
- * ------------------------------------------------------------------- *
- * 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.util;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-public class NetMatcher
-{
- private ArrayList networks;
-
- public void initInetNetworks(final Collection nets)
- {
- networks = new ArrayList();
- for (Iterator iter = nets.iterator(); iter.hasNext(); )
- {
- try
- {
- InetNetwork net = InetNetwork.getFromString((String) iter.next());
- if (!networks.contains(net))
- {
- networks.add(net);
- }
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address: " + uhe.getMessage());
- }
- }
- networks.trimToSize();
- }
-
- public void initInetNetworks(final String[] nets)
- {
- networks = new ArrayList();
- for (int i = 0; i < nets.length; i++)
- {
- try
- {
- InetNetwork net = InetNetwork.getFromString(nets[i]);
- if (!networks.contains(net))
- {
- networks.add(net);
- }
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address: " + uhe.getMessage());
- }
- }
- networks.trimToSize();
- }
-
- public boolean matchInetNetwork(final String hostIP)
- {
- InetAddress ip = null;
-
- try
- {
- ip = InetAddress.getByName(hostIP);
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address for " + hostIP + ": " + uhe.getMessage());
- }
-
- boolean sameNet = false;
-
- if (ip != null)
- {
- for (Iterator iter = networks.iterator(); (!sameNet) && iter.hasNext(); )
- {
- InetNetwork network = (InetNetwork) iter.next();
- sameNet = network.contains(ip);
- }
- }
- return sameNet;
- }
-
- public boolean matchInetNetwork(final InetAddress ip)
- {
- boolean sameNet = false;
-
- for (Iterator iter = networks.iterator(); (!sameNet) && iter.hasNext(); )
- {
- InetNetwork network = (InetNetwork) iter.next();
- sameNet = network.contains(ip);
- }
- return sameNet;
- }
-
- public NetMatcher()
- {
- }
-
- public NetMatcher(final String[] nets)
- {
- initInetNetworks(nets);
- }
-
- public NetMatcher(final Collection nets)
- {
- initInetNetworks(nets);
- }
-
- public String toString() {
- return networks.toString();
- }
-
- protected void log(String s) { }
-}
-
-class InetNetwork
-{
- /*
- * Implements network masking, and is compatible with RFC 1518 and
- * RFC 1519, which describe CIDR: Classless Inter-Domain Routing.
- */
-
- private InetAddress network;
- private InetAddress netmask;
-
- public InetNetwork(InetAddress ip, InetAddress netmask)
- {
- network = maskIP(ip, netmask);
- this.netmask = netmask;
- }
-
- public boolean contains(final String name) throws java.net.UnknownHostException
- {
- return network.equals(maskIP(InetAddress.getByName(name), netmask));
- }
-
- public boolean contains(final InetAddress ip)
- {
- return network.equals(maskIP(ip, netmask));
- }
-
- public String toString()
- {
- return network.getHostAddress() + "/" + netmask.getHostAddress();
- }
-
- public int hashCode()
- {
- return maskIP(network, netmask).hashCode();
- }
-
- public boolean equals(Object obj)
- {
- return (obj != null) && (obj instanceof InetNetwork) &&
- ((((InetNetwork)obj).network.equals(network)) && (((InetNetwork)obj).netmask.equals(netmask)));
- }
-
- public static InetNetwork getFromString(String netspec) throws java.net.UnknownHostException
- {
- if (netspec.endsWith("*"))
- {
- netspec = normalizeFromAsterisk(netspec);
- }
- else
- {
- int iSlash = netspec.indexOf('/');
- if (iSlash == -1)
- {
- netspec += "/255.255.255.255";
- }
- else if (netspec.indexOf('.', iSlash) == -1)
- {
- netspec = normalizeFromCIDR(netspec);
- }
- }
-
- return new InetNetwork(InetAddress.getByName(netspec.substring(0, netspec.indexOf('/'))),
- InetAddress.getByName(netspec.substring(netspec.indexOf('/') + 1)));
- }
-
- public static InetAddress maskIP(final byte[] ip, final byte[] mask)
- {
- try
- {
- return getByAddress(new byte[]
- {
- (byte) (mask[0] & ip[0]),
- (byte) (mask[1] & ip[1]),
- (byte) (mask[2] & ip[2]),
- (byte) (mask[3] & ip[3])
- });
- }
- catch(Exception _) {}
- {
- return null;
- }
- }
-
- public static InetAddress maskIP(final InetAddress ip, final InetAddress mask)
- {
- return maskIP(ip.getAddress(), mask.getAddress());
- }
-
- /*
- * This converts from an uncommon "wildcard" CIDR format
- * to "address + mask" format:
- *
- * * => 000.000.000.0/000.000.000.0
- * xxx.* => xxx.000.000.0/255.000.000.0
- * xxx.xxx.* => xxx.xxx.000.0/255.255.000.0
- * xxx.xxx.xxx.* => xxx.xxx.xxx.0/255.255.255.0
- */
- static private String normalizeFromAsterisk(final String netspec)
- {
- String[] masks = { "0.0.0.0/0.0.0.0", "0.0.0/255.0.0.0", "0.0/255.255.0.0", "0/255.255.255.0" };
- char[] srcb = netspec.toCharArray();
- int octets = 0;
- for (int i = 1; i < netspec.length(); i++)
- {
- if (srcb[i] == '.')
- {
- octets++;
- }
- }
- return (octets == 0) ? masks[0] : netspec.substring(0, netspec.length() -1 ).concat(masks[octets]);
- }
-
- /*
- * RFC 1518, 1519 - Classless Inter-Domain Routing (CIDR)
- * This converts from "prefix + prefix-length" format to
- * "address + mask" format, e.g. from xxx.xxx.xxx.xxx/yy
- * to xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy.
- */
- static private String normalizeFromCIDR(final String netspec)
- {
- final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/')+1));
- final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits)-1);
-
- return netspec.substring(0, netspec.indexOf('/') + 1) +
- Integer.toString(mask >> 24 & 0xFF, 10) + "." +
- Integer.toString(mask >> 16 & 0xFF, 10) + "." +
- Integer.toString(mask >> 8 & 0xFF, 10) + "." +
- Integer.toString(mask >> 0 & 0xFF, 10);
- }
-
- private static java.lang.reflect.Method getByAddress = null;
-
- static {
- try {
- Class inetAddressClass = Class.forName("java.net.InetAddress");
- Class[] parameterTypes = { byte[].class };
- getByAddress = inetAddressClass.getMethod("getByAddress", parameterTypes);
- } catch (Exception e) {
- getByAddress = null;
- }
- }
-
- private static InetAddress getByAddress(byte[] ip) throws java.net.UnknownHostException
- {
- InetAddress addr = null;
- if (getByAddress != null)
- {
- try
- {
- addr = (InetAddress) getByAddress.invoke(null, new Object[] { ip });
- }
- catch (IllegalAccessException e)
- {
- }
- catch (java.lang.reflect.InvocationTargetException e)
- {
- }
- }
-
- if (addr == null) {
- addr = InetAddress.getByName
- (
- Integer.toString(ip[0] & 0xFF, 10) + "." +
- Integer.toString(ip[1] & 0xFF, 10) + "." +
- Integer.toString(ip[2] & 0xFF, 10) + "." +
- Integer.toString(ip[3] & 0xFF, 10)
- );
- }
- return addr;
- }
-}
diff --git a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java b/java/common/src/test/java/org/apache/qpid/framing/FieldTableTest.java
index 16f35613d8..1ecf450551 100644
--- a/java/common/src/test/java/org/apache/qpid/framing/PropertyFieldTableTest.java
+++ b/java/common/src/test/java/org/apache/qpid/framing/FieldTableTest.java
@@ -22,8 +22,6 @@ package org.apache.qpid.framing;
import junit.framework.Assert;
import junit.framework.TestCase;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.qpid.AMQPInvalidClassException;
@@ -33,10 +31,8 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-public class PropertyFieldTableTest extends TestCase
+public class FieldTableTest extends TestCase
{
- private static final Logger _logger = LoggerFactory.getLogger(PropertyFieldTableTest.class);
-
/**
* Test that setting a similar named value replaces any previous value set on that name
*/
@@ -696,66 +692,8 @@ public class PropertyFieldTableTest extends TestCase
result.setObject("object-short", Short.MAX_VALUE);
size += 1 + EncodingUtils.encodedShortStringLength("object-short") + EncodingUtils.encodedShortLength();
Assert.assertEquals(size, result.getEncodedSize());
-
}
- // public void testEncodingSize1()
- // {
- // PropertyFieldTable table = new PropertyFieldTable();
- // int length = 0;
- // result.put("one", 1L);
- // length = EncodingUtils.encodedShortStringLength("one");
- // length += 1 + EncodingUtils.encodedLongLength();
- // assertEquals(length, result.getEncodedSize());
- //
- // result.put("two", 2L);
- // length += EncodingUtils.encodedShortStringLength("two");
- // length += 1 + EncodingUtils.encodedLongLength();
- // assertEquals(length, result.getEncodedSize());
- //
- // result.put("three", 3L);
- // length += EncodingUtils.encodedShortStringLength("three");
- // length += 1 + EncodingUtils.encodedLongLength();
- // assertEquals(length, result.getEncodedSize());
- //
- // result.put("four", 4L);
- // length += EncodingUtils.encodedShortStringLength("four");
- // length += 1 + EncodingUtils.encodedLongLength();
- // assertEquals(length, result.getEncodedSize());
- //
- // result.put("five", 5L);
- // length += EncodingUtils.encodedShortStringLength("five");
- // length += 1 + EncodingUtils.encodedLongLength();
- // assertEquals(length, result.getEncodedSize());
- //
- // //fixme should perhaps be expanded to incorporate all types.
- //
- // final ByteBuffer buffer = ByteBuffer.allocate((int) result.getEncodedSize()); // FIXME XXX: Is cast a problem?
- //
- // result.writeToBuffer(buffer);
- //
- // buffer.flip();
- //
- // long length = buffer.getUnsignedInt();
- //
- // try
- // {
- // PropertyFieldTable table2 = new PropertyFieldTable(buffer, length);
- //
- // Assert.assertEquals((Long) 1L, table2.getLong("one"));
- // Assert.assertEquals((Long) 2L, table2.getLong("two"));
- // Assert.assertEquals((Long) 3L, table2.getLong("three"));
- // Assert.assertEquals((Long) 4L, table2.getLong("four"));
- // Assert.assertEquals((Long) 5L, table2.getLong("five"));
- // }
- // catch (AMQFrameDecodingException e)
- // {
- // e.printStackTrace();
- // fail("PFT should be instantiated from bytes." + e.getCause());
- // }
- //
- // }
-
/**
* Additional test for setObject
*/
@@ -883,7 +821,6 @@ public class PropertyFieldTableTest extends TestCase
{
fail("property name are allowed to start with # and $s");
}
-
}
/**
@@ -919,7 +856,6 @@ public class PropertyFieldTableTest extends TestCase
Assert.assertEquals("1", table.getObject("n1"));
Assert.assertEquals("2", table.getObject("n2"));
Assert.assertEquals("3", table.getObject("n3"));
-
}
public void testAddAll()
@@ -952,29 +888,51 @@ public class PropertyFieldTableTest extends TestCase
assertEquals("Unexpected number of entries in table1 after addAll", 2, table1.size());
}
- private void assertBytesEqual(byte[] expected, byte[] actual)
+ /**
+ * Tests that when copying properties into a new FielTable using the addAll() method, the
+ * properties are successfully added to the destination table when the source FieldTable
+ * was created from encoded input bytes,
+ */
+ public void testAddingAllFromFieldTableCreatedUsingEncodedBytes() throws Exception
{
- Assert.assertEquals(expected.length, actual.length);
+ AMQShortString myBooleanTestProperty = new AMQShortString("myBooleanTestProperty");
- for (int index = 0; index < expected.length; index++)
- {
- Assert.assertEquals(expected[index], actual[index]);
- }
+ //Create a new FieldTable and use it to encode data into a byte array.
+ FieldTable encodeTable = new FieldTable();
+ encodeTable.put(myBooleanTestProperty, true);
+ byte[] data = encodeTable.getDataAsBytes();
+ int length = data.length;
+
+ //Verify we got the expected mount of encoded data (1B type hdr + 21B for name + 1B type hdr + 1B for boolean)
+ assertEquals("unexpected data length", 24, length);
+
+ //Create a second FieldTable from the encoded bytes
+ FieldTable tableFromBytes = new FieldTable(new DataInputStream(new ByteArrayInputStream(data)), length);
+
+ //Create a final FieldTable and addAll() from the table created with encoded bytes
+ FieldTable destinationTable = new FieldTable();
+ assertTrue("unexpected size", destinationTable.isEmpty());
+ destinationTable.addAll(tableFromBytes);
+
+ //Verify that the destination table now contains the expected entry
+ assertEquals("unexpected size", 1, destinationTable.size());
+ assertTrue("expected property not present", destinationTable.containsKey(myBooleanTestProperty));
+ assertTrue("unexpected property value", destinationTable.getBoolean(myBooleanTestProperty));
}
- private void assertBytesNotEqual(byte[] expected, byte[] actual)
+ private void assertBytesEqual(byte[] expected, byte[] actual)
{
Assert.assertEquals(expected.length, actual.length);
for (int index = 0; index < expected.length; index++)
{
- Assert.assertFalse(expected[index] == actual[index]);
+ Assert.assertEquals(expected[index], actual[index]);
}
}
public static junit.framework.Test suite()
{
- return new junit.framework.TestSuite(PropertyFieldTableTest.class);
+ return new junit.framework.TestSuite(FieldTableTest.class);
}
}
diff --git a/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java b/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
index ec06400b7d..08f7387b75 100644
--- a/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
+++ b/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
@@ -41,6 +41,7 @@ public class QpidTestCase extends TestCase
public static final String QPID_HOME = System.getProperty("QPID_HOME");
public static final String TEST_RESOURCES_DIR = QPID_HOME + "/../test-profiles/test_resources/";
public static final String TMP_FOLDER = System.getProperty("java.io.tmpdir");
+ public static final String LOG4J_CONFIG_FILE_PATH = System.getProperty("log4j.configuration.file");
private static final Logger _logger = Logger.getLogger(QpidTestCase.class);
@@ -115,12 +116,7 @@ public class QpidTestCase extends TestCase
public QpidTestCase()
{
- this("QpidTestCase");
- }
-
- public QpidTestCase(String name)
- {
- super(name);
+ super();
}
public void run(TestResult testResult)
@@ -204,6 +200,8 @@ public class QpidTestCase extends TestCase
{
System.setProperty(property, value);
}
+
+ _logger.info("Set system property \"" + property + "\" to: \"" + value + "\"");
}
/**
diff --git a/java/common/src/test/java/org/apache/qpid/test/utils/TestFileUtils.java b/java/common/src/test/java/org/apache/qpid/test/utils/TestFileUtils.java
index 056d11faaa..14dec8efad 100644
--- a/java/common/src/test/java/org/apache/qpid/test/utils/TestFileUtils.java
+++ b/java/common/src/test/java/org/apache/qpid/test/utils/TestFileUtils.java
@@ -21,6 +21,12 @@
package org.apache.qpid.test.utils;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.io.FileOutputStream;
+
+import junit.framework.TestCase;
import org.apache.qpid.util.FileUtils;
@@ -30,6 +36,7 @@ import org.apache.qpid.util.FileUtils;
public class TestFileUtils
{
private static final String SYSTEM_TMP_DIR = System.getProperty("java.io.tmpdir");
+ private static final String SUFFIX = "tmp";
/**
* Create and return a temporary directory that will be deleted on exit.
@@ -60,4 +67,87 @@ public class TestFileUtils
return testDir;
}
+
+ public static File createTempFile(TestCase testcase)
+ {
+ return createTempFile(testcase, SUFFIX);
+ }
+
+ public static File createTempFile(TestCase testcase, String suffix)
+ {
+ String prefix = testcase.getClass().getSimpleName() + "-" + testcase.getName();
+
+ File tmpFile;
+ try
+ {
+ tmpFile = File.createTempFile(prefix, suffix);
+ tmpFile.deleteOnExit();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Cannot create temporary file with prefix " + prefix + " and suffix " + SUFFIX, e);
+ }
+
+ return tmpFile;
+ }
+
+ /**
+ * Creates a temporary file from the resource name given, using the resource name as the file suffix.
+ *
+ * This is required because the tests use the jar files as their class path.
+ */
+ public static File createTempFileFromResource(TestCase testCase, String resourceName)
+ {
+ File dst = createTempFile(testCase, resourceName);
+ InputStream in = testCase.getClass().getResourceAsStream(resourceName);
+ try
+ {
+ FileUtils.copy(in, dst);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Cannot copy resource " + resourceName +
+ " to temp file " + dst.getAbsolutePath(), e);
+ }
+ dst.deleteOnExit();
+ return dst;
+ }
+
+ /**
+ * Creates a temporary file for given test with given suffix in file name.
+ * The given content is stored in the file using UTF-8 encoding.
+ */
+ public static File createTempFile(TestCase testcase, String suffix, String content)
+ {
+ File file = createTempFile(testcase, suffix);
+ if (content != null)
+ {
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream(file);
+ fos.write(content.getBytes("UTF-8"));
+ fos.flush();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Cannot add the content into temp file " + file.getAbsolutePath(), e);
+ }
+ finally
+ {
+ if (fos != null)
+ {
+ try
+ {
+ fos.close();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Cannot close output stream into temp file " + file.getAbsolutePath(), e);
+ }
+ }
+ }
+ }
+ return file;
+ }
}
diff --git a/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java b/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
index f3715f351e..12bbd20228 100644
--- a/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
+++ b/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
@@ -155,6 +155,7 @@ public class ConnectionTest extends QpidTestCase implements SessionListener
{
final Connection conn = new Connection();
conn.setConnectionDelegate(new ClientDelegate(new ConnectionSettings()));
+
conn.addConnectionListener(new ConnectionListener()
{
public void opened(Connection conn) {}
@@ -225,6 +226,12 @@ public class ConnectionTest extends QpidTestCase implements SessionListener
ssn.setSessionListener(ConnectionTest.this);
return ssn;
}
+
+ @Override
+ public void connectionStartOk(Connection conn, ConnectionStartOk ok)
+ {
+ tuneAuthorizedConnection(conn);
+ }
};
try
diff --git a/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java b/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
index 893f66c5ff..a19c2e7e43 100644
--- a/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
+++ b/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
@@ -83,6 +83,18 @@ public class TestNetworkConnection implements NetworkConnection
return null;
}
+ @Override
+ public int getMaxReadIdle()
+ {
+ return 0;
+ }
+
+ @Override
+ public int getMaxWriteIdle()
+ {
+ return 0;
+ }
+
public void setMaxWriteIdle(int idleTime)
{
diff --git a/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java b/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
index c882d3437e..bf9a5843d6 100644
--- a/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
+++ b/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
@@ -128,7 +128,8 @@ public class TransportTest extends QpidTestCase
}
public NetworkConnection connect(ConnectionSettings settings,
- Receiver<ByteBuffer> delegate, SSLContext sslContext)
+ Receiver<ByteBuffer> delegate,
+ TransportActivity transportActivity)
{
throw new UnsupportedOperationException();
}
@@ -148,7 +149,7 @@ public class TransportTest extends QpidTestCase
}
public void accept(NetworkTransportConfiguration config,
- ProtocolEngineFactory factory, SSLContext sslContext)
+ ProtocolEngineFactory factory, SSLContext sslContext)
{
throw new UnsupportedOperationException();
}
diff --git a/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java b/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
new file mode 100644
index 0000000000..5cdd7a8597
--- /dev/null
+++ b/java/common/src/test/java/org/apache/qpid/transport/network/io/IdleTimeoutTickerTest.java
@@ -0,0 +1,257 @@
+/*
+ *
+ * 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.transport.network.io;
+
+import junit.framework.TestCase;
+
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.network.TransportActivity;
+
+public class IdleTimeoutTickerTest extends TestCase implements TransportActivity, NetworkConnection
+{
+ private IdleTimeoutTicker _ticker;
+ private static final int DEFAULT_TIMEOUT = 567890;
+ private long _lastReadTime;
+ private long _lastWriteTime;
+ private long _currentTime;
+ private int _maxWriteIdle;
+ private int _maxReadIdle;
+ private boolean _readerIdle;
+ private boolean _writerIdle;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _ticker = new IdleTimeoutTicker(this, DEFAULT_TIMEOUT);
+ _ticker.setConnection(this);
+ _readerIdle = false;
+ _writerIdle = false;
+ _lastReadTime = 0l;
+ _lastWriteTime = 0l;
+ _maxReadIdle = 0;
+ _maxWriteIdle = 0;
+ }
+
+ public void testNoIdle() throws Exception
+ {
+ _maxReadIdle = 4;
+ _maxWriteIdle = 2;
+ _lastReadTime = 0;
+ _lastWriteTime = 1500;
+ _currentTime = 3000;
+ // Current time = 3s,
+ // last read = 0s, max read idle = 4s, should check in 1s
+ // last write = 1.5s, max write idle = 2s, should check in 0.5s
+ long nextTime = _ticker.tick(_currentTime);
+ assertEquals("Incorrect next tick calculation", 500l, nextTime);
+ assertFalse("Incorrectly caused reader idle", _readerIdle);
+ assertFalse("Incorrectly caused writer idle", _writerIdle);
+
+
+ // Current time = 3.4s,
+ // last read = 0s, max read idle = 4s, should check in 0.6s
+ // last write = 3.1s, max write idle = 2s, should check in 1.7s
+ _lastWriteTime = 3100;
+ _currentTime = 3400;
+ nextTime = _ticker.tick(_currentTime);
+ assertEquals("Incorrect next tick calculation", 600l, nextTime);
+ assertFalse("Incorrectly caused reader idle", _readerIdle);
+ assertFalse("Incorrectly caused writer idle", _writerIdle);
+
+ _maxReadIdle = 0;
+ nextTime = _ticker.tick(_currentTime);
+ assertEquals("Incorrect next tick calculation", 1700l, nextTime);
+ assertFalse("Incorrectly caused reader idle", _readerIdle);
+ assertFalse("Incorrectly caused writer idle", _writerIdle);
+
+ _maxWriteIdle = 0;
+ nextTime = _ticker.tick(_currentTime);
+ assertEquals("Incorrect next tick calculation", DEFAULT_TIMEOUT, nextTime);
+ assertFalse("Incorrectly caused reader idle", _readerIdle);
+ assertFalse("Incorrectly caused writer idle", _writerIdle);
+
+ }
+
+ public void testReaderIdle() throws Exception
+ {
+ _maxReadIdle = 4;
+ _maxWriteIdle = 0;
+ _lastReadTime = 0;
+ _lastWriteTime = 2500;
+ _currentTime = 4000;
+ // Current time = 4s,
+ // last read = 0s, max read idle = 4s, reader idle
+ long nextTime = _ticker.tick(_currentTime);
+
+ assertTrue(_readerIdle);
+ assertFalse(_writerIdle);
+
+ _readerIdle = false;
+
+ // last write = 2.5s, max write idle = 2s, should check in 0.5s
+ _maxWriteIdle = 2;
+ nextTime = _ticker.tick(_currentTime);
+ assertTrue(_readerIdle);
+ assertFalse(_writerIdle);
+
+ _readerIdle = false;
+ // last write = 1.5s, max write idle = 2s, should check in 0.5s
+
+ _lastWriteTime = 1500;
+ nextTime = _ticker.tick(_currentTime);
+
+ assertTrue(_readerIdle);
+ assertTrue(_writerIdle);
+
+ }
+
+ public void testWriterIdle() throws Exception
+ {
+ _maxReadIdle = 0;
+ _maxWriteIdle = 2;
+ _lastReadTime = 0;
+ _lastWriteTime = 1500;
+ _currentTime = 4000;
+ // Current time = 4s,
+ // last write = 1.5s, max write idle = 2s, writer idle
+ long nextTime = _ticker.tick(_currentTime);
+
+ assertTrue(_writerIdle);
+ assertFalse(_readerIdle);
+ assertEquals(2000l,nextTime);
+
+ _writerIdle = false;
+ _lastWriteTime = 1500;
+ _maxReadIdle = 5;
+
+ nextTime = _ticker.tick(_currentTime);
+
+ assertTrue(_writerIdle);
+ assertFalse(_readerIdle);
+ assertEquals(1000l,nextTime);
+
+ }
+
+ //-------------------------------------------------------------------------
+ // Implement TransportActivity methods
+ //-------------------------------------------------------------------------
+
+ @Override
+ public long getLastReadTime()
+ {
+ return _lastReadTime;
+ }
+
+ @Override
+ public long getLastWriteTime()
+ {
+ return _lastWriteTime;
+ }
+
+ @Override
+ public void writerIdle()
+ {
+ _writerIdle = true;
+ _lastWriteTime = _currentTime;
+ }
+
+ @Override
+ public void readerIdle()
+ {
+ _readerIdle = true;
+ }
+
+ //-------------------------------------------------------------------------
+ // Implement NetworkConnection methods
+ // Only actually use those relating to idle timeouts
+ //-------------------------------------------------------------------------
+
+ @Override
+ public Sender<ByteBuffer> getSender()
+ {
+ return null;
+ }
+
+ @Override
+ public void start()
+ {
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public SocketAddress getRemoteAddress()
+ {
+ return null;
+ }
+
+ @Override
+ public SocketAddress getLocalAddress()
+ {
+ return null;
+ }
+
+ @Override
+ public void setMaxWriteIdle(int sec)
+ {
+ _maxWriteIdle = sec;
+ }
+
+ @Override
+ public void setMaxReadIdle(int sec)
+ {
+ _maxReadIdle = sec;
+ }
+
+ @Override
+ public void setPeerPrincipal(Principal principal)
+ {
+ }
+
+ @Override
+ public Principal getPeerPrincipal()
+ {
+ return null;
+ }
+
+ @Override
+ public int getMaxReadIdle()
+ {
+ return _maxReadIdle;
+ }
+
+ @Override
+ public int getMaxWriteIdle()
+ {
+ return _maxWriteIdle;
+ }
+}
diff --git a/java/ivy.nexus.xml b/java/ivy.nexus.xml
index 61ae9f315b..c39f466da3 100644
--- a/java/ivy.nexus.xml
+++ b/java/ivy.nexus.xml
@@ -39,6 +39,42 @@
<artifact name="qpid-broker" type="jar.asc" ext="jar.asc"/>
<artifact name="qpid-broker" type="source" ext="jar" e:classifier="sources"/>
<artifact name="qpid-broker" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-access-control" type="pom" ext="pom"/>
+ <artifact name="qpid-broker-plugins-access-control" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-broker-plugins-access-control" type="jar" ext="jar"/>
+ <artifact name="qpid-broker-plugins-access-control" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-broker-plugins-access-control" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-access-control" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-management-http" type="pom" ext="pom"/>
+ <artifact name="qpid-broker-plugins-management-http" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-broker-plugins-management-http" type="jar" ext="jar"/>
+ <artifact name="qpid-broker-plugins-management-http" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-broker-plugins-management-http" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-management-http" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="pom" ext="pom"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="jar" ext="jar"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-broker-plugins-management-jmx" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-common" type="pom" ext="pom"/>
+ <artifact name="qpid-amqp-1-0-common" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-amqp-1-0-common" type="jar" ext="jar"/>
+ <artifact name="qpid-amqp-1-0-common" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-amqp-1-0-common" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-common" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client" type="pom" ext="pom"/>
+ <artifact name="qpid-amqp-1-0-client" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-amqp-1-0-client" type="jar" ext="jar"/>
+ <artifact name="qpid-amqp-1-0-client" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-amqp-1-0-client" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="pom" ext="pom"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="jar" ext="jar"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-amqp-1-0-client-jms" type="source.asc" ext="jar.asc" e:classifier="sources"/>
<artifact name="qpid-management-common" type="pom" ext="pom"/>
<artifact name="qpid-management-common" type="pom.asc" ext="pom.asc"/>
<artifact name="qpid-management-common" type="jar" ext="jar"/>
@@ -51,6 +87,12 @@
<artifact name="qpid-bdbstore" type="jar.asc" ext="jar.asc"/>
<artifact name="qpid-bdbstore" type="source" ext="jar" e:classifier="sources"/>
<artifact name="qpid-bdbstore" type="source.asc" ext="jar.asc" e:classifier="sources"/>
+ <artifact name="qpid-bdbstore-jmx" type="pom" ext="pom"/>
+ <artifact name="qpid-bdbstore-jmx" type="pom.asc" ext="pom.asc"/>
+ <artifact name="qpid-bdbstore-jmx" type="jar" ext="jar"/>
+ <artifact name="qpid-bdbstore-jmx" type="jar.asc" ext="jar.asc"/>
+ <artifact name="qpid-bdbstore-jmx" type="source" ext="jar" e:classifier="sources"/>
+ <artifact name="qpid-bdbstore-jmx" type="source.asc" ext="jar.asc" e:classifier="sources"/>
</publications>
<dependencies/>
diff --git a/java/ivy.retrieve.xml b/java/ivy.retrieve.xml
index 3af847a48a..5998a3e78e 100644
--- a/java/ivy.retrieve.xml
+++ b/java/ivy.retrieve.xml
@@ -57,7 +57,6 @@
<dependency org="log4j" name="log4j" rev="1.2.16" transitive="false"/>
<dependency org="org.apache.maven" name="maven-ant-tasks" rev="2.1.1" transitive="false"/>
<dependency org="org.mockito" name="mockito-all" rev="1.9.0" transitive="false"/>
- <dependency org="org.apache.felix" name="org.apache.felix.main" rev="2.0.5" transitive="false"/>
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" transitive="false"/>
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.4" transitive="false"/>
<dependency org="org.eclipse.jetty" name="jetty-server" rev="7.6.3.v20120416" transitive="false"/>
@@ -70,6 +69,8 @@
<dependency org="org.eclipse.jetty" name="jetty-util" rev="7.6.3.v20120416" transitive="false"/>
<dependency org="org.dojotoolkit" name="dojo-war" rev="1.7.2" transitive="false"/>
<dependency org="xalan" name="xalan" rev="2.7.0" transitive="false"/>
+ <dependency org="velocity" name="velocity" rev="1.4" transitive="false"/>
+ <dependency org="velocity" name="velocity-dep" rev="1.4" transitive="false"/>
<!-- The following are optional dependencies, for modules providing optional functionlity or
for use in optional build/test steps. Their optional status is usually indicative of licences
diff --git a/java/ivysettings.retrieve.xml b/java/ivysettings.retrieve.xml
index e31af1e5b5..cc50121821 100644
--- a/java/ivysettings.retrieve.xml
+++ b/java/ivysettings.retrieve.xml
@@ -16,7 +16,7 @@
-->
<ivysettings>
<property name="ivy.default.resolver" value="chain" override="false"/>
- <property name="ivy.localfs.root" value="${project.root}/localfs_repo" override="false"/>
+ <property name="ivy.localfs.root" value="${project.root}/lib/localfs_repo" override="false"/>
<property name="ivy.localfs.pattern" value="[artifact]-[revision](-[classifier]).[ext]" override="false"/>
<settings defaultResolver="${ivy.default.resolver}"/>
diff --git a/java/jca/README-JBOSS-EAP6.txt b/java/jca/README-JBOSS-EAP6.txt
new file mode 100644
index 0000000000..219bfb6468
--- /dev/null
+++ b/java/jca/README-JBOSS-EAP6.txt
@@ -0,0 +1,183 @@
+Qpid JCA Resource Adapter
+
+JBoss EAP 6.x Installation and Configuration Instructions
+
+Overview
+========
+The Qpid Resource Adapter is a JCA 1.5 compliant resource adapter that allows
+for JEE integration between EE applications and AMQP 0.10 message brokers.
+
+The adapter provides both outbound and inbound connectivity and
+exposes a variety of options to fine tune your messaging applications.
+Currently the adapter only supports C++ based brokers and has only been tested with Apache Qpid C++ broker.
+
+The following document explains how to configure the resource adapter for deployment in JBoss EAP 6.x.
+
+Deployment
+==========
+To deploy the Qpid JCA adapter in the JBoss EAP 6 environment, copy the qpid-ra-<version>.rar file
+to your JBoss deployment directory. By default this can be found at
+
+JBOSS_ROOT/<server-config>/deployments
+
+where JBOSS_ROOT denotes the root directory of your JBoss EAP 6.x installation and <server-config> denotes the
+particular server configuration for your applicationd development. Currently, JBoss EAP 6 provides two configurations
+by default standalone and domain. This documentation assumes the standalone server configuration, though the process
+to configure and deploy the Qpid JCA adapter is largely the same between the two. Assuming the standalone configuration
+the deployment location above would be
+
+JBOSS_ROOT/standalone/deployments
+
+Note, as opposed to prior versions of EAP, copying a RAR file to the deployment location does not automatically
+start and deploy the adapter. A separate manual configuration step is required which is explained in the following
+section.
+
+Configuration
+=============
+The EAP 6.x environment uses an XML based configuration scheme that is fundamentally different than prior versions
+of EAP. As previously mentioned, EAP 6.x provides two server configuration types, standalone and domain. Each come with
+a different set of configuration files that are tailored to varying types of server environments. Configuration locations
+can be found at
+
+JBOSS_ROOT/<server-config>/configuration
+
+The varying XML files are named
+
+<server-config>-full.xml
+<server-config>-full-ha.xml
+<server-config>.xml
+
+where each XML file denotes the capabilites of the server. This document assumes a minimal server configuration in
+the standalone server environment. While each configuration file provides a variety of options, this document is
+only concerned with the configuration of the JCA adapter. Please consult the EAP 6.x documentation for other
+options and configuration scenarios.
+
+The EAP 6.x infrastructure is built upon the notion of varying subsystem where subsystem generally corresponds
+to one particular piece of functionality. Typical examples are EJB, JAXR etc. In order to configure the Qpid JCA adapter
+we need to modify the ejb and resource-adapters subsystems in order to tell EAP 6.x about our RAR deployment as well
+as the RAR that will provide JMS provider functionality.
+
+Note, JCA in EAP 6.x involves two subsystems, jca and resource-adapters. The former subsytem provides capabilities for
+all JCA deployments (the JCA runtime environment) where the resource-adapters subsystem is particular to an invidual JCA
+deployment. Here we are only concerned with the latter. Please consult the EAP 6.x documentation for more general JCA
+configuration options as well as other subsystems.
+
+Each subsystem is configured in an XML fragment and is versioned separately. Subsystem versions will change over
+time so this document may not reflect the most current version, but the Qpid JCA configuration options remain
+unchanged across subsystem regardless of version or release date.
+
+The following XML fragment replaces the default messaging provider in the EAP 6.x environment
+
+ <subsystem xmlns="urn:jboss:domain:ejb3:1.2">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <mdb>
+ <resource-adapter-ref resource-adapter-name="qpid-ra-<rar-version>.rar"/>
+ <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
+ </mdb>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple" aliases="NoPassivationCache"/>
+ <cache name="passivating" passivation-store-ref="file" aliases="SimpleStatefulCache"/>
+ </caches>
+ <passivation-stores>
+ <file-passivation-store name="file"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default">
+ <data-store path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </timer-service>
+ <remote connector-ref="remoting-connector" thread-pool-name="default"/>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ </subsystem>
+
+The only real lines we are concerned with are
+
+ <mdb>
+ <resource-adapter-ref resource-adapter-name="qpid-ra-<rar-version>.rar"/>
+ <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
+ </mdb>
+
+however, the complete fragment is provided for clarity.
+
+The following XML fragment provides a minimal example configuration in the EAP 6 environment. Here we are configuring
+an XA aware ManagedConnectionFactory and two JMS destinations (queue and topic)
+
+ <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0">
+ <resource-adapters>
+ <resource-adapter>
+ <archive>
+ qpid-ra-<rar-version>.rar
+ </archive>
+ <transaction-support>
+ XATransaction
+ </transaction-support>
+ <config-property name="connectionURL">
+ amqp://anonymous:passwd@client/test?brokerlist='tcp://localhost?sasl_mechs='PLAIN''
+ </config-property>
+ <config-property name="TransactionManagerLocatorClass">
+ org.apache.qpid.ra.tm.JBoss7TransactionManagerLocator
+ </config-property>
+ <config-property name="TransactionManagerLocatorMethod">
+ getTm
+ </config-property>
+ <connection-definitions>
+ <connection-definition class-name="org.apache.qpid.ra.QpidRAManagedConnectionFactory" jndi-name="QpidJMSXA" pool-name="QpidJMSXA">
+ <config-property name="connectionURL">
+ amqp://anonymous:passwd@client/test?brokerlist='tcp://localhost?sasl_mechs='PLAIN''
+ </config-property>
+ <config-property name="SessionDefaultType">
+ javax.jms.Queue
+ </config-property>
+ </connection-definition>
+ </connection-definitions>
+ <admin-objects>
+ <admin-object class-name="org.apache.qpid.ra.admin.QpidTopicImpl" jndi-name="java:jboss/exported/GoodByeTopic" use-java-context="false" pool-name="GoodByeTopic">
+ <config-property name="DestinationAddress">
+ amq.topic/hello.Topic
+ </config-property>
+ </admin-object>
+ <admin-object class-name="org.apache.qpid.ra.admin.QpidQueueImpl" jndi-name="java:jboss/exported/HelloQueue" use-java-context="false" pool-name="HelloQueue">
+ <config-property name="DestinationAddress">
+ hello.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}
+ </config-property>
+ </admin-object>
+ </admin-objects>
+ </resource-adapter>
+ </resource-adapters>
+ </subsystem>
+
+
+
+Note, while this document assumes that you are modifying the standalone.xml file directly, an alternative to this approach would be
+to make a copy of the file, apply the modifications above and start the EAP instance with the new configuration
+
+JBOSS_HOME/bin/standalone.sh -c your-modified-config.xml
+
+Regardless of the approach that you use, once the modifications have been made you can start your EAP 6.x instance and the Qpid JCA
+adapter will be deployed and ready for use. If property deployed and configured, you should see something in the log files or console
+resembling the following:
+
+INFO [org.apache.qpid.ra.QpidResourceAdapter] (MSC service thread 1-4) Qpid resource adapter started
+
+
+Notes
+=====
+While the differences between the EAP 5.x and 6.x environments may appear to be dramatic, the configuration options and functionality of the Qpid
+JCA adapter are not. The README.txt file outlines general configuration options that remain unchanged between the respective EAP environments.
+
diff --git a/java/jca/README-JBOSS.txt b/java/jca/README-JBOSS.txt
index 77bf91e6dd..e88643e0f2 100644
--- a/java/jca/README-JBOSS.txt
+++ b/java/jca/README-JBOSS.txt
@@ -61,7 +61,7 @@ XA ConnectionFactory
<xa-transaction/>
<rar-name>qpid-ra-<ra-version>.rar</rar-name>
<connection-definition>org.apache.qpid.ra.QpidRAConnectionFactory</connection-definition>
- <config-property name="connectionURL">amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?sasl_mechs='ANONYMOUS''</config-property>
+ <config-property name="ConnectionURL">amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?sasl_mechs='PLAIN''</config-property>
<max-pool-size>20</max-pool-size>
</tx-connection-factory>
@@ -79,11 +79,11 @@ Local ConnectionFactory
=======================
<tx-connection-factory>
<jndi-name>QpidJMS</jndi-name>
- <rar-name>qpid-ra-0.10.rar</rar-name>
+ <rar-name>qpid-ra-<ra-version>.rar</rar-name>
<local-transaction/>
- <config-property name="useLocalTx" type="java.lang.Boolean">true</config-property>
- <config-property name="connectionURL">amqp://anonymous:@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='ANONYMOUS''</config-property>
- <connection-definition>org.apache.qpid.ra.QpidRAConnectionFactory</connection-definition>
+ <config-property name="UseLocalTx" type="java.lang.Boolean">true</config-property>
+ <config-property name="ConnectionURL">amqp://anonymous:@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='PLAIN''
+ </config-property> <connection-definition>org.apache.qpid.ra.QpidRAConnectionFactory</connection-definition>
<max-pool-size>20</max-pool-size>
</tx-connection-factory>
@@ -100,11 +100,10 @@ provides two such objects
<mbean code="org.jboss.resource.deployment.AdminObject"
name="qpid.jca:name=HelloQueue">
<attribute name="JNDIName">Hello</attribute>
- <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-0.10.rar'</depends>
+ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-<ra-version>.rar'</depends>
<attribute name="Type">javax.jms.Destination</attribute>
<attribute name="Properties">
- destinationType=QUEUE
- destinationAddress=amq.direct
+ DestinationAddress=amq.direct
</attribute>
</mbean>
@@ -113,16 +112,15 @@ The above XML defines a JMS Queue which is bound into JNDI as
queue/HelloQueue
This destination can be retrieved from JNDI and be used for the consumption or production of messages. The desinationAddress property
-can be customized for your environment. Please see the Qpid Java Client documentation for specific configuration options.
+can be customized for your environment. Please see the Qpid Java Client documentation for specific configuration options.
<mbean code="org.jboss.resource.deployment.AdminObject"
name="qpid.jca:name=HelloTopic">
<attribute name="JNDIName">HelloTopic</attribute>
- <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-0.10.rar'</depends>
+ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-<ra-version>.rar'</depends>
<attribute name="Type">javax.jms.Destination</attribute>
<attribute name="Properties">
- destinationType=TOPIC
- destinationAddress=amq.topic
+ DestinationAddress=amq.topic
</attribute>
</mbean>
@@ -138,10 +136,10 @@ can be customized for your environment. Please see the Qpid Java Client document
<mbean code="org.jboss.resource.deployment.AdminObject"
name="qpid.jca:name=QpidConnectionFactory">
<attribute name="JNDIName">QpidConnectionFactory</attribute>
- <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-0.10.rar'</depends>
+ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='qpid-ra-<ra-version>.rar'</depends>
<attribute name="Type">javax.jms.ConnectionFactory</attribute>
<attribute name="Properties">
- connectionURL=amqp://anonymous:@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='ANONYMOUS''
+ ConnectionURL=amqp://anonymous:@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='PLAIN''
</attribute>
</mbean>
diff --git a/java/jca/build.xml b/java/jca/build.xml
index 934514aa52..42a19ff83a 100644
--- a/java/jca/build.xml
+++ b/java/jca/build.xml
@@ -22,18 +22,26 @@
<property name="module.depends" value="common client"/>
<property name="module.name" value="jca"/>
+ <!-- Hack to make the renamed module jars available on the module test classpath -->
+ <property name="module.test.depends" value="ra ra/tests"/>
+
+ <!-- Import common.xml to make the properties it defines available before importing module.xml -->
+ <import file="../common.xml"/>
+
+ <!-- Override the standard output jar names before importing module.xml, to produce
+ artifacts that use ra in the name instead of jca like the module should -->
+ <property name="module.test.jar" value="${build.lib}/${project.name}-ra-tests-${project.version}.jar"/>
+ <property name="module.jar" value="${build.lib}/${project.name}-ra-${project.version}.jar"/>
+ <property name="module.source.jar" value="${build.lib}/${project.name}-ra-${project.version}-sources.jar"/>
<import file="../module.xml"/>
<property name="module.rar" value="${build.lib}/${project.name}-ra-${project.version}.rar"/>
+ <property name="rar.resources" value="rar/src/main/resources"/>
- <property name="module.resources" value="src/main/resources"/>
-
- <target name="rar" depends="jar">
- <!--Note we need to do this as we need to keep the ra in the name of the artificats but we can't override the module.jar property which is based on the directory name-->
- <move file="${build.lib}/${project.name}-${module.name}-${project.version}.jar" tofile="${build.lib}/${project.name}-ra-${project.version}.jar"/>
+ <target name="rar" depends="jar" description="creates a rar file containing the module jar, client jars, etc">
<jar destfile="${module.rar}">
- <fileset dir="${module.resources}">
+ <fileset dir="${rar.resources}">
<include name="**/*.xml"/>
</fileset>
<fileset dir="${build.lib}">
@@ -67,6 +75,9 @@
<target name="examples" depends="example-properties-file, example-jars"/>
- <target name="build" depends="rar, examples"/>
+ <target name="postbuild" depends="rar, examples"/>
+ <!-- Override module.xml 'libs' target to avoid copying the jar files dependencies
+ into the 'build/lib' dir, since they will be supplied by the app server -->
+ <target name="libs"/>
</project>
diff --git a/java/jca/src/main/resources/META-INF/jboss-ra.xml b/java/jca/rar/src/main/resources/META-INF/jboss-ra.xml
index f459b1efc1..f459b1efc1 100644
--- a/java/jca/src/main/resources/META-INF/jboss-ra.xml
+++ b/java/jca/rar/src/main/resources/META-INF/jboss-ra.xml
diff --git a/java/jca/src/main/resources/META-INF/ra.xml b/java/jca/rar/src/main/resources/META-INF/ra.xml
index a9374f52d7..a9374f52d7 100755
--- a/java/jca/src/main/resources/META-INF/ra.xml
+++ b/java/jca/rar/src/main/resources/META-INF/ra.xml
diff --git a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java
index a948948d6a..d7ca29e04a 100644
--- a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java
+++ b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java
@@ -27,13 +27,17 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
-import javax.jms.ConnectionFactory;
import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.naming.NamingException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.spi.ObjectFactory;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
import org.apache.qpid.client.AMQConnectionFactory;
@@ -44,7 +48,7 @@ import org.slf4j.LoggerFactory;
*
*
*/
-public class QpidConnectionFactoryProxy implements Externalizable, Referenceable, ConnectionFactory, Serializable
+public class QpidConnectionFactoryProxy implements QueueConnectionFactory, TopicConnectionFactory, Externalizable, Referenceable, Serializable
{
private static final Logger _log = LoggerFactory.getLogger(QpidDestinationProxy.class);
@@ -100,13 +104,6 @@ public class QpidConnectionFactoryProxy implements Externalizable, Referenceable
try
{
_delegate = new AMQConnectionFactory(getConnectionURL());
- /*
- QpidResourceAdapter ra = new QpidResourceAdapter();
- QpidRAManagedConnectionFactory mcf = new QpidRAManagedConnectionFactory();
- mcf.setResourceAdapter(ra);
- mcf.setConnectionURL(getConnectionURL());
- delegate = new QpidRAConnectionFactoryImpl(mcf, null);
- */
return ((Referenceable) _delegate).getReference();
}
catch(Exception e)
@@ -162,7 +159,63 @@ public class QpidConnectionFactoryProxy implements Externalizable, Referenceable
*/
public Connection createConnection(final String userName, final String password) throws JMSException
{
- return _delegate.createConnection(userName, password);
+ try
+ {
+ if(_delegate == null)
+ {
+ getReference();
+ }
+
+ return _delegate.createConnection(userName, password);
+ }
+ catch(Exception e)
+ {
+ throw new JMSException(e.getMessage());
+ }
+ }
+
+ /**
+ * Create a queue connection
+ * @return The queue connection
+ * @exception JMSException Thrown if the operation fails
+ */
+ public QueueConnection createQueueConnection() throws JMSException
+ {
+ return (QueueConnection)createConnection();
+ }
+
+ /**
+ * Create a queue connection
+ * @param userName The user name
+ * @param password The password
+ * @return The connection
+ * @exception JMSException Thrown if the operation fails
+ */
+ public QueueConnection createQueueConnection(final String userName, final String password) throws JMSException
+ {
+ return (QueueConnection)createConnection(userName, password);
+ }
+
+ /**
+ * Create a topic connection
+ * @return The topic connection
+ * @exception JMSException Thrown if the operation fails
+ */
+ public TopicConnection createTopicConnection() throws JMSException
+ {
+ return (TopicConnection)createConnection();
+ }
+
+ /**
+ * Create a topic connection
+ * @param userName The user name
+ * @param password The password
+ * @return The topic connection
+ * @exception JMSException Thrown if the operation fails
+ */
+ public TopicConnection createTopicConnection(final String userName, final String password) throws JMSException
+ {
+ return (TopicConnection)createConnection(userName, password);
}
}
diff --git a/java/management/common/src/main/java/management-common.bnd b/java/management/common/src/main/java/management-common.bnd
index 5a6be6bb15..5ae9791299 100644
--- a/java/management/common/src/main/java/management-common.bnd
+++ b/java/management/common/src/main/java/management-common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.19.0
+ver: 0.21.0
Bundle-SymbolicName: qpid-management-common
Bundle-Version: ${ver}
diff --git a/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java b/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java
deleted file mode 100644
index 4582dc4088..0000000000
--- a/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ConfigurationManagement.java
+++ /dev/null
@@ -1,41 +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.management.common.mbeans;
-
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-
-import javax.management.MBeanOperationInfo;
-
-public interface ConfigurationManagement
-{
-
- String TYPE = "ConfigurationManagement";
-
- /**
- * Reload the
- * @throws ConfigurationException
- */
- @MBeanOperation(name="reloadSecurityConfiguration",
- description = "Force a reload of the security configuration sections",
- impact = MBeanOperationInfo.ACTION)
- void reloadSecurityConfiguration() throws Exception;
-
-}
diff --git a/java/management/example/src/main/java/org/apache/qpid/example/jmxexample/AddQueue.java b/java/management/example/src/main/java/org/apache/qpid/example/jmxexample/AddQueue.java
index b858742c4e..f82408bd27 100644
--- a/java/management/example/src/main/java/org/apache/qpid/example/jmxexample/AddQueue.java
+++ b/java/management/example/src/main/java/org/apache/qpid/example/jmxexample/AddQueue.java
@@ -36,15 +36,14 @@ import org.apache.qpid.management.common.mbeans.ManagedExchange;
public class AddQueue
{
-
public static void main(String[] args)
{
//Example: add 'newqueue' to the 'test' virtualhost and bind to the 'amq.direct' exchange
//TODO: take these parameters as arguments
-
+
addQueue("test", "amq.direct", "newqueue");
}
-
+
private static JMXConnector getJMXConnection() throws Exception
{
//TODO: Take these parameters as main+method arguments
@@ -52,52 +51,55 @@ public class AddQueue
int port = 8999;
String username = "admin";
String password = "admin";
-
+
Map<String, Object> env = new HashMap<String, Object>();
JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi");
//Add user credential's to environment map for RMIConnector startup.
env.put(JMXConnector.CREDENTIALS, new String[] {username,password});
-
+
return JMXConnectorFactory.connect(jmxUrl, env);
}
-
- public static boolean addQueue(String virHost, String exchName, String queueName) {
+ public static boolean addQueue(String virHost, String exchName, String queueName)
+ {
JMXConnector jmxc = null;
try
{
jmxc = getJMXConnection();
-
+
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName hostManagerObjectName = new ObjectName(
"org.apache.qpid:" +
"type=VirtualHost.VirtualHostManager," +
- "VirtualHost=" + virHost + ",*");
+ "VirtualHost=" + ObjectName.quote(virHost) + ",*");
Set<ObjectName> vhostManagers = mbsc.queryNames(hostManagerObjectName, null);
-
+
if(vhostManagers.size() == 0)
{
+ System.out.println("VirtualHostManager MBean wasnt found: " + virHost);
+
//The vhostManager MBean wasnt found, cant procede
return false;
}
-
+
ManagedBroker vhostManager = (ManagedBroker) MBeanServerInvocationHandler.newProxyInstance(
mbsc, (ObjectName) vhostManagers.toArray()[0], ManagedBroker.class, false);
ObjectName customExchangeObjectName = new ObjectName(
"org.apache.qpid:" +
"type=VirtualHost.Exchange," +
- "VirtualHost=" + virHost + "," +
- "name=" + exchName + "," +
- "ExchangeType=direct,*");
+ "VirtualHost=" + ObjectName.quote(virHost) + "," +
+ "name=" + ObjectName.quote(exchName) + ",*");
Set<ObjectName> exchanges = mbsc.queryNames(customExchangeObjectName, null);
-
+
if(exchanges.size() == 0)
{
+ System.out.println("Exchange wasnt found: " + exchName);
+
//The exchange doesnt exist, cant procede.
return false;
}
@@ -105,12 +107,14 @@ public class AddQueue
//create the MBean proxy
ManagedExchange managedExchange = (ManagedExchange) MBeanServerInvocationHandler.newProxyInstance(
mbsc, (ObjectName) exchanges.toArray()[0], ManagedExchange.class, false);
-
+
try
{
//create the new durable queue and bind it.
vhostManager.createNewQueue(queueName, null, true);
+ System.out.println("Created queue: " + queueName);
managedExchange.createNewBinding(queueName,queueName);
+ System.out.println("Bound queue to exchange: "+ exchName);
}
catch (Exception e)
{
@@ -126,7 +130,7 @@ public class AddQueue
{
System.out.println("Could not add queue due to error :" + e.getMessage());
e.printStackTrace();
- }
+ }
finally
{
if(jmxc != null)
@@ -141,9 +145,8 @@ public class AddQueue
}
}
}
-
+
return false;
-
}
}
diff --git a/java/module.xml b/java/module.xml
index af77d84e86..9146403d04 100644
--- a/java/module.xml
+++ b/java/module.xml
@@ -48,16 +48,19 @@
<property name="module.api" location="${build.api}/${module}/"/>
<property name="module.test.api" location="${build.test.api}/${module}"/>
<property name="module.test.classes" location="${module.build}/test/classes"/>
- <property name="module.test.resources" location="${module.build}/test/resources"/>
+ <property name="module.test.resources" location="src/test/resources"/>
<property name="module.results" location="${build.results}/${module}"/>
<property name="module.failed" location="${module.results}/FAILED"/>
<property name="module.src" location="src/main/java"/>
<property name="module.test.src" location="src/test/java"/>
<property name="module.bin" location="bin"/>
<property name="module.etc" location="etc"/>
- <property name="module.src.resources.metainf" location="src/main/resources/META-INF"/>
- <property name="module.metainf" location="${module.build}/META-INF"/>
-
+
+ <property name="module.src.resources" location="src/main/resources"/>
+ <property name="module.src.resources.metainf" location="${module.src.resources}/META-INF"/>
+ <property name="module.resources.dir" location="resources/"/>
+ <property name="module.metainf" location="${module.build}/META-INF"/>
+
<property name="module.namever" value="${project.name}-${module.name}-${project.version}"/>
<property name="module.namever.osgi" value="${project.name}-${module.name}_${project.version}.0.osgi"/>
<property name="module.release.base" value="${basedir}/release"/>
@@ -74,6 +77,7 @@
<property name="broker.log.prefix" value="BROKER: "/>
<property name="broker.log.interleave" value="true"/>
+ <property name="module.jar" location="${build.lib}/${project.name}-${module.name}-${project.version}.jar"/>
<property name="module.qpid.jar" location="${module.release.lib}/qpid-all.jar"/>
<basename property="qpid.jar.name" file="${module.qpid.jar}"/>
@@ -84,7 +88,10 @@
<available property="module.test.src.exists" file="${module.test.src}"/>
<available property="module.etc.exists" file="${module.etc}"/>
<available property="module.bin.exists" file="${module.bin}"/>
+ <available property="module.src.resources.exists" file="${module.src.resources}"/>
+ <available property="module.test.src.resources.exists" file="${module.test.resources}"/>
<available property="module.src.resources.metainf.exists" file="${module.src.resources.metainf}"/>
+ <available property="module.resources.dir.exists" file="${module.resources.dir}"/>
<property name="module.source.jar"
location="${build.lib}/${project.name}-${module.name}-${project.version}-sources.jar"/>
@@ -94,15 +101,6 @@
<property name="module.test.depends" value=""/>
<property name="module.test.excludes" value=""/>
- <map property="module.depends.path" value="${module.depends}" join="${path.separator}">
- <globmapper from="*" to="${build.scratch}/*/classes"/>
- </map>
-
- <map property="module.test.depends.path" value="${module.test.depends}" join="${path.separator}">
- <globmapper from="*" to="${build.scratch}/*/classes"/>
- </map>
-
-
<!-- Add depenencies dependencies to path -->
<map property="module.depends.libs" value="${module.depends}" join=" ">
<chainedmapper>
@@ -160,30 +158,57 @@
<pathelement location="${module.test.src}"/>
</path>
- <condition property="module.jar"
- value="${build.plugins}/${project.name}-${module.name}-${project.version}.jar"
- else="${build.lib}/${project.name}-${module.name}-${project.version}.jar">
- <and>
- <isset property="module.plugin"/>
- <istrue value="${module.plugin}"/>
- </and>
- </condition>
-
<property name="module.test.jar"
location="${build.lib}/${project.name}-${module.name}-tests-${project.version}.jar"/>
+ <map property="module.depends.jars" value="${module.depends}" join=",">
+ <globmapper from="*" to="${project.name}-*-${project.version}.jar"/>
+ <filtermapper>
+ <replacestring from="/" to="-"/>
+ </filtermapper>
+ </map>
+
+ <map property="module.depends.jars.path" value="${module.depends}" join="${path.separator}">
+ <filtermapper>
+ <replacestring from="/" to="-"/>
+ </filtermapper>
+
+ <globmapper from="*" to="${build.lib}/${project.name}-*-${project.version}.jar"/>
+ </map>
+
+ <map property="module.test.depends.jars.path" value="${module.test.depends}" join="${path.separator}">
+ <filtermapper>
+ <replacestring from="/" to="-"/>
+ </filtermapper>
+ <globmapper from="*" to="${build.lib}/${project.name}-*-${project.version}.jar"/>
+ </map>
+
+ <!-- used for building the module -->
<path id="module.class.path">
- <pathelement location="${module.classes}"/>
- <pathelement path="${module.depends.path}"/>
+ <pathelement path="${module.depends.jars.path}"/>
<path refid="module.libs"/>
</path>
+ <!-- used at runtime -->
+ <path id="module.runtime.class.path">
+ <pathelement location="${module.jar}"/>
+ <pathelement path="${module.depends.jars.path}"/>
+ <path refid="module.libs"/>
+ </path>
+
+ <!-- used to build the tests -->
<path id="module.test.path">
- <pathelement path="${module.test.classes}"/>
- <path refid="module.class.path"/>
- <pathelement path="${module.test.depends.path}"/>
+ <path refid="module.runtime.class.path"/>
+ <pathelement path="${module.test.depends.jars.path}"/>
+ <path refid="module.test.libs"/>
+ </path>
+
+ <!-- used to run the tests -->
+ <path id="module.test.runtime.path">
+ <pathelement path="${module.test.jar}"/>
+ <path refid="module.runtime.class.path"/>
+ <pathelement path="${module.test.depends.jars.path}"/>
<path refid="module.test.libs"/>
- <pathelement path="${module.test.resources}"/>
</path>
<property name="javac.deprecation" value="off"/>
@@ -197,14 +222,21 @@
<echo-prop name="module.name"/>
<echo-prop name="module.jar"/>
<echo-prop name="module.depends"/>
- <echo-prop name="module.depends.path"/>
+
<echo-prop name="module.test.depends"/>
- <echo-prop name="module.test.depends.path"/>
+
<echo-prop name="module.depends.libs"/>
<echo-prop name="module.test.depends.libs"/>
+
+ <echo-prop name="module.depends.jars"/>
+ <echo-prop name="module.depends.jars.path"/>
+ <echo-prop name="module.test.depends.jars.path"/>
+
<echo-path refid="module.src.path"/>
<echo-path refid="module.class.path"/>
+ <echo-path refid="module.runtime.class.path"/>
<echo-path refid="module.test.path"/>
+ <echo-path refid="module.test.runtime.path"/>
</target>
<target name="prepare">
@@ -212,7 +244,7 @@
<mkdir dir="${build.etc}"/>
<mkdir dir="${build.lib}"/>
<mkdir dir="${build.results}"/>
- <mkdir dir="${build.plugins}"/>
+ <mkdir dir="${build.scratch.broker.plugins.lib}"/>
<mkdir dir="${module.classes}"/>
<mkdir dir="${module.precompiled}"/>
<mkdir dir="${module.api}"/>
@@ -229,7 +261,7 @@
<arg line='-o "${build.scratch}/qpid-${module.name}.pom"'/>
<arg line="-u ${project.url}"/>
<arg line="-g ${project.groupid}"/>
- <arg line="-v ${project.version}${maven.version.suffix}"/>
+ <arg line="-v ${project.version.maven}${maven.version.suffix}"/>
<arg line="-p qpid"/>
<arg line='-m "${module.depends}"'/>
<arg line="-a ${module.name}"/>
@@ -239,9 +271,7 @@
</jython>
</target>
- <target name="release-mvn" depends="pom" if="module.genpom" description="Install the artifacts into the local repository and prepare the release">
- <antcall target="build"/>
-
+ <target name="release-mvn" depends="build,pom" if="module.genpom" description="Install the artifacts into the local repository and prepare the release artifacts">
<artifact:pom id="module.pom" file="${build.scratch}/qpid-${module.name}.pom"/>
<artifact:install file="${module.jar}" pomRefId="module.pom" settingsFile="${maven.settings.xml}">
@@ -255,6 +285,29 @@
</artifact:deploy>
</target>
+ <target name="deploy-snapshot" depends="build,pom" if="module.genpom" description="deploy a snapshot build to nexus">
+ <!-- In order to use this target you need to have predefined a username and password for the
+ server with id ${maven.snapshots.repo.id} in your m2 settings file, e.g ~/.m2/settings.xml -->
+ <artifact:pom id="module.pom" file="${build.scratch}/qpid-${module.name}.pom"/>
+
+ <fail message="The pom version must include -SNAPSHOT. Version found was: ${module.pom.version}">
+ <condition>
+ <not>
+ <contains substring="-SNAPSHOT" string="${module.pom.version}" />
+ </not>
+ </condition>
+ </fail>
+
+ <artifact:install file="${module.jar}" pomRefId="module.pom" settingsFile="${maven.settings.xml}">
+ <localRepository path="${maven.local.repo}"/>
+ </artifact:install>
+
+ <artifact:deploy file="${module.jar}" pomRefId="module.pom">
+ <localRepository path="${maven.local.repo}"/>
+ <remoteRepository id="${maven.snapshots.repo.id}" url="${maven.snapshots.repo.url}"/>
+ </artifact:deploy>
+ </target>
+
<target name="precompile"/>
<target name="compile" depends="prepare,precompile" description="compile sources">
@@ -280,6 +333,13 @@
<target name="precompile-tests" if="module.test.src.exists"/>
+ <target name="copy-test-resources" if="module.test.src.resources.exists">
+ <echo message="Copying test resources from ${module.test.resources} to ${module.test.classes}..."/>
+ <copy todir="${module.test.classes}" failonerror="true">
+ <fileset dir="${module.test.resources}"/>
+ </copy>
+ </target>
+
<target name="compile-tests" depends="compile,precompile-tests" if="module.test.src.exists"
description="compilte unit tests">
<javac target="${java.target}" source="${java.source}"
@@ -312,9 +372,8 @@
<map property="_profile_files" value="${profiles}" join=" ">
<globmapper from="*" to="*.testprofile"/>
</map>
-
- <delete file="${build.scratch}/test-${profile}.properties" quiet="true"/>
- <concat destfile="${build.scratch}/test-${profile}.properties" force="no" fixlastline="yes">
+
+ <concat destfile="${build.scratch}/test-${profile}.properties" force="yes" append="no" fixlastline="yes">
<filelist dir="${test.profiles}" files="testprofile.defaults"/>
<filelist dir="${test.profiles}" files="${_profile_files}"/>
</concat>
@@ -335,14 +394,13 @@
<property name="QPID_HOME" value="${qpid.home}"/>
<property name="QPID_WORK" value="${qpid.work}"/>
<property name="broker.existing.qpid.work" value=""/>
- <!-- Used by PluginTest -->
- <property name="example.plugin.target" value="${project.root}/build/lib/plugins"/>
<propertyset id="all.test.systemproperties">
<propertyref prefix="test"/>
<propertyref prefix="profile"/>
<propertyref prefix="javax.net.ssl"/>
<propertyref prefix="broker"/>
+ <propertyref prefix="qpid"/>
<propertyref name="amqj.logging.level"/>
<propertyref name="amqj.server.logging.level"/>
@@ -350,16 +408,14 @@
<propertyref name="log4j.debug"/>
<propertyref name="log4j.configuration"/>
+ <propertyref name="log4j.configuration.file"/>
<propertyref name="root.logging.level"/>
<propertyref name="java.naming.factory.initial"/>
<propertyref name="java.naming.provider.url"/>
<propertyref name="messagestore.class.name" />
- <propertyref name="qpid.amqp.version"/>
<propertyref name="max_prefetch"/>
- <propertyref name="qpid.dest_syntax"/>
- <propertyref name="test.output"/>
<propertyref name="QPID_HOME"/>
<propertyref name="QPID_WORK"/>
<propertyref name="example.plugin.target"/>
@@ -383,7 +439,7 @@
<formatter type="plain"/>
<formatter type="xml"/>
- <classpath refid="module.test.path"/>
+ <classpath refid="module.test.runtime.path"/>
<batchtest todir="${module.results}">
<fileset dir="${module.test.src}" excludes="${module.test.excludes}">
@@ -447,35 +503,54 @@
<target name="postbuild" description="run after a build"/>
- <target name="build" depends="jar,jar-tests,jar-sources,libs,copy-bin,copy-etc,postbuild" description="compile and copy resources into build tree"/>
+ <target name="build" depends="jar,jar-tests,jar-sources,libs,copy-bin,copy-etc,postbuild,copy-broker-plugin-jars" description="compile and copy resources into build tree"/>
- <target name="jar.manifest" depends="compile, copy-module-metainf" if="module.manifest">
+ <target name="jar.manifest" depends="compile,copy-resources,copy-files-to-module-metainf" if="module.manifest">
<jar destfile="${module.jar}" basedir="${module.classes}" manifest="${module.manifest}">
<metainf dir="${module.metainf}" />
</jar>
</target>
- <target name="jar.nomanifest" depends="compile, copy-module-metainf" unless="module.manifest">
+ <target name="jar.nomanifest" depends="compile,copy-resources,copy-files-to-module-metainf" unless="module.manifest">
<jar destfile="${module.jar}" basedir="${module.classes}">
<metainf dir="${module.metainf}" />
</jar>
</target>
- <target name="copy-module-metainf" depends="copy-metainf-resources" if="module.src.resources.metainf.exists">
+ <target name="copy-broker-plugin-jars" if="broker.plugin" description="copy broker plugins for use in release packaging">
+ <copy file="${module.jar}" todir="${build.scratch.broker.plugins.lib}" failonerror="true"/>
+ </target>
+
+ <target name="copy-files-to-module-metainf" depends="copy-project-resources-metainf, copy-module-resources-metainf, copy-module-src-resources-metainf"/>
+
+ <target name="copy-project-resources-metainf">
<copy todir="${module.metainf}" failonerror="true">
- <fileset dir="${module.src.resources.metainf}"/>
+ <fileset dir="${project.root}/resources/"/>
</copy>
</target>
- <target name="copy-metainf-resources">
+ <target name="copy-resources" if="module.src.resources.exists">
+ <echo message="Copying resources from ${module.src.resources} to ${module.classes}..."/>
+ <copy todir="${module.classes}" failonerror="true">
+ <fileset dir="${module.src.resources}" excludes="META-INF/**"/>
+ </copy>
+ </target>
+
+ <target name="copy-module-resources-metainf" if="module.resources.dir.exists">
+ <copy todir="${module.metainf}" failonerror="false" overwrite="true">
+ <fileset dir="${module.resources.dir}"/>
+ </copy>
+ </target>
+
+ <target name="copy-module-src-resources-metainf" if="module.src.resources.metainf.exists">
<copy todir="${module.metainf}" failonerror="true">
- <fileset dir="${project.root}/resources/"/>
+ <fileset dir="${module.src.resources.metainf}"/>
</copy>
</target>
<target name="jar" depends="jar.manifest,jar.nomanifest" description="create jar"/>
- <target name="jar-tests" depends="compile-tests" description="create unit test jar">
+ <target name="jar-tests" depends="compile-tests, copy-test-resources" description="create unit test jar">
<jar destfile="${module.test.jar}" basedir="${module.test.classes}"/>
</target>
@@ -494,14 +569,7 @@
<copylist todir="${build.lib}" dir="${project.root}" files="${module.libs}"/>
</target>
- <map property="module.depends.jars" value="${module.depends}" join=",">
- <globmapper from="*" to="${project.name}-*-${project.version}.jar"/>
- <filtermapper>
- <replacestring from="/" to="-"/>
- </filtermapper>
- </map>
-
<target name="libs-release" description="copy dependencies into module release">
<!-- Copy the module dependencies -->
<echo message="${module.libs}"/>
@@ -688,8 +756,7 @@
<syspropertyset refid="all.test.systemproperties"/>
- <sysproperty key="net.sourceforge.cobertura.datafile"
- file="${cobertura.datafile}" />
+ <sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.datafile}" />
<formatter type="plain"/>
<formatter type="xml"/>
@@ -697,10 +764,10 @@
<classpath path="${module.instrumented}"/>
<classpath>
<fileset dir="${build}">
- <include name="**/classes-instrumented/*.class"/>
- </fileset>
+ <include name="**/classes-instrumented/*.class"/>
+ </fileset>
</classpath>
- <classpath refid="module.test.path"/>
+ <classpath refid="module.test.runtime.path"/>
<classpath refid="cobertura.classpath"/>
<batchtest todir="${module.results}">
@@ -713,8 +780,8 @@
<target name="coverage-report" depends="cobertura-init">
<cobertura-report format="html"
- destdir="${module.coverage}"
- datafile="${cobertura.datafile}">
+ destdir="${module.coverage}"
+ datafile="${cobertura.datafile}">
<fileset dir="${module.src}" includes="**/*.java" />
</cobertura-report>
</target>
@@ -750,7 +817,8 @@ qpid.name=${project.name}
-->
- <property name="gentools.home" location="${project.root}/../gentools" />
+ <property name="gentools.home" location="${project.root}/common/gentools" />
+ <property name="gentools.build" location="${build.scratch}/common/gentools" />
<property name="generated.dir" location="${module.precompiled}" />
<property name="velocity.compile.dir" value="${build.scratch}/broker/velocity"/>
<property name="velocity.timestamp" location="${generated.dir}/velocity.timestamp" />
@@ -763,7 +831,7 @@ qpid.name=${project.name}
deprecation="${javac.deprecation}"
srcdir="${project.root}/broker/src/velocity/java" >
<classpath>
- <pathelement path="${gentools.home}/lib/velocity-1.4.jar" />
+ <pathelement path="${project.root}/${velocity.jar}" />
</classpath>
<compilerarg line="${javac.compiler.args}"/>
</javac>
@@ -793,7 +861,7 @@ qpid.name=${project.name}
<echo message="logmessages is ${logmessages}"/>
- <java classname="org.apache.qpid.server.logging.GenerateLogMessages" fork="true" dir="${gentools.home}/src" failonerror="true">
+ <java classname="org.apache.qpid.server.logging.GenerateLogMessages" fork="true" dir="${gentools.build}/classes" failonerror="true">
<arg line="'${logmessages}'"/>
<arg value="-j"/>
<arg value="-o"/>
@@ -810,7 +878,7 @@ qpid.name=${project.name}
<fileset dir="${project.root}/lib/required">
<include name="**/*.jar"/>
</fileset>
- <pathelement path="${gentools.home}/lib/velocity-1.4.jar" />
+ <pathelement path="${project.root}/${velocity.jar}" />
</classpath>
</java>
<touch file="${velocity.timestamp}" />
diff --git a/java/perftests/build.xml b/java/perftests/build.xml
index c59986c06d..d29649ad68 100644
--- a/java/perftests/build.xml
+++ b/java/perftests/build.xml
@@ -33,7 +33,7 @@
</condition>
<property name="module.depends" value="client common"/>
- <property name="module.test.depends" value="systests broker common/test management/common ${perftests.optional.test.depends}"/>
+ <property name="module.test.depends" value="systests broker common/tests management/common ${perftests.optional.test.depends}"/>
<import file="../module.xml"/>
diff --git a/java/perftests/etc/chartdefs/1001-MessageSize-Transient.chartdef b/java/perftests/etc/chartdefs/1001-MessageSize-Transient-ByteSec.chartdef
index 757a396dff..7559b5934e 100644
--- a/java/perftests/etc/chartdefs/1001-MessageSize-Transient.chartdef
+++ b/java/perftests/etc/chartdefs/1001-MessageSize-Transient-ByteSec.chartdef
@@ -18,15 +18,20 @@
#
chartType=XYLINE
-chartTitle=Impact of Message Size
+chartTitle=Impact of Message Size Bytes/S
chartSubtitle=Transient messages
+chartDescription=1P 1C, transient, auto-ack, with message payload between 256-262144 bytes.
+
xAxisTitle=Message Size (B)
yAxisTitle=Throughput (KB/s)
series.1.statement=SELECT payloadSizeB, throughputKbPerS FROM MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=red
series.2.statement=SELECT payloadSizeB, throughputKbPerS FROM MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1002-MessageSize-Persistent.chartdef b/java/perftests/etc/chartdefs/1002-MessageSize-Persistent-ByteSec.chartdef
index 58c280e227..db8a5f3896 100644
--- a/java/perftests/etc/chartdefs/1002-MessageSize-Persistent.chartdef
+++ b/java/perftests/etc/chartdefs/1002-MessageSize-Persistent-ByteSec.chartdef
@@ -18,15 +18,20 @@
#
chartType=XYLINE
-chartTitle=Impact of Message Size
+chartTitle=Impact of Message Size Bytes/S
chartSubtitle=Persistent messages
+chartDescription=1P 1C, persistent, auto-ack, with message payload between 256-262144 bytes.
+
xAxisTitle=Message Size (B)
yAxisTitle=Throughput (KB/s)
series.1.statement=SELECT payloadSizeB, throughputKbPerS FROM MessageSize WHERE testName like '% PERSISTENT' AND participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=red
series.2.statement=SELECT payloadSizeB, throughputKbPerS FROM MessageSize WHERE testName like '% PERSISTENT' AND participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1003-MessageSize-Transient-MsgSec.chartdef b/java/perftests/etc/chartdefs/1003-MessageSize-Transient-MsgSec.chartdef
new file mode 100644
index 0000000000..7f18fcc986
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1003-MessageSize-Transient-MsgSec.chartdef
@@ -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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of Message Size
+chartSubtitle=Transient messages
+chartDescription=1P 1C, transient, auto-ack, with message payload between 256-262144 bytes.
+
+xAxisTitle=Message Size (B)
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT payloadSizeB, throughputMessagesPerS FROM MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.1.colourName=red
+
+series.2.statement=SELECT payloadSizeB, throughputMessagesPerS FROM MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1004-MessageSize-Persistent-MsgSec.chartdef b/java/perftests/etc/chartdefs/1004-MessageSize-Persistent-MsgSec.chartdef
new file mode 100644
index 0000000000..667be044bc
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1004-MessageSize-Persistent-MsgSec.chartdef
@@ -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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of Message Size
+chartSubtitle=Persistent messages
+chartDescription=1P 1C, persistent, auto-ack, with message payload between 256-262144 bytes.
+
+xAxisTitle=Message Size (B)
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT payloadSizeB, throughputMessagesPerS FROM MessageSize WHERE testName like '% PERSISTENT' AND participantName = 'All'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.2.colourName=red
+
+series.2.statement=SELECT payloadSizeB, throughputMessagesPerS FROM MessageSize WHERE testName like '% PERSISTENT' AND participantName = 'All'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers.chartdef b/java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers-AutoAck.chartdef
index f39e7c3d0d..b3038c1671 100644
--- a/java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers.chartdef
+++ b/java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers-AutoAck.chartdef
@@ -18,23 +18,30 @@
#
chartType=XYLINE
-chartTitle=Varying number of producers
+chartTitle=Varying number of producers - auto ack
chartSubtitle=Persistent 1KB messages
+chartDescription=1,2,5,10 P/Cs, persistent, auto-ack, with message payload 1KB.
+
xAxisTitle=Producers
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT totalNumberOfProducers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1'
+series.1.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1' and acknowledgeMode = '1'
series.1.legend=1 Consumer
series.1.dir=${csvCurrentDir}
+series.1.colourName=red
-series.2.statement=SELECT totalNumberOfProducers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '5'
+series.2.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '5' and acknowledgeMode = '1'
series.2.legend=5 Consumer
series.2.dir=${csvCurrentDir}
+series.2.colourName=blue
-series.3.statement=SELECT totalNumberOfProducers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '10'
+series.3.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '10' and acknowledgeMode = '1'
series.3.legend=10 Consumer
series.3.dir=${csvCurrentDir}
+series.3.colourName=green
-series.4.statement=SELECT totalNumberOfProducers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1'
+series.4.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1' and acknowledgeMode = '1'
series.4.legend=1 Consumer (baseline)
series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_red
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers.chartdef b/java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers-AutoAck.chartdef
index 0f0b35a7c8..d1f3d6e9a4 100644
--- a/java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers.chartdef
+++ b/java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers-AutoAck.chartdef
@@ -18,23 +18,30 @@
#
chartType=XYLINE
-chartTitle=Varying number of consumers
+chartTitle=Varying number of consumers - auto ack
chartSubtitle=Persistent 1KB messages
+chartDescription=1,2,5,10 P/Cs, persistent, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT totalNumberOfConsumers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '1'
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '1' and acknowledgeMode = '1'
series.1.legend=1 Producer
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-series.2.statement=SELECT totalNumberOfConsumers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '5'
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '5' and acknowledgeMode = '1'
series.2.legend=5 Producers
series.2.dir=${csvCurrentDir}
+series.2.colourName=green
-series.3.statement=SELECT totalNumberOfConsumers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10'
+series.3.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10' and acknowledgeMode = '1'
series.3.legend=10 Producers
series.3.dir=${csvCurrentDir}
+series.3.colourName=red
-series.4.statement=SELECT totalNumberOfConsumers, throughputKbPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10'
+series.4.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10' and acknowledgeMode = '1'
series.4.legend=10 Producers (baseline)
series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_red
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1015-VaryingNumberOfProducers-SessionTrans.chartdef b/java/perftests/etc/chartdefs/1015-VaryingNumberOfProducers-SessionTrans.chartdef
new file mode 100644
index 0000000000..42ba6f8f20
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1015-VaryingNumberOfProducers-SessionTrans.chartdef
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Varying number of producers - transacted
+chartSubtitle=Persistent 1KB messages
+chartDescription=1,2,5,10 P/Cs, persistent, transacted, with message payload 1KB.
+
+xAxisTitle=Producers
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1' and acknowledgeMode = '0'
+series.1.legend=1 Consumer
+series.1.dir=${csvCurrentDir}
+series.1.colourName=red
+
+series.2.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '5' and acknowledgeMode = '0'
+series.2.legend=5 Consumer
+series.2.dir=${csvCurrentDir}
+series.2.colourName=blue
+
+series.3.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '10' and acknowledgeMode = '0'
+series.3.legend=10 Consumer
+series.3.dir=${csvCurrentDir}
+series.3.colourName=green
+
+series.4.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfConsumers = '1' and acknowledgeMode = '0'
+series.4.legend=1 Consumer (baseline)
+series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_red
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1016-VaryingNumberOfConsumers-SessionTrans.chartdef b/java/perftests/etc/chartdefs/1016-VaryingNumberOfConsumers-SessionTrans.chartdef
new file mode 100644
index 0000000000..0afd162ad0
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1016-VaryingNumberOfConsumers-SessionTrans.chartdef
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Varying number of consumers - transacted
+chartSubtitle=Persistent 1KB messages
+chartDescription=1,2,5,10 P/Cs, persistent, transacted, with message payload 1KB.
+
+xAxisTitle=Consumers
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '1' and acknowledgeMode = '0'
+series.1.legend=1 Producer
+series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
+
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '5' and acknowledgeMode = '0'
+series.2.legend=5 Producers
+series.2.dir=${csvCurrentDir}
+series.2.colourName=green
+
+series.3.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10' and acknowledgeMode = '0'
+series.3.legend=10 Producers
+series.3.dir=${csvCurrentDir}
+series.3.colourName=red
+
+series.4.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '10' and acknowledgeMode = '0'
+series.4.legend=10 Producers (baseline)
+series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_red
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef b/java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef
index 30aee40c27..827f8b5567 100644
--- a/java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef
+++ b/java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef
@@ -19,17 +19,20 @@
chartType=BAR
chartTitle=Performance of acknowledgement modes
-chartSubtitle=Persistent messages (1024b)
+chartSubtitle=Persistent messages (1KB)
+chartDescription=1P 1C, persistent, with message payload 1KB.
+
xAxisTitle=Acknowledge mode (0=session transacted; 1=auto-acknowledge)
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT acknowledgeMode, throughputKbPerS FROM AcknowledgementModes WHERE testName like 'Persistent%' AND participantName = 'All' ORDER BY acknowledgeMode
+series.1.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM AcknowledgementModes WHERE testName like 'Persistent%' AND participantName = 'All' ORDER BY acknowledgeMode
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-
-series.2.statement=SELECT acknowledgeMode, throughputKbPerS FROM AcknowledgementModes WHERE testName like 'Persistent%' AND participantName = 'All' ORDER BY acknowledgeMode
+series.2.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM AcknowledgementModes WHERE testName like 'Persistent%' AND participantName = 'All' ORDER BY acknowledgeMode
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
diff --git a/java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef b/java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef
index 7a26391deb..8ca5d838e2 100644
--- a/java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef
+++ b/java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef
@@ -20,13 +20,17 @@
chartType=BAR
chartTitle=Performance of acknowledgement modes
chartSubtitle=Transient messages (1024b)
+chartDescription=1P 1C, transient, with message payload 1KB.
+
xAxisTitle=Acknowledge mode (0=session transacted; 1=auto-acknowledge)
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT acknowledgeMode, throughputKbPerS FROM AcknowledgementModes WHERE testName like 'Transient%' AND participantName = 'All' ORDER BY acknowledgeMode
+series.1.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM AcknowledgementModes WHERE testName like 'Transient%' AND participantName = 'All' ORDER BY acknowledgeMode
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-series.2.statement=SELECT acknowledgeMode, throughputKbPerS FROM AcknowledgementModes WHERE testName like 'Transient%' AND participantName = 'All' ORDER BY acknowledgeMode
+series.2.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM AcknowledgementModes WHERE testName like 'Transient%' AND participantName = 'All' ORDER BY acknowledgeMode
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
diff --git a/java/perftests/etc/chartdefs/1030-BatchSize-Equal.chartdef b/java/perftests/etc/chartdefs/1030-BatchSize-Equal.chartdef
new file mode 100644
index 0000000000..97b712e027
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1030-BatchSize-Equal.chartdef
@@ -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.
+#
+
+chartType=XYLINE
+chartTitle=Transaction Batch Sizes Equal
+chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, transacted with message payload 1KB with producer/consumer batch size varying between 1-400 messages for both P and C
+
+xAxisTitle=Batch Size
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT batchSize, throughputMessagesPerS FROM BatchSize WHERE participantName = 'All'
+series.1.legend=Equal Producer/Consumer
+series.1.dir=${csvCurrentDir}
+series.1.colourName=red
+
+series.2.statement=SELECT batchSize, throughputMessagesPerS FROM BatchSize WHERE participantName = 'All'
+series.2.legend=Equal Producer/Consumer (Baseline)
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1031-BatchSize-Unequal.chartdef b/java/perftests/etc/chartdefs/1031-BatchSize-Unequal.chartdef
new file mode 100644
index 0000000000..51b3bb2144
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1031-BatchSize-Unequal.chartdef
@@ -0,0 +1,53 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Transaction Batch Size Unequal
+chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, transacted with message payload 1KB with fixed batch size 1 for one party whilst other varies between 1-400 messages
+
+xAxisTitle=Batch Size
+yAxisTitle=Throughput (messages/s)
+
+#
+# If csvjdbc could do sub-selects (allowing us to extract the consumer/producer batch size from the All Consumers/All Producers rows),
+# we would not need the workaround where we have testdef place the consumer/producer batch size into testName field
+#
+
+series.1.statement=SELECT testName, throughputMessagesPerS FROM BatchSizeProducerVaries WHERE participantName = 'All'
+series.1.legend=Variable Producer, Fixed Consumer
+series.1.dir=${csvCurrentDir}
+series.1.colourName=red
+
+series.2.statement=SELECT testName, throughputMessagesPerS FROM BatchSizeProducerVaries WHERE participantName = 'All'
+series.2.legend=Variable Producer, Fixed Consumer (Baseline)
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
+
+series.3.statement=SELECT testName, throughputMessagesPerS FROM BatchSizeConsumerVaries WHERE participantName = 'All'
+series.3.legend=Fixed Producer, Variable Consumer
+series.3.dir=${csvCurrentDir}
+series.3.colourName=blue
+
+series.4.statement=SELECT testName, throughputMessagesPerS FROM BatchSizeConsumerVaries WHERE participantName = 'All'
+series.4.legend=Fixed Producer, Variable Consumer (Baseline)
+series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_blue
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1040-QueueTypes.chartdef b/java/perftests/etc/chartdefs/1040-QueueTypes.chartdef
index 42ed69c19d..aacedab421 100644
--- a/java/perftests/etc/chartdefs/1040-QueueTypes.chartdef
+++ b/java/perftests/etc/chartdefs/1040-QueueTypes.chartdef
@@ -20,13 +20,17 @@
chartType=BAR
chartTitle=Queue Types
chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, auto-ack with message payload 1KB. Sorted queue - 160,000 random keys, Priority - iteriates priority 0..9.
+
xAxisTitle=Queue Types
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT testName, throughputKbPerS FROM QueueTypes WHERE participantName = 'All'
+series.1.statement=SELECT testName, throughputMessagesPerS FROM QueueTypes WHERE participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-series.2.statement=SELECT testName, throughputKbPerS FROM QueueTypes WHERE participantName = 'All'
+series.2.statement=SELECT testName, throughputMessagesPerS FROM QueueTypes WHERE participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
diff --git a/java/perftests/etc/chartdefs/1050-VaryingNumberOfProducerSessionsSingleConnection.chartdef b/java/perftests/etc/chartdefs/1050-VaryingNumberOfProducerSessionsSingleConnection.chartdef
new file mode 100644
index 0000000000..46696bf942
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1050-VaryingNumberOfProducerSessionsSingleConnection.chartdef
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Varying number of producer sessions on single connection
+chartSubtitle=Persistent messages (1024b)
+chartDescription=1-80P transacted on single connection, 20C transacted on separate connections, persistent, message payload 1KB.
+
+xAxisTitle=Number of producer sessions
+yAxisTitle=Throughput (KB/s)
+
+# testName contains the number of sessions
+series.1.statement=SELECT testName, throughputKbPerS FROM VaryingNumberOfProducerSessionsSingleConnection WHERE participantName = 'All'
+series.1.legend=Current - End-to-end throughput
+series.1.dir=${csvCurrentDir}
+series.1.colourName=red
+
+series.2.statement=SELECT testName, throughputKbPerS FROM VaryingNumberOfProducerSessionsSingleConnection WHERE participantName = 'All Producers'
+series.2.legend=Current - Producer only throughput
+series.2.dir=${csvCurrentDir}
+series.2.colourName=blue
+
+series.3.statement=SELECT testName, throughputKbPerS FROM VaryingNumberOfProducerSessionsSingleConnection WHERE participantName = 'All'
+series.3.legend=Baseline - End-to-end throughput
+series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
+series.3.strokeWidth=-1
+
+series.4.statement=SELECT testName, throughputKbPerS FROM VaryingNumberOfProducerSessionsSingleConnection WHERE participantName = 'All Producers'
+series.4.legend=Baseline - Producer only throughput
+series.4.dir=${csvBaselineDir}
+series.4.colourName=dark_blue
+series.4.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1300-QueueConsumersWithNonOverlappingSelectors-Transient.chartdef b/java/perftests/etc/chartdefs/1300-QueueConsumersWithNonOverlappingSelectors-Transient.chartdef
new file mode 100644
index 0000000000..5081b379e7
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1300-QueueConsumersWithNonOverlappingSelectors-Transient.chartdef
@@ -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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of non-overlapping selectors on queue consumers with transient messages
+chartSubtitle=Transient 1KB messages
+xAxisTitle=Consumers
+yAxisTitle=Throughput (messages/s)
+chartDescription=Impact of non-overlapping selectors on queue consumers with transient messages, auto-ack, message payload of 1024 bytes, 1 producer, varying number of consumers from 1 to 32.
+
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithNonOverlappingSelectors WHERE participantName = 'All' and testName like '%non overlapping - NON_PERSISTENT%'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
+
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithNonOverlappingSelectors WHERE participantName = 'All' and testName like '%non overlapping - NON_PERSISTENT%'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=-1
+
diff --git a/java/perftests/etc/chartdefs/1301-QueueConsumersWithNonOverlappingSelectors-Persistent.chartdef b/java/perftests/etc/chartdefs/1301-QueueConsumersWithNonOverlappingSelectors-Persistent.chartdef
new file mode 100644
index 0000000000..137f7bde36
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1301-QueueConsumersWithNonOverlappingSelectors-Persistent.chartdef
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of non-overlapping selectors on queue consumers with persistent messages
+chartSubtitle=Persistent 1KB messages
+xAxisTitle=Consumers
+yAxisTitle=Throughput (messages/s)
+chartDescription=Impact of non-overlapping selectors on queue consumers with persistent messages, auto-ack, message payload of 1024 bytes, 1 producer, varying number of consumers from 1 to 32..
+
+
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithNonOverlappingSelectors WHERE participantName = 'All' and testName like '%non overlapping - PERSISTENT'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
+
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithNonOverlappingSelectors WHERE participantName = 'All' and testName like '%non overlapping - PERSISTENT'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=-1
+
+series.3.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '1' and acknowledgeMode = '1'
+series.3.legend=Current: no selectors
+series.3.dir=${csvCurrentDir}
+series.3.colourName=green
+
diff --git a/java/perftests/etc/chartdefs/1302-QueueConsumersWithOverlappingSelectors-Transient.chartdef b/java/perftests/etc/chartdefs/1302-QueueConsumersWithOverlappingSelectors-Transient.chartdef
new file mode 100644
index 0000000000..74f370317b
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1302-QueueConsumersWithOverlappingSelectors-Transient.chartdef
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of 50%-overlapping selectors in queue consumers with transient messages
+chartSubtitle=Transient 1KB messages
+xAxisTitle=Consumers
+yAxisTitle=Throughput (messages/s)
+chartDescription=Impact of 50%-overlapping selectors in queue consumers with transient messages, auto-ack, message payload 1KB, 1 producer, varying number of consumers from 2 to 32.
+
+series.1.statement=SELECT totalNumberOfConsumers,throughputMessagesPerS FROM QueueConsumersWithOverlappingSelectors WHERE participantName = 'All' and testName like '%50_ overlapping - NON_PERSISTENT%'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
+
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithOverlappingSelectors WHERE participantName = 'All' and testName like '%50_ overlapping - NON_PERSISTENT%'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1303-QueueConsumersWithOverlappingSelectors-Persistent.chartdef b/java/perftests/etc/chartdefs/1303-QueueConsumersWithOverlappingSelectors-Persistent.chartdef
new file mode 100644
index 0000000000..0dd78e02ef
--- /dev/null
+++ b/java/perftests/etc/chartdefs/1303-QueueConsumersWithOverlappingSelectors-Persistent.chartdef
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+chartType=XYLINE
+chartTitle=Impact of 50%-overlapping selectors in queue consumers with persistent messages
+chartDescription=Impact of 50%-overlapping selectors in queue consumers with persistent messages, auto-ack, message payload of 1KB, 1 producer, varying number of consumers from 2 to 32.
+chartSubtitle=Persistent 1KB messages
+xAxisTitle=Consumers
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithOverlappingSelectors WHERE participantName = 'All' and testName like '%50_ overlapping - PERSISTENT%'
+series.1.legend=Current
+series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
+
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM QueueConsumersWithOverlappingSelectors WHERE participantName = 'All' and testName like '%50_ overlapping - PERSISTENT%'
+series.2.legend=Baseline
+series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=-1
+
+series.3.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM VaryingNumberOfParticipants WHERE participantName = 'All' and totalNumberOfProducers = '1' and acknowledgeMode = '1'
+series.3.legend=Current: no selectors
+series.3.dir=${csvCurrentDir}
+series.3.colourName=green
+
diff --git a/java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef b/java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef
index 305c5009e2..073cee810d 100644
--- a/java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef
+++ b/java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef
@@ -20,13 +20,18 @@
chartType=XYLINE
chartTitle=Number of topic consumers
chartSubtitle=Transient 1KB messages
+chartDescription=1P 1-100C transient, transacted, with message payload 1KB.
+
xAxisTitle=Numer of consumers
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT testName, throughputKbPerS FROM Topic-NumberOfConsumers WHERE participantName = 'All'
+series.1.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM Topic-NumberOfConsumers WHERE participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=red
-series.2.statement=SELECT testName, throughputKbPerS FROM Topic-NumberOfConsumers WHERE participantName = 'All'
+series.2.statement=SELECT totalNumberOfConsumers, throughputMessagesPerS FROM Topic-NumberOfConsumers WHERE participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef b/java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef
index 9bc53e5a9e..b32f43d0c2 100644
--- a/java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef
+++ b/java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef
@@ -20,13 +20,18 @@
chartType=XYLINE
chartTitle=Number of topics
chartSubtitle=Transient 1KB messages
+chartDescription=1,10,50,100 PC, transient, transacted, with each PC pair having own topic, message payload 1KB.
+
xAxisTitle=Numer of topics
-yAxisTitle=Throughput (KB/s)
+yAxisTitle=Throughput (messages/s)
-series.1.statement=SELECT testName, throughputKbPerS FROM Topic-NumberOfTopics WHERE participantName = 'All'
+series.1.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM Topic-NumberOfTopics WHERE participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=red
-series.2.statement=SELECT testName, throughputKbPerS FROM Topic-NumberOfTopics WHERE participantName = 'All'
+series.2.statement=SELECT totalNumberOfProducers, throughputMessagesPerS FROM Topic-NumberOfTopics WHERE participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.strokeWidth=-1
diff --git a/java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef b/java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef
index ce64d14ac4..5fd905ab4f 100644
--- a/java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef
+++ b/java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef
@@ -20,13 +20,18 @@
chartType=BAR
chartTitle=Topic transient/durable subscriptions
chartSubtitle=1KB messages
-xAxisTitle=Durable subscription
-yAxisTitle=Throughput (KB/s)
+chartDescription=1P 10C, transacted, message payload 1KB, transient messages on non-durable sub, persistent messages on durable sub
-series.1.statement=SELECT isDurableSubscription, throughputKbPerS FROM Topic-Persistence WHERE participantName = 'All Consumers'
+xAxisTitle=Subscription type (true durable, false non durable)
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT isDurableSubscription, throughputMessagesPerS FROM Topic-Persistence WHERE participantName = 'All Consumers'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-series.2.statement=SELECT isDurableSubscription, throughputKbPerS FROM Topic-Persistence WHERE participantName = 'All Consumers'
+series.2.statement=SELECT isDurableSubscription, throughputMessagesPerS FROM Topic-Persistence WHERE participantName = 'All Consumers'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=2
diff --git a/java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef b/java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef
index 5ccc166fc8..9edb1950a4 100644
--- a/java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef
+++ b/java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef
@@ -20,13 +20,18 @@
chartType=BAR
chartTitle=Topic acknowledge modes
chartSubtitle=Transient 1KB messages
-xAxisTitle=Ack Mode
-yAxisTitle=Throughput (KB/s)
+chartDescription=1P 10C, transient, non-durable subscription, message payload 1KB
-series.1.statement=SELECT acknowledgeMode, throughputKbPerS FROM Topic-AckModes WHERE participantName = 'All'
+xAxisTitle=Ack Mode (0=transaction 1=auto-ack)
+yAxisTitle=Throughput (messages/s)
+
+series.1.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM Topic-AckModes WHERE participantName = 'All'
series.1.legend=Current
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
-series.2.statement=SELECT acknowledgeMode, throughputKbPerS FROM Topic-AckModes WHERE participantName = 'All'
+series.2.statement=SELECT acknowledgeMode, throughputMessagesPerS FROM Topic-AckModes WHERE participantName = 'All'
series.2.legend=Baseline
series.2.dir=${csvBaselineDir}
+series.2.colourName=dark_red
+series.2.stokeWidth=2
diff --git a/java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef b/java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef
index c892ea16cf..67a0278bff 100644
--- a/java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef
+++ b/java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Impact of message size on latency
chartSubtitle=Transient messages
+chartDescription=1P 1C, transient, auto-ack, with message payload between 256-262144 bytes.
+
xAxisTitle=Message Size (B)
yAxisTitle=Latency (millis)
series.1.statement=SELECT payloadSizeB, maxLatency, 0 FROM Latency-MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All Consumers'
series.1.legend=Maximum latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT payloadSizeB, averageLatency,latencyStandardDeviation FROM Latency-MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All Consumers'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT payloadSizeB, averageLatency,latencyStandardDeviation FROM Latency-MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All Consumers'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT payloadSizeB, minLatency,0 FROM Latency-MessageSize WHERE testName like '%TRANSIENT' AND participantName = 'All Consumers'
series.4.legend=Minimum latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef b/java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef
index 167e62603a..e9761f07d8 100644
--- a/java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef
+++ b/java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Impact of message size on latency
chartSubtitle=Persistent messages
+chartDescription=1P 1C, persistent, auto-ack, with message payload between 256-262144 bytes.
+
xAxisTitle=Message Size (B)
yAxisTitle=Latency (millis)
series.1.statement=SELECT payloadSizeB, maxLatency, 0 FROM Latency-MessageSize WHERE testName like '%PERSISTENT' AND participantName = 'All Consumers'
series.1.legend=Maximum latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT payloadSizeB, averageLatency, latencyStandardDeviation FROM Latency-MessageSize WHERE testName like '%PERSISTENT' AND participantName = 'All Consumers'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT payloadSizeB, averageLatency, latencyStandardDeviation FROM Latency-MessageSize WHERE testName like '%PERSISTENT' AND participantName = 'All Consumers'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT payloadSizeB, minLatency, 0 FROM Latency-MessageSize WHERE testName like '%PERSISTENT' AND participantName = 'All Consumers'
series.4.legend=Minimum latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2011-Latency-QueuesWithNonOverlappingSelectors-Transient.chartdef b/java/perftests/etc/chartdefs/2011-Latency-QueuesWithNonOverlappingSelectors-Transient.chartdef
index 45c6031b1e..663912b622 100644
--- a/java/perftests/etc/chartdefs/2011-Latency-QueuesWithNonOverlappingSelectors-Transient.chartdef
+++ b/java/perftests/etc/chartdefs/2011-Latency-QueuesWithNonOverlappingSelectors-Transient.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Latency with consumers having non-overlapping selectors
chartSubtitle=Transient 1KB messages
+chartDescription=1P 1-10C, transient, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
yAxisTitle=Latency (millis)
series.1.statement=SELECT totalNumberOfConsumers, maxLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - NON_PERSISTENT%'
series.1.legend=Max latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - NON_PERSISTENT%'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - NON_PERSISTENT%'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT totalNumberOfConsumers, minLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - NON_PERSISTENT%'
series.4.legend=Min latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2012-Latency-QueuesWithOverlappingSelectors-Transient.chartdef b/java/perftests/etc/chartdefs/2012-Latency-QueuesWithOverlappingSelectors-Transient.chartdef
index 351a4639b1..3b9e207e10 100644
--- a/java/perftests/etc/chartdefs/2012-Latency-QueuesWithOverlappingSelectors-Transient.chartdef
+++ b/java/perftests/etc/chartdefs/2012-Latency-QueuesWithOverlappingSelectors-Transient.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Latency with consumers having 50%-overlapping selectors
chartSubtitle=Transient 1KB messages
+chartDescription=1P 1-10C, transient, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
yAxisTitle=Latency (millis)
series.1.statement=SELECT totalNumberOfConsumers, maxLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - NON_PERSISTENT%'
series.1.legend=Max latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - NON_PERSISTENT%'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - NON_PERSISTENT%'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT totalNumberOfConsumers, minLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - NON_PERSISTENT%'
series.4.legend=Min latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2021-Latency-QueuesWithNonOverlappingSelectors-Persistent.chartdef b/java/perftests/etc/chartdefs/2021-Latency-QueuesWithNonOverlappingSelectors-Persistent.chartdef
index 9d95075b3d..296d115d3f 100644
--- a/java/perftests/etc/chartdefs/2021-Latency-QueuesWithNonOverlappingSelectors-Persistent.chartdef
+++ b/java/perftests/etc/chartdefs/2021-Latency-QueuesWithNonOverlappingSelectors-Persistent.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Latency with consumers having non-overlapping selectors
chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1-10C, persistent, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
yAxisTitle=Latency (millis)
series.1.statement=SELECT totalNumberOfConsumers, maxLatency,0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - PERSISTENT'
series.1.legend=Max latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT totalNumberOfConsumers, averageLatency, latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - PERSISTENT'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT totalNumberOfConsumers, averageLatency, latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - PERSISTENT'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT totalNumberOfConsumers, minLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%non overlapping - PERSISTENT'
series.4.legend=Min latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2022-Latency-QueuesWithOverlappingSelectors-Persistent.chartdef b/java/perftests/etc/chartdefs/2022-Latency-QueuesWithOverlappingSelectors-Persistent.chartdef
index 9a323d4044..65be60b5e5 100644
--- a/java/perftests/etc/chartdefs/2022-Latency-QueuesWithOverlappingSelectors-Persistent.chartdef
+++ b/java/perftests/etc/chartdefs/2022-Latency-QueuesWithOverlappingSelectors-Persistent.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Latency with consumers having 50%-overlapping selectors
chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1-10C, persistent, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
yAxisTitle=Latency (millis)
series.1.statement=SELECT totalNumberOfConsumers, maxLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - PERSISTENT%'
series.1.legend=Max latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - PERSISTENT%'
series.2.legend=Average latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - PERSISTENT%'
series.3.legend=Average latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT totalNumberOfConsumers, minLatency, 0 FROM Latency-QueuesWithSelectors WHERE participantName = 'All Consumers' and testName like '%overlapping 50% - PERSISTENT%'
series.4.legend=Min latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef b/java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef
index 82cf1168ef..d52b05d870 100644
--- a/java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef
+++ b/java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef
@@ -20,25 +20,32 @@
chartType=STATISTICAL_BAR
chartTitle=Latency, varying number of participants
chartSubtitle=Persistent 1KB messages
+chartDescription=1,2,5,10 P/Cs, persistent, auto-ack, with message payload 1KB.
+
xAxisTitle=Consumers
yAxisTitle=Latency (millis)
series.1.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-VaryingNumberOfParticipants WHERE participantName = 'All Consumers' and testName like '% - 1 producer - PERSISTENT'
series.1.legend=1 producer
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-VaryingNumberOfParticipants WHERE participantName = 'All Consumers' and testName like '% - 2 producers - PERSISTENT'
series.2.legend=2 producers
series.2.dir=${csvCurrentDir}
+series.2.colourName=green
series.3.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-VaryingNumberOfParticipants WHERE participantName = 'All Consumers' and testName like '% - 5 producers - PERSISTENT'
series.3.legend=5 producers
series.3.dir=${csvCurrentDir}
+series.3.colourName=magenta
series.4.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-VaryingNumberOfParticipants WHERE participantName = 'All Consumers' and testName like '% - 10 producers - PERSISTENT'
series.4.legend=10 producers
series.4.dir=${csvCurrentDir}
+series.4.colourName=red
series.5.statement=SELECT totalNumberOfConsumers, averageLatency,latencyStandardDeviation FROM Latency-VaryingNumberOfParticipants WHERE participantName = 'All Consumers' and testName like '% - 10 producers - PERSISTENT'
series.5.legend=10 producers (baseline)
series.5.dir=${csvBaselineDir}
+series.5.colourName=dark_red
diff --git a/java/perftests/etc/chartdefs/2041-Latency-QueueTypes.chartdef b/java/perftests/etc/chartdefs/2041-Latency-QueueTypes.chartdef
index c1aae19376..dac8a52f89 100644
--- a/java/perftests/etc/chartdefs/2041-Latency-QueueTypes.chartdef
+++ b/java/perftests/etc/chartdefs/2041-Latency-QueueTypes.chartdef
@@ -20,21 +20,27 @@
chartType=STATISTICAL_BAR
chartTitle=Latency on different queues
chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, auto-ack with message payload 1KB. Sorted queue - 400 varied keys, Priority - 200 varied priorities.
+
xAxisTitle=Queue type
yAxisTitle=Latency (millis)
series.1.statement=SELECT testName, maxLatency,0 FROM Latency-QueueTypes WHERE participantName = 'All Consumers'
series.1.legend=Maximum latency
series.1.dir=${csvCurrentDir}
+series.1.colourName=blue
series.2.statement=SELECT testName, averageLatency,latencyStandardDeviation FROM Latency-QueueTypes WHERE participantName = 'All Consumers'
series.2.legend=Average Latency
series.2.dir=${csvCurrentDir}
+series.2.colourName=red
series.3.statement=SELECT testName, averageLatency,latencyStandardDeviation FROM Latency-QueueTypes WHERE participantName = 'All Consumers'
series.3.legend=Average Latency (baseline)
series.3.dir=${csvBaselineDir}
+series.3.colourName=dark_red
series.4.statement=SELECT testName, minLatency,0 FROM Latency-QueueTypes WHERE participantName = 'All Consumers'
series.4.legend=Minimum latency
series.4.dir=${csvCurrentDir}
+series.4.colourName=green
diff --git a/java/perftests/etc/chartdefs/timeseries/1001-Large-Messages-Transient.chartdef b/java/perftests/etc/chartdefs/timeseries/1001-Large-Messages-Transient.chartdef
new file mode 100644
index 0000000000..e77f7b4eff
--- /dev/null
+++ b/java/perftests/etc/chartdefs/timeseries/1001-Large-Messages-Transient.chartdef
@@ -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.
+#
+
+chartType=TIMELINE
+chartTitle=Large transient messages
+chartDescription=1P 1C, transient, auto-ack, with message payload 65536 bytes.
+
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'Message Size - 1P-1C - TRANSIENT' and payloadSizeB = 65536
+series.1.colourName=red
+series.1.legend=Throughput
diff --git a/java/perftests/etc/chartdefs/timeseries/1002-Large-Messages-Persistent.chartdef b/java/perftests/etc/chartdefs/timeseries/1002-Large-Messages-Persistent.chartdef
new file mode 100644
index 0000000000..ffcf8c26b8
--- /dev/null
+++ b/java/perftests/etc/chartdefs/timeseries/1002-Large-Messages-Persistent.chartdef
@@ -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.
+#
+
+chartType=TIMELINE
+chartTitle=Large persistent messages
+chartDescription=1P 1C, persistent, auto-ack, with message payload 65536 bytes.
+
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'Message Size - 1P-1C - PERSISTENT' and payloadSizeB = 65536
+series.1.colourName=red
+series.1.legend=Throughput
diff --git a/java/perftests/etc/chartdefs/timeseries/1011-MultipleProducersAndConsumers-Persistent.chartdef b/java/perftests/etc/chartdefs/timeseries/1011-MultipleProducersAndConsumers-Persistent.chartdef
new file mode 100644
index 0000000000..ba01d4b7ad
--- /dev/null
+++ b/java/perftests/etc/chartdefs/timeseries/1011-MultipleProducersAndConsumers-Persistent.chartdef
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+chartType=TIMELINE
+chartTitle=Multiple producers and consumers - auto ack
+chartSubtitle=Persistent 1KB messages
+chartDescription=10 P/Cs, persistent, auto-ack, with message payload 1KB.
+
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'Varying number of participants: 10 consumers - 10 producers - PERSISTENT'
+series.1.colourName=red
+series.1.legend=Throughput \ No newline at end of file
diff --git a/java/perftests/etc/chartdefs/1030-BatchSize.chartdef b/java/perftests/etc/chartdefs/timeseries/1030-Batch-Size-Small.chartdef
index 1f01aa85aa..f755bf4a5b 100644
--- a/java/perftests/etc/chartdefs/1030-BatchSize.chartdef
+++ b/java/perftests/etc/chartdefs/timeseries/1030-Batch-Size-Small.chartdef
@@ -17,17 +17,14 @@
# under the License.
#
-chartType=XYLINE
-chartTitle=Transaction Batch Size
+chartType=TIMELINE
+chartTitle=Transactions
chartSubtitle=Persistent 1KB messages
-xAxisTitle=Batch Size
-yAxisTitle=Throughput (KB/s)
-
-series.1.statement=SELECT batchSize, throughputKbPerS FROM BatchSize WHERE participantName = 'All'
-series.1.legend=Current
-series.1.dir=${csvCurrentDir}
+chartDescription=1P 1C, persistent, transacted with message payload 1KB with batch size 1 for both P and C
-series.2.statement=SELECT batchSize, throughputKbPerS FROM BatchSize WHERE participantName = 'All'
-series.2.legend=Baseline
-series.2.dir=${csvBaselineDir}
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'Batch Size 1-1 - PERSISTENT'
+series.1.colourName=red
+series.1.legend=Throughput \ No newline at end of file
diff --git a/java/perftests/etc/chartdefs/timeseries/1031-Batch-Size-Large.chartdef b/java/perftests/etc/chartdefs/timeseries/1031-Batch-Size-Large.chartdef
new file mode 100644
index 0000000000..ca390f8226
--- /dev/null
+++ b/java/perftests/etc/chartdefs/timeseries/1031-Batch-Size-Large.chartdef
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+chartType=TIMELINE
+chartTitle=Transactions with large batches
+chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, transacted with message payload 1KB with batch size 100 for both P and C
+
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'Batch Size 100-100 - PERSISTENT'
+series.1.colourName=red
+series.1.legend=Throughput
diff --git a/java/perftests/etc/chartdefs/timeseries/1040-SortedQueue.chartdef b/java/perftests/etc/chartdefs/timeseries/1040-SortedQueue.chartdef
new file mode 100644
index 0000000000..6dce3a1a77
--- /dev/null
+++ b/java/perftests/etc/chartdefs/timeseries/1040-SortedQueue.chartdef
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+chartType=TIMELINE
+chartTitle=Sorted queue
+chartSubtitle=Persistent 1KB messages
+chartDescription=1P 1C, persistent, auto-ack with message payload 1KB. Sorted queue with 160,000 random keys
+
+xAxisTitle=Date
+yAxisTitle=Throughput (KB/s)
+
+series.1.statement=SELECT insertedTimestamp, throughputKbPerS FROM RESULTS WHERE participantName = 'All' AND testName = 'queue-type:sorted-queue'
+series.1.colourName=red
+series.1.legend=Throughput \ No newline at end of file
diff --git a/java/perftests/etc/perftests-jndi.properties b/java/perftests/etc/perftests-jndi.properties
index f33af6fdd5..ce6493b49a 100644
--- a/java/perftests/etc/perftests-jndi.properties
+++ b/java/perftests/etc/perftests-jndi.properties
@@ -20,3 +20,7 @@ java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextF
connectionfactory.connectionfactory = amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'
destination.controllerqueue = direct://amq.direct//controllerqueue?autodelete='true'
+
+jdbcDriverClass=org.apache.derby.jdbc.EmbeddedDriver
+# writes to a results database in ./perftestResultsDb by default.
+jdbcUrl=jdbc:derby:perftestResultsDb;create=true
diff --git a/java/perftests/etc/run-perftests.sh b/java/perftests/etc/run-perftests.sh
new file mode 100755
index 0000000000..f963879e7e
--- /dev/null
+++ b/java/perftests/etc/run-perftests.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# 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.
+#
+
+# Runs the perftests using a typical configuration.
+
+BASE_DIR=`dirname $0`
+DURATION=${1:-5000}
+AMQP_VERSION=${2:-0-91}
+
+echo Will run perftests using a maximum duration of ${DURATION}ms and AMQP protocol version ${AMQP_VERSION}.
+echo
+
+java -cp "${BASE_DIR}:${BASE_DIR}/../../build/lib/*" \
+ -Dqpid.amqp.version=${AMQP_VERSION} -Dqpid.dest_syntax=BURL \
+ -Dqpid.disttest.duration=$DURATION \
+ org.apache.qpid.disttest.ControllerRunner \
+ jndi-config=${BASE_DIR}/perftests-jndi.properties \
+ test-config=${BASE_DIR}/testdefs \
+ distributed=false \
+ writeToDb=true
diff --git a/java/perftests/etc/testdefs/BatchSize.js b/java/perftests/etc/testdefs/BatchSize.js
new file mode 100644
index 0000000000..f17751b7b5
--- /dev/null
+++ b/java/perftests/etc/testdefs/BatchSize.js
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+var jsonObject = {
+ _tests:[]
+};
+
+var duration = 30000;
+
+var txBatchSizes = [[1,1], [2,2], [5,5], [10,10], [20,20], [50,50], [100,100], [200,200], [400,400]];
+
+var acknowledgeMode = 0;
+var deliveryMode = 2;
+var messageSize = 1024;
+
+for(i=0; i < txBatchSizes.length ; i++)
+{
+ var producerBatchSize = txBatchSizes[i][0];
+ var consumerBatchSize = txBatchSizes[i][1];
+ var queueName = "txBatchSize" + producerBatchSize + "_" + consumerBatchSize;
+ var destination = "direct://amq.direct//" + queueName + "?durable='true'";
+
+ var test = {
+ "_name": "Batch Size " + producerBatchSize + "-" + consumerBatchSize + " - PERSISTENT",
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": true
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_producers": [
+ {
+ "_name": "Producer1",
+ "_destinationName": destination,
+ "_messageSize": messageSize,
+ "_deliveryMode": deliveryMode,
+ "_batchSize": producerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_name": "consumingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_consumers": [
+ {
+ "_name": "Consumer1",
+ "_destinationName": destination,
+ "_batchSize": consumerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+
+ jsonObject._tests= jsonObject._tests.concat(test);
+}
diff --git a/java/perftests/etc/testdefs/BatchSize.json b/java/perftests/etc/testdefs/BatchSize.json
deleted file mode 100644
index eeb446bad6..0000000000
--- a/java/perftests/etc/testdefs/BatchSize.json
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "_tests":[
- {
- "_name": "Batch Size- PERSISTENT";
- "_iterations":[
- {
- "_batchSize": 1
- },
- {
- "_batchSize": 2
- },
- {
- "_batchSize": 5
- },
- {
- "_batchSize": 10
- },
- {
- "_batchSize": 20
- },
- {
- "_batchSize": 50
- },
- {
- "_batchSize": 100
- }
- ],
- "_queues":[
- {
- "_name": "direct://amq.direct//batchSize?durable='true'",
- "_durable": true
- }
- ],
- "_clients":[
- {
- "_name": "producingClient",
- "_connections":[
- {
- "_name": "connection1",
- "_factory": "connectionfactory",
- "_sessions": [
- {
- "_sessionName": "session1",
- "_acknowledgeMode": 0,
- "_producers": [
- {
- "_name": "Producer1",
- "_destinationName": "direct://amq.direct//batchSize?durable='true'",
- "_messageSize": 1024,
- "_maximumDuration": 30000,
- "_deliveryMode": 2
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "_name": "consumingClient",
- "_connections":[
- {
- "_name": "connection1",
- "_factory": "connectionfactory",
- "_sessions": [
- {
- "_sessionName": "session1",
- "_acknowledgeMode": 0,
- "_consumers": [
- {
- "_name": "Consumer1",
- "_destinationName": "direct://amq.direct//batchSize?durable='true'",
- "_maximumDuration": 30000
- }
- ]
- }
- ]
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/java/perftests/etc/testdefs/BatchSizeConsumerVaries.js b/java/perftests/etc/testdefs/BatchSizeConsumerVaries.js
new file mode 100644
index 0000000000..b491f431c9
--- /dev/null
+++ b/java/perftests/etc/testdefs/BatchSizeConsumerVaries.js
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+var jsonObject = {
+ _tests:[]
+};
+
+var duration = 30000;
+
+var txBatchSizes = [[1,1], [1,2], [1,5], [1,10], [1,20], [1,50], [1,100], [1,200], [1,400]];
+
+var acknowledgeMode = 0;
+var deliveryMode = 2;
+var messageSize = 1024;
+
+for(i=0; i < txBatchSizes.length ; i++)
+{
+ var producerBatchSize = txBatchSizes[i][0];
+ var consumerBatchSize = txBatchSizes[i][1];
+ var queueName = "txBatchSize" + producerBatchSize + "_" + consumerBatchSize;
+ var destination = "direct://amq.direct//" + queueName + "?durable='true'";
+
+ var test = {
+ "_name": consumerBatchSize,// hack - use test name to expose the consumer batch size on the All result rows
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": true
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_producers": [
+ {
+ "_name": "Producer1",
+ "_destinationName": destination,
+ "_messageSize": messageSize,
+ "_deliveryMode": deliveryMode,
+ "_batchSize": producerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_name": "consumingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_consumers": [
+ {
+ "_name": "Consumer1",
+ "_destinationName": destination,
+ "_batchSize": consumerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+
+ jsonObject._tests= jsonObject._tests.concat(test);
+}
diff --git a/java/perftests/etc/testdefs/BatchSizeProducerVaries.js b/java/perftests/etc/testdefs/BatchSizeProducerVaries.js
new file mode 100644
index 0000000000..ac23c52c9e
--- /dev/null
+++ b/java/perftests/etc/testdefs/BatchSizeProducerVaries.js
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+var jsonObject = {
+ _tests:[]
+};
+
+var duration = 30000;
+
+var txBatchSizes = [[1,1], [2,1], [5,1], [10,1], [20,1], [50,1], [100,1], [200,1], [400,1]];
+
+var acknowledgeMode = 0;
+var deliveryMode = 2;
+var messageSize = 1024;
+
+for(i=0; i < txBatchSizes.length ; i++)
+{
+ var producerBatchSize = txBatchSizes[i][0];
+ var consumerBatchSize = txBatchSizes[i][1];
+ var queueName = "txBatchSize" + producerBatchSize + "_" + consumerBatchSize;
+ var destination = "direct://amq.direct//" + queueName + "?durable='true'";
+
+ var test = {
+ "_name": producerBatchSize,// hack - use test name to expose the producer batch size on the All result rows
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": true
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_producers": [
+ {
+ "_name": "Producer1",
+ "_destinationName": destination,
+ "_messageSize": messageSize,
+ "_deliveryMode": deliveryMode,
+ "_batchSize": producerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_name": "consumingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": acknowledgeMode,
+ "_consumers": [
+ {
+ "_name": "Consumer1",
+ "_destinationName": destination,
+ "_batchSize": consumerBatchSize,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+
+ jsonObject._tests= jsonObject._tests.concat(test);
+}
diff --git a/java/perftests/etc/testdefs/QueueConsumersWithNonOverlappingSelectors.js b/java/perftests/etc/testdefs/QueueConsumersWithNonOverlappingSelectors.js
new file mode 100644
index 0000000000..0dd45b0392
--- /dev/null
+++ b/java/perftests/etc/testdefs/QueueConsumersWithNonOverlappingSelectors.js
@@ -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.
+ *
+ */
+var jsonObject = {
+ _tests:[]
+};
+
+for (var i=0; i<2; i++)
+{
+ var deliveryMode = i+1;
+ var durable = (deliveryMode == 2);
+ var suffix = durable ? "PERSISTENT" : "NON-PERSISTENT";
+ var queueName = "direct://amq.direct//queue-selectors-" + suffix + "?durable='" + durable + "'";
+ var consumerNumbers = [1, 2, 4, 8, 16, 32];
+ var consumerAcknowledgeMode = 1;
+ for (var j=0; j<consumerNumbers.length; j++)
+ {
+ var consumerNumber = consumerNumbers[j];
+ var testName = "Queues with selectors: " +consumerNumber + " consumers - 1 producer - non overlapping - " + suffix;
+ var test = {
+ "_name": testName,
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": durable,
+ "_attributes":
+ {
+ "x-qpid-capacity": 10485760,
+ "x-qpid-flow-resume-capacity": 8388608
+ }
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_messageProviders": [
+ {
+ "_name": "messageProvider",
+ "_messageProperties": {
+ "id": {
+ "@def": "range",
+ "_lower": 1,
+ "_upper": consumerNumber,
+ "_type": "int"
+ }
+ }
+ }
+ ],
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": 1,
+ "_producers": [
+ {
+ "_name": "Producer1",
+ "_destinationName": queueName,
+ "_maximumDuration": 60000,
+ "_deliveryMode": deliveryMode,
+ "_messageSize": 1024,
+ "_messageProviderName": "messageProvider"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_name": "consumingClient",
+ "_connections":[]
+ }
+ ]
+ };
+ for(var n=0; n<consumerNumber; n++)
+ {
+ var consumerConnection = {
+ "_name": "connection" + n,
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session" + n,
+ "_acknowledgeMode": consumerAcknowledgeMode,
+ "_consumers": [
+ {
+ "_name": "Consumer" + n,
+ "_destinationName": queueName,
+ "_maximumDuration": 60000,
+ "_selector": "id=" + ( n + 1)
+ }
+ ]
+ }
+ ]
+ };
+ test._clients[1]._connections.push(consumerConnection);
+ }
+ jsonObject._tests.push(test);
+ }
+}
+
diff --git a/java/perftests/etc/testdefs/QueueConsumersWithOverlappingSelectors.js b/java/perftests/etc/testdefs/QueueConsumersWithOverlappingSelectors.js
new file mode 100644
index 0000000000..20cfb4ad45
--- /dev/null
+++ b/java/perftests/etc/testdefs/QueueConsumersWithOverlappingSelectors.js
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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.
+ *
+ */
+var jsonObject = {
+ _tests:[]
+};
+
+for (var i=0; i<2; i++)
+{
+ var deliveryMode = i+1;
+ var durable = (deliveryMode == 2);
+ var suffix = durable ? "PERSISTENT" : "NON-PERSISTENT";
+ var queueName = "direct://amq.direct//queue-selectors-overlapping-" + suffix + "?durable='" + durable + "'";
+ var consumerNumbers = [2, 4, 8, 16, 32];
+ var consumerAcknowledgeMode = 1;
+ for (var j=0; j<consumerNumbers.length; j++)
+ {
+ var consumerNumber = consumerNumbers[j];
+ var testName = "Queues with selectors: " +consumerNumber + " consumers - 1 producer - 50% overlapping - " + suffix;
+ var test = {
+ "_name": testName,
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": durable,
+ "_attributes":
+ {
+ "x-qpid-capacity": 10485760,
+ "x-qpid-flow-resume-capacity": 8388608
+ }
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_messageProviders": [
+ {
+ "_name": "messageProvider",
+ "_messageProperties": {
+ "id": {
+ "@def": "range",
+ "_lower": 1,
+ "_upper": consumerNumber * 2,
+ "_type": "int"
+ }
+ }
+ }
+ ],
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session1",
+ "_acknowledgeMode": 1,
+ "_producers": [
+ {
+ "_name": "Producer1",
+ "_destinationName": queueName,
+ "_maximumDuration": 60000,
+ "_deliveryMode": deliveryMode,
+ "_messageSize": 1024,
+ "_messageProviderName": "messageProvider"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "_name": "consumingClient",
+ "_connections":[]
+ }
+ ]
+ };
+
+ var selectorBase = "";
+ var maxId = consumerNumber * 2;
+ // odd IDs overlaps in each selector expression
+ for (var m = 1; m <= maxId; m+=2)
+ {
+ selectorBase += " or id=" + m;
+ }
+ for(var n = 0, id = 0 ; n< consumerNumber; n++)
+ {
+ // even IDs are unique per each selector expression
+ id = id + 2;
+ selector = "id=" + id + selectorBase;
+ var consumerConnection = {
+ "_name": "connection" + n,
+ "_factory": "connectionfactory",
+ "_sessions": [
+ {
+ "_sessionName": "session" + n,
+ "_acknowledgeMode": consumerAcknowledgeMode,
+ "_consumers": [
+ {
+ "_name": "Consumer" + n,
+ "_destinationName": queueName,
+ "_maximumDuration": 60000,
+ "_selector": selector
+ }
+ ]
+ }
+ ]
+ };
+ test._clients[1]._connections.push(consumerConnection);
+ }
+ jsonObject._tests.push(test);
+ }
+}
+
diff --git a/java/perftests/etc/testdefs/Topic-AckModes.js b/java/perftests/etc/testdefs/Topic-AckModes.js
index 63c4b8646e..3f7eb5d3a7 100644
--- a/java/perftests/etc/testdefs/Topic-AckModes.js
+++ b/java/perftests/etc/testdefs/Topic-AckModes.js
@@ -27,13 +27,10 @@ var jsonObject = {
"_name": "Topic ack modes",
"_iterations": [
{
- "_acknowledgeMode": 1
- },
- {
- "_acknowledgeMode": 2
+ "_acknowledgeMode": 0
},
{
- "_acknowledgeMode": 3
+ "_acknowledgeMode": 1
}
],
"_clients": [
@@ -50,6 +47,7 @@ var jsonObject = {
{
"_name": "Producer",
"_destinationName": topicName,
+ "_isTopic": true,
"_deliveryMode": 1,
"_maximumDuration": duration,
"_startDelay": 2000 // gives the consumers time to implicitly create the topic
@@ -75,6 +73,7 @@ var jsonObject = {
{
"_name": "Consumer-__INDEX",
"_destinationName": topicName,
+ "_isTopic": true,
"_maximumDuration": duration,
}
]
diff --git a/java/perftests/etc/testdefs/Topic-NumberOfConsumers.js b/java/perftests/etc/testdefs/Topic-NumberOfConsumers.js
index 58ae2f5862..1d38ff08e5 100644
--- a/java/perftests/etc/testdefs/Topic-NumberOfConsumers.js
+++ b/java/perftests/etc/testdefs/Topic-NumberOfConsumers.js
@@ -42,10 +42,12 @@ for(i=0; i < numbersOfConsumers.length ; i++)
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_producers": [
{
"_name": "Producer1",
"_destinationName": topicName,
+ "_isTopic": true,
"_deliveryMode": 1,
"_maximumDuration": duration,
"_startDelay": 2000 // gives the consumers time to implicitly create the topic
@@ -66,10 +68,12 @@ for(i=0; i < numbersOfConsumers.length ; i++)
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_consumers": [
{
"_name": "Consumer-__INDEX",
"_destinationName": topicName,
+ "_isTopic": true,
"_maximumDuration": duration
}
]
diff --git a/java/perftests/etc/testdefs/Topic-NumberOfTopics.js b/java/perftests/etc/testdefs/Topic-NumberOfTopics.js
index d31dd36c76..811f8e3a07 100644
--- a/java/perftests/etc/testdefs/Topic-NumberOfTopics.js
+++ b/java/perftests/etc/testdefs/Topic-NumberOfTopics.js
@@ -45,10 +45,12 @@ for(i=0; i < numbersOfTopics.length ; i++)
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_producers": [
{
"_name": "Producer-__INDEX",
"_destinationName": topicName,
+ "_isTopic": true,
"_deliveryMode": 1,
"_maximumDuration": duration,
"_startDelay": 2000 // gives the consumers time to implicitly create the topic
@@ -71,10 +73,12 @@ for(i=0; i < numbersOfTopics.length ; i++)
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_consumers": [
{
"_name": "Consumer-__INDEX",
"_destinationName": topicName,
+ "_isTopic": true,
"_maximumDuration": duration
}
]
diff --git a/java/perftests/etc/testdefs/Topic-Persistence.js b/java/perftests/etc/testdefs/Topic-Persistence.js
index bbec7ab8ed..96872b6c55 100644
--- a/java/perftests/etc/testdefs/Topic-Persistence.js
+++ b/java/perftests/etc/testdefs/Topic-Persistence.js
@@ -26,8 +26,9 @@ var jsonObject = {
{
"_name": "Topic persistence",
"_iterations": [
- // note that we use _durableSubscription (the JaveBeans property name)
- // rather than _isDurableSubscription (the field name)
+ // Note that we use _durableSubscription (more like the JavaBeans property name)
+ // rather than _isDurableSubscription (the field name, which we use elsewhere).
+ // This convention is required within the _iterations definition.
{
"_deliveryMode": 1,
"_durableSubscription": false
@@ -47,10 +48,12 @@ var jsonObject = {
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_producers": [
{
"_name": "Producer",
"_destinationName": topicName,
+ "_isTopic": true,
"_maximumDuration": duration,
"_startDelay": 2000 // gives the consumers time to implicitly create the topic
}
@@ -71,6 +74,7 @@ var jsonObject = {
"_sessions": [
{
"_sessionName": "session1",
+ "_acknowledgeMode": 0,
"_consumers": [
{
"_name": "Consumer-__INDEX",
diff --git a/java/perftests/etc/testdefs/VaryingNumberOfParticipants.json b/java/perftests/etc/testdefs/VaryingNumberOfParticipants.json
index 457b0bc348..03dd2848b6 100644
--- a/java/perftests/etc/testdefs/VaryingNumberOfParticipants.json
+++ b/java/perftests/etc/testdefs/VaryingNumberOfParticipants.json
@@ -8,6 +8,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -18,7 +26,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -42,7 +49,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -65,6 +71,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -75,7 +89,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -99,7 +112,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -116,7 +128,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -139,6 +150,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -149,7 +168,6 @@
"_sessions": [
{
"_sessionName": "session0",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -173,7 +191,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -190,7 +207,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -207,7 +223,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -224,7 +239,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -241,7 +255,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -267,6 +280,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -277,7 +298,6 @@
"_sessions": [
{
"_sessionName": "session0",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -301,7 +321,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -318,7 +337,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -335,7 +353,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -352,7 +369,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -369,7 +385,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -386,7 +401,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer6",
@@ -403,7 +417,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer7",
@@ -420,7 +433,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer8",
@@ -437,7 +449,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer9",
@@ -454,7 +465,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer10",
@@ -480,6 +490,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -490,7 +508,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -509,7 +526,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -533,7 +549,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -560,6 +575,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -570,7 +593,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -589,7 +611,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -613,7 +634,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -630,7 +650,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -657,6 +676,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -667,7 +694,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -686,7 +712,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -710,7 +735,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -727,7 +751,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -744,7 +767,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -761,7 +783,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -778,7 +799,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -804,6 +824,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -814,7 +842,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -833,7 +860,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -857,7 +883,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -874,7 +899,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -891,7 +915,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -908,7 +931,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -925,7 +947,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -942,7 +963,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer6",
@@ -959,7 +979,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer7",
@@ -976,7 +995,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer8",
@@ -993,7 +1011,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer9",
@@ -1010,7 +1027,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer10",
@@ -1036,6 +1052,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -1046,7 +1070,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -1065,7 +1088,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -1084,7 +1106,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -1103,7 +1124,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -1122,7 +1142,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -1146,7 +1165,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -1173,6 +1191,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -1183,7 +1209,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -1202,7 +1227,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -1221,7 +1245,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -1240,7 +1263,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -1259,7 +1281,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -1283,7 +1304,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -1300,7 +1320,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -1328,6 +1347,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -1338,7 +1365,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -1357,7 +1383,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -1376,7 +1401,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -1395,7 +1419,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -1414,7 +1437,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -1438,7 +1460,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -1455,7 +1476,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -1472,7 +1492,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -1489,7 +1508,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -1506,7 +1524,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -1532,6 +1549,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -1542,7 +1567,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -1561,7 +1585,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -1580,7 +1603,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -1599,7 +1621,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -1618,7 +1639,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -1642,7 +1662,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -1659,7 +1678,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -1676,7 +1694,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -1693,7 +1710,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -1710,7 +1726,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -1727,7 +1742,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer6",
@@ -1744,7 +1758,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer7",
@@ -1761,7 +1774,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer8",
@@ -1778,7 +1790,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer9",
@@ -1795,7 +1806,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer10",
@@ -1822,6 +1832,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -1832,7 +1850,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -1851,7 +1868,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -1870,7 +1886,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -1889,7 +1904,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -1908,7 +1922,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -1927,7 +1940,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer6",
@@ -1946,7 +1958,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer7",
@@ -1965,7 +1976,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer8",
@@ -1984,7 +1994,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer9",
@@ -2003,7 +2012,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer10",
@@ -2027,7 +2035,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -2054,6 +2061,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -2064,7 +2079,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -2083,7 +2097,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -2102,7 +2115,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -2121,7 +2133,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -2140,7 +2151,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -2159,7 +2169,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer6",
@@ -2178,7 +2187,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer7",
@@ -2197,7 +2205,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer8",
@@ -2216,7 +2223,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer9",
@@ -2235,7 +2241,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer10",
@@ -2259,7 +2264,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -2276,7 +2280,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -2304,6 +2307,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -2314,7 +2325,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -2333,7 +2343,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -2352,7 +2361,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -2371,7 +2379,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -2390,7 +2397,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -2409,7 +2415,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer6",
@@ -2428,7 +2433,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer7",
@@ -2447,7 +2451,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer8",
@@ -2466,7 +2469,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer9",
@@ -2485,7 +2487,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer10",
@@ -2509,7 +2510,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -2526,7 +2526,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -2543,7 +2542,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -2560,7 +2558,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -2577,7 +2574,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -2604,6 +2600,14 @@
"_durable": true
}
],
+ "_iterations":[
+ {
+ "_acknowledgeMode": 0
+ },
+ {
+ "_acknowledgeMode": 1
+ }
+ ],
"_clients":[
{
"_name": "producingClient",
@@ -2614,7 +2618,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer1",
@@ -2633,7 +2636,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer2",
@@ -2652,7 +2654,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer3",
@@ -2671,7 +2672,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer4",
@@ -2690,7 +2690,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer5",
@@ -2709,7 +2708,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer6",
@@ -2728,7 +2726,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer7",
@@ -2747,7 +2744,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer8",
@@ -2766,7 +2762,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer9",
@@ -2785,7 +2780,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_producers": [
{
"_name": "Producer10",
@@ -2809,7 +2803,6 @@
"_sessions": [
{
"_sessionName": "session1",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer1",
@@ -2826,7 +2819,6 @@
"_sessions": [
{
"_sessionName": "session2",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer2",
@@ -2843,7 +2835,6 @@
"_sessions": [
{
"_sessionName": "session3",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer3",
@@ -2860,7 +2851,6 @@
"_sessions": [
{
"_sessionName": "session4",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer4",
@@ -2877,7 +2867,6 @@
"_sessions": [
{
"_sessionName": "session5",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer5",
@@ -2894,7 +2883,6 @@
"_sessions": [
{
"_sessionName": "session6",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer6",
@@ -2911,7 +2899,6 @@
"_sessions": [
{
"_sessionName": "session7",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer7",
@@ -2928,7 +2915,6 @@
"_sessions": [
{
"_sessionName": "session8",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer8",
@@ -2945,7 +2931,6 @@
"_sessions": [
{
"_sessionName": "session9",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer9",
@@ -2962,7 +2947,6 @@
"_sessions": [
{
"_sessionName": "session10",
- "_acknowledgeMode": 1,
"_consumers": [
{
"_name": "Consumer10",
diff --git a/java/perftests/etc/testdefs/VaryingNumberOfProducerSessionsSingleConnection.js b/java/perftests/etc/testdefs/VaryingNumberOfProducerSessionsSingleConnection.js
new file mode 100644
index 0000000000..c62a8344b1
--- /dev/null
+++ b/java/perftests/etc/testdefs/VaryingNumberOfProducerSessionsSingleConnection.js
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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.
+ *
+ */
+var jsonObject = {
+ _tests:[]
+};
+
+var duration = 30000;
+var queueName = "direct://amq.direct//varNumOfSessions?durable='true'";
+
+var numbersOfSessions = [1, 2, 5, 10, 20, 40, 80];
+var numberOfConsumingClients = 20;
+
+for(i=0; i < numbersOfSessions.length ; i++)
+{
+ var sessionNumber = numbersOfSessions[i];
+ var test = {
+ "_name": sessionNumber,
+ "_queues":[
+ {
+ "_name": queueName,
+ "_durable": "true"
+ }
+ ],
+ "_clients":[
+ {
+ "_name": "producingClient",
+ "_connections":[
+ {
+ "_name": "connection1",
+ "_factory": "connectionfactory",
+ "_sessions": QPID.times(sessionNumber,
+ {
+ "_sessionName": "session__SESSION_INDEX",
+ "_producers": [
+ {
+ "_name": "Producer__SESSION_INDEX",
+ "_destinationName": queueName,
+ "_deliveryMode": 2,
+ "_acknowledgeMode": 0,
+ "_maximumDuration": duration
+ }
+ ]
+ },
+ "__SESSION_INDEX")
+ }
+ ]
+ },
+ ].concat(QPID.times(numberOfConsumingClients,
+ {
+ "_name": "consumingClient__CONSUMING_CLIENT_INDEX",
+ "_connections":[
+ {
+ "_name": "client__CONSUMING_CLIENT_INDEXconnection1",
+ "_factory": "connectionfactory",
+ "_sessions":
+ [
+ {
+ "_sessionName": "client__CONSUMING_CLIENT_INDEXsession1",
+ "_consumers": [
+ {
+ "_name": "client__CONSUMING_CLIENT_INDEXConsumer1Session1",
+ "_destinationName": queueName,
+ "_acknowledgeMode": 1,
+ "_maximumDuration": duration
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "__CONSUMING_CLIENT_INDEX"))
+ };
+
+ jsonObject._tests= jsonObject._tests.concat(test);
+}
+
diff --git a/java/perftests/etc/visualisation-timeseries.sh b/java/perftests/etc/visualisation-timeseries.sh
new file mode 100755
index 0000000000..32db2cb010
--- /dev/null
+++ b/java/perftests/etc/visualisation-timeseries.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# 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.
+#
+
+# Runs the visualisation tool against perftest output assumed to be in a Derby database in the current directory
+
+BASE_DIR=`dirname $0`
+
+# Uncomment to read perftest data from a Derby database
+JDBC_URL=jdbcUrl=jdbc:derby:perftestResultsDb
+JDBC_DRIVER=jdbcDriverClass=org.apache.derby.jdbc.EmbeddedDriver
+
+java -cp "${BASE_DIR}:${BASE_DIR}/../../build/lib/*" \
+ -Djava.awt.headless=true -Dlog4j.configuration=file:log4j.properties \
+ org.apache.qpid.disttest.charting.ChartingUtil \
+ chart-defs=chartdefs/timeseries \
+ ${JDBC_DRIVER} ${JDBC_URL}
diff --git a/java/perftests/etc/visualisation.sh b/java/perftests/etc/visualisation.sh
new file mode 100755
index 0000000000..53a3f94f9c
--- /dev/null
+++ b/java/perftests/etc/visualisation.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# 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.
+#
+
+# Runs the visualisation tool against perftest CSV output assumed to be in the current directory
+
+BASE_DIR=`dirname $0`
+
+# Uncomment to read perftest data from a Derby database
+# JDBC_URL=jdbcUrl=jdbc:derby:perftestResultsDb
+# JDBC_DRIVER=jdbcDriverClass=org.apache.derby.jdbc.EmbeddedDriver
+
+java -cp "${BASE_DIR}:${BASE_DIR}/../../build/lib/*" \
+ -Djava.awt.headless=true -Dlog4j.configuration=file:log4j.properties \
+ -DcsvCurrentDir=. \
+ -DcsvBaselineDir=. \
+ org.apache.qpid.disttest.charting.ChartingUtil \
+ chart-defs=chartdefs \
+ ${JDBC_DRIVER} ${JDBC_URL}
diff --git a/java/perftests/example/brokerconfig/log4j.xml b/java/perftests/example/brokerconfig/log4j.xml
index 7dbb1bc87d..7e53d2667b 100644
--- a/java/perftests/example/brokerconfig/log4j.xml
+++ b/java/perftests/example/brokerconfig/log4j.xml
@@ -68,7 +68,7 @@
<param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%t] (%c{2}) - %m%n"/>
</layout>
</appender>
diff --git a/java/perftests/example/perftests-jndi.properties b/java/perftests/example/perftests-jndi.properties
index 04a8ad9101..1c0fd57663 100644
--- a/java/perftests/example/perftests-jndi.properties
+++ b/java/perftests/example/perftests-jndi.properties
@@ -24,3 +24,6 @@ java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextF
connectionfactory.connectionfactory = amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672'
destination.controllerqueue = direct://amq.direct//controllerqueue?autodelete='true'
+
+driverName=org.apache.derby.jdbc.EmbeddedDriver
+jdbcUrl=jdbc:derby:/tmp/perftestResultsDb;create=true
diff --git a/java/perftests/example/run.sh b/java/perftests/example/run.sh
index cb68c52853..31124a060a 100755
--- a/java/perftests/example/run.sh
+++ b/java/perftests/example/run.sh
@@ -18,5 +18,5 @@
# under the License.
#
-java -cp ".:${QPID_HOME}/lib/*" -Dqpid.dest_syntax=BURL org.apache.qpid.disttest.ControllerRunner jndi-config=perftests-jndi.properties test-config=$1 distributed=false
+java -cp ".:${QPID_HOME}/lib/*" -Dqpid.dest_syntax=BURL org.apache.qpid.disttest.ControllerRunner jndi-config=perftests-jndi.properties test-config=$1 distributed=false writeToDb=true
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java b/java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java
index 8c1f8675e3..e962bfe799 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java
@@ -34,10 +34,14 @@ public class ArgumentParser
throw new IllegalArgumentException("arguments must have format <name>=<value>: " + arg);
}
- if(initialValues.put(splitArg[0], splitArg[1]) == null)
+
+ String argumentKey = splitArg[0];
+ String argumentValue = splitArg[1];
+ if(!initialValues.containsKey(argumentKey))
{
throw new IllegalArgumentException("not a valid configuration property: " + arg);
}
+ initialValues.put(argumentKey, argumentValue);
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/ConfigFileHelper.java b/java/perftests/src/main/java/org/apache/qpid/disttest/ConfigFileHelper.java
index fb4c1b700b..ee374e180d 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/ConfigFileHelper.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/ConfigFileHelper.java
@@ -60,15 +60,4 @@ public class ConfigFileHelper
return testConfigFile;
}
-
- /**
- * generateOutputCsvNameFrom("/config/testConfigFile.js", "/output") returns /output/testConfigFile.csv
- */
- public String generateOutputCsvNameFrom(String testConfigFile, String outputDir)
- {
- final String filenameOnlyWithExtension = new File(testConfigFile).getName();
- final String cvsFile = filenameOnlyWithExtension.replaceFirst(".?\\w*$", ".csv");
-
- return new File(outputDir, cvsFile).getAbsolutePath();
- }
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java b/java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java
index aea0ea301a..449130a328 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java
@@ -19,9 +19,9 @@
*/
package org.apache.qpid.disttest;
+import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
@@ -30,9 +30,9 @@ import org.apache.qpid.disttest.controller.Controller;
import org.apache.qpid.disttest.controller.ResultsForAllTests;
import org.apache.qpid.disttest.controller.config.Config;
import org.apache.qpid.disttest.controller.config.ConfigReader;
+import org.apache.qpid.disttest.db.ResultsDbWriter;
import org.apache.qpid.disttest.jms.ControllerJmsDelegate;
import org.apache.qpid.disttest.results.aggregation.Aggregator;
-import org.apache.qpid.disttest.results.formatting.CSVFormater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,20 +43,29 @@ public class ControllerRunner extends AbstractRunner
public static final String TEST_CONFIG_PROP = "test-config";
public static final String DISTRIBUTED_PROP = "distributed";
public static final String OUTPUT_DIR_PROP = "outputdir";
+ public static final String WRITE_TO_DB = "writeToDb";
+ public static final String RUN_ID = "runId";
private static final String TEST_CONFIG_DEFAULT = "perftests-config.json";
private static final String DISTRIBUTED_DEFAULT = "false";
private static final String OUTPUT_DIR_DEFAULT = ".";
+ public static final String WRITE_TO_DB_DEFAULT = "false";
private final Aggregator _aggregator = new Aggregator();
private final ConfigFileHelper _configFileHelper = new ConfigFileHelper();
+ private ResultsFileWriter _resultsFileWriter;
+
+ private ResultsDbWriter _resultsDbWriter;
+
public ControllerRunner()
{
getCliOptions().put(TEST_CONFIG_PROP, TEST_CONFIG_DEFAULT);
getCliOptions().put(DISTRIBUTED_PROP, DISTRIBUTED_DEFAULT);
getCliOptions().put(OUTPUT_DIR_PROP, OUTPUT_DIR_DEFAULT);
+ getCliOptions().put(WRITE_TO_DB, WRITE_TO_DB_DEFAULT);
+ getCliOptions().put(RUN_ID, null);
}
public static void main(String[] args) throws Exception
@@ -69,6 +78,8 @@ public class ControllerRunner extends AbstractRunner
public void runController() throws Exception
{
Context context = getContext();
+ setUpResultFilesWriter();
+ setUpResultsDbWriter();
ControllerJmsDelegate jmsDelegate = new ControllerJmsDelegate(context);
@@ -82,6 +93,24 @@ public class ControllerRunner extends AbstractRunner
}
}
+ private void setUpResultsDbWriter()
+ {
+ String writeToDbStr = getCliOptions().get(WRITE_TO_DB);
+ if(Boolean.valueOf(writeToDbStr))
+ {
+ String runId = getCliOptions().get(RUN_ID);
+ _resultsDbWriter = new ResultsDbWriter(getContext(), runId);
+ _resultsDbWriter.createResultsTableIfNecessary();
+ }
+ }
+
+ void setUpResultFilesWriter()
+ {
+ String outputDirString = getCliOptions().get(ControllerRunner.OUTPUT_DIR_PROP);
+ File outputDir = new File(outputDirString);
+ _resultsFileWriter = new ResultsFileWriter(outputDir);
+ }
+
private void runTests(ControllerJmsDelegate jmsDelegate)
{
Controller controller = new Controller(jmsDelegate, DistributedTestConstants.REGISTRATION_TIMEOUT, DistributedTestConstants.COMMAND_RESPONSE_TIMEOUT);
@@ -92,6 +121,8 @@ public class ControllerRunner extends AbstractRunner
try
{
+ List<ResultsForAllTests> results = new ArrayList<ResultsForAllTests>();
+
for (String testConfigFile : testConfigFiles)
{
final Config testConfig = buildTestConfigFrom(testConfigFile);
@@ -100,8 +131,11 @@ public class ControllerRunner extends AbstractRunner
controller.awaitClientRegistrations();
LOGGER.info("Running test : " + testConfigFile);
- runTest(controller, testConfigFile);
+ ResultsForAllTests testResult = runTest(controller, testConfigFile);
+ results.add(testResult);
}
+
+ _resultsFileWriter.writeResultsSummary(results);
}
catch(Exception e)
{
@@ -113,7 +147,7 @@ public class ControllerRunner extends AbstractRunner
}
}
- private void runTest(Controller controller, String testConfigFile)
+ private ResultsForAllTests runTest(Controller controller, String testConfigFile)
{
final Config testConfig = buildTestConfigFrom(testConfigFile);
controller.setConfig(testConfig);
@@ -121,9 +155,13 @@ public class ControllerRunner extends AbstractRunner
ResultsForAllTests rawResultsForAllTests = controller.runAllTests();
ResultsForAllTests resultsForAllTests = _aggregator.aggregateResults(rawResultsForAllTests);
- String outputDir = getCliOptions().get(ControllerRunner.OUTPUT_DIR_PROP);
- final String outputFile = _configFileHelper.generateOutputCsvNameFrom(testConfigFile, outputDir);
- writeResultsToFile(resultsForAllTests, outputFile);
+ _resultsFileWriter.writeResultsToFile(resultsForAllTests, testConfigFile);
+ if(_resultsDbWriter != null)
+ {
+ _resultsDbWriter.writeResults(resultsForAllTests);
+ }
+
+ return resultsForAllTests;
}
private void createClientsIfNotDistributed(final List<String> testConfigFiles)
@@ -148,36 +186,6 @@ public class ControllerRunner extends AbstractRunner
}
}
- private void writeResultsToFile(ResultsForAllTests resultsForAllTests, String outputFile)
- {
- FileWriter writer = null;
- try
- {
- final String outputCsv = new CSVFormater().format(resultsForAllTests);
- writer = new FileWriter(outputFile);
- writer.write(outputCsv);
- LOGGER.info("Wrote " + resultsForAllTests.getTestResults().size() + " test result(s) to output file " + outputFile);
- }
- catch (IOException e)
- {
- throw new DistributedTestException("Unable to write output file " + outputFile, e);
- }
- finally
- {
- if (writer != null)
- {
- try
- {
- writer.close();
- }
- catch (IOException e)
- {
- LOGGER.error("Failed to close stream for file " + outputFile, e);
- }
- }
- }
- }
-
private Config buildTestConfigFrom(String testConfigFile)
{
ConfigReader configReader = new ConfigReader();
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/ResultsFileWriter.java b/java/perftests/src/main/java/org/apache/qpid/disttest/ResultsFileWriter.java
new file mode 100644
index 0000000000..81b717403d
--- /dev/null
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/ResultsFileWriter.java
@@ -0,0 +1,112 @@
+/*
+ * 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.disttest;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.disttest.results.aggregation.TestResultAggregator;
+import org.apache.qpid.disttest.results.formatting.CSVFormatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResultsFileWriter
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(ResultsFileWriter.class);
+
+ static final String TEST_SUMMARY_FILE_NAME = "test-summary.csv";
+
+ private final File _outputDir;
+
+ private CSVFormatter _csvFormater = new CSVFormatter();
+
+ private TestResultAggregator _testResultAggregator = new TestResultAggregator();
+
+ public ResultsFileWriter(File outputDir)
+ {
+ _outputDir = outputDir;
+ }
+
+ public void writeResultsToFile(ResultsForAllTests resultsForAllTests, String testConfigFile)
+ {
+ final String outputFile = generateOutputCsvNameFrom(testConfigFile);
+ writeResultsToOutputFile(resultsForAllTests, outputFile);
+ }
+
+ public void writeResultsSummary(List<ResultsForAllTests> allResultsList)
+ {
+ ResultsForAllTests combinedResults = _testResultAggregator.aggregateTestResults(allResultsList);
+ writeResultsToOutputFile(combinedResults, new File(_outputDir, TEST_SUMMARY_FILE_NAME).getAbsolutePath());
+ }
+
+ /**
+ * generateOutputCsvNameFrom("/config/testConfigFile.js", "/output") returns /output/testConfigFile.csv
+ */
+ private String generateOutputCsvNameFrom(String testConfigFile)
+ {
+ final String filenameOnlyWithExtension = new File(testConfigFile).getName();
+ final String cvsFile = filenameOnlyWithExtension.replaceFirst(".?\\w*$", ".csv");
+
+ return new File(_outputDir, cvsFile).getAbsolutePath();
+ }
+
+ private void writeResultsToOutputFile(ResultsForAllTests resultsForAllTests, String outputFile)
+ {
+ FileWriter writer = null;
+ try
+ {
+ final String outputCsv = _csvFormater.format(resultsForAllTests);
+ writer = new FileWriter(outputFile);
+ writer.write(outputCsv);
+ LOGGER.info("Wrote " + resultsForAllTests.getTestResults().size() + " test result(s) to output file " + outputFile);
+ }
+ catch (IOException e)
+ {
+ throw new DistributedTestException("Unable to write output file " + outputFile, e);
+ }
+ finally
+ {
+ if (writer != null)
+ {
+ try
+ {
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ LOGGER.error("Failed to close stream for file " + outputFile, e);
+ }
+ }
+ }
+ }
+
+ void setCsvFormater(CSVFormatter csvFormater)
+ {
+ _csvFormater = csvFormater;
+ }
+
+ void setTestResultAggregator(TestResultAggregator testResultAggregator)
+ {
+ _testResultAggregator = testResultAggregator;
+ }
+
+}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java
index f9d50e8e64..d3a5e30191 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java
@@ -35,7 +35,6 @@ import javax.jms.MessageListener;
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.jms.ClientJmsDelegate;
-import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.CreateConsumerCommand;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.slf4j.Logger;
@@ -103,16 +102,22 @@ public class ConsumerParticipant implements Participant
}
Date end = new Date();
- int numberOfMessagesSent = _totalNumberOfMessagesReceived.get();
+ int numberOfMessagesReceived = _totalNumberOfMessagesReceived.get();
long totalPayloadSize = _totalPayloadSizeOfAllMessagesReceived.get();
int payloadSize = getPayloadSizeForResultIfConstantOrZeroOtherwise(_allConsumedPayloadSizes);
- ConsumerParticipantResult result = _resultFactory.createForConsumer(
+ if (LOGGER.isInfoEnabled())
+ {
+ LOGGER.info("Consumer {} finished consuming. Number of messages consumed: {}",
+ getName(), numberOfMessagesReceived);
+ }
+
+ ParticipantResult result = _resultFactory.createForConsumer(
getName(),
registeredClientName,
_command,
acknowledgeMode,
- numberOfMessagesSent,
+ numberOfMessagesReceived,
payloadSize,
totalPayloadSize,
start, end, _messageLatencies);
@@ -174,7 +179,7 @@ public class ConsumerParticipant implements Participant
{
LOGGER.trace("Committing: batch size " + _command.getBatchSize() );
}
- _jmsDelegate.commitOrAcknowledgeMessage(message, _command.getSessionName());
+ _jmsDelegate.commitOrAcknowledgeMessageIfNecessary(_command.getSessionName(), message);
}
}
@@ -199,7 +204,7 @@ public class ConsumerParticipant implements Participant
}
// commit/acknowledge remaining messages if necessary
- _jmsDelegate.commitOrAcknowledgeMessage(message, _command.getSessionName());
+ _jmsDelegate.commitOrAcknowledgeMessageIfNecessary(_command.getSessionName(), message);
}
return false;
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java
index bb9ce26f7e..10f62708a4 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java
@@ -108,8 +108,16 @@ public class ParticipantExecutor
}
finally
{
+ try
+ {
+ _participant.releaseResources();
+ }
+ catch(Exception e)
+ {
+ LOGGER.error("Participant " + _participant + " unable to release resources", e);
+ }
+
_client.sendResults(result);
- _participant.releaseResources();
}
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java
index 63cbe98b5c..a9da837dea 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java
@@ -58,17 +58,25 @@ public class ProducerParticipant implements Participant
@Override
public ParticipantResult doIt(String registeredClientName) throws Exception
{
- if (_command.getMaximumDuration() == 0 && _command.getNumberOfMessages() == 0)
+ long numberOfMessages = _command.getNumberOfMessages();
+ long maximumDuration = _command.getMaximumDuration();
+
+ if (maximumDuration == 0 && numberOfMessages == 0)
{
throw new DistributedTestException("number of messages and duration cannot both be zero");
}
- int acknowledgeMode = _jmsDelegate.getAcknowledgeMode(_command.getSessionName());
+ long duration = maximumDuration - _command.getStartDelay();
+ if (maximumDuration > 0 && duration <= 0)
+ {
+ throw new DistributedTestException("Start delay must be less than maximum test duration");
+ }
+ final long requiredDuration = duration > 0 ? duration : 0;
doSleepForStartDelay();
- final long requiredDuration = _command.getMaximumDuration() - _command.getStartDelay();
-
+ final int batchSize = _command.getBatchSize();
+ final int acknowledgeMode = _jmsDelegate.getAcknowledgeMode(_command.getSessionName());
final long startTime = System.currentTimeMillis();
Message lastPublishedMessage = null;
@@ -78,10 +86,20 @@ public class ProducerParticipant implements Participant
_limiter = ExecutorWithLimitsFactory.createExecutorWithLimit(startTime, requiredDuration);
- LOGGER.info("Producer {} about to send messages", getName());
+ if (LOGGER.isInfoEnabled())
+ {
+ LOGGER.info("Producer {} about to send messages. Duration limit: {} ms, Message limit: {}",
+ new Object[]{getName(), requiredDuration, numberOfMessages});
+ }
while (true)
{
+ if (numberOfMessages > 0 && numberOfMessagesSent >= numberOfMessages
+ || requiredDuration > 0 && System.currentTimeMillis() - startTime >= requiredDuration)
+ {
+ break;
+ }
+
try
{
lastPublishedMessage = _limiter.execute(new Callable<Message>()
@@ -110,35 +128,35 @@ public class ProducerParticipant implements Participant
LOGGER.trace("message " + numberOfMessagesSent + " sent by " + this);
}
- final boolean batchLimitReached = _command.getBatchSize() <= 0
- || numberOfMessagesSent % _command.getBatchSize() == 0;
+ final boolean batchLimitReached = batchSize <= 0
+ || numberOfMessagesSent % batchSize == 0;
if (batchLimitReached)
{
- if (LOGGER.isTraceEnabled() && _command.getBatchSize() > 0)
+ if (LOGGER.isTraceEnabled() && batchSize > 0)
{
- LOGGER.trace("Committing: batch size " + _command.getBatchSize() );
+ LOGGER.trace("Committing: batch size " + batchSize );
}
- _jmsDelegate.commitOrAcknowledgeMessage(lastPublishedMessage, _command.getSessionName());
+ _jmsDelegate.commitIfNecessary(_command.getSessionName());
doSleepForInterval();
}
-
- if (_command.getNumberOfMessages() > 0 && numberOfMessagesSent >= _command.getNumberOfMessages()
- || requiredDuration > 0 && System.currentTimeMillis() - startTime >= requiredDuration)
- {
- break;
- }
}
// commit the remaining batch messages
- if (_command.getBatchSize() > 0 && numberOfMessagesSent % _command.getBatchSize() != 0)
+ if (batchSize > 0 && numberOfMessagesSent % batchSize != 0)
{
if (LOGGER.isTraceEnabled())
{
- LOGGER.trace("Committing: batch size " + _command.getBatchSize() );
+ LOGGER.trace("Committing: batch size " + batchSize );
}
- _jmsDelegate.commitOrAcknowledgeMessage(lastPublishedMessage, _command.getSessionName());
+ _jmsDelegate.commitIfNecessary(_command.getSessionName());
+ }
+
+ if (LOGGER.isInfoEnabled())
+ {
+ LOGGER.info("Producer {} finished publishing. Number of messages published: {}",
+ getName(), numberOfMessagesSent);
}
Date start = new Date(startTime);
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java
index eaccb54f0e..5a726c50b4 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java
@@ -57,34 +57,54 @@ public class ClientRegistry
return Collections.unmodifiableSet(_registeredClientNames);
}
- public int awaitClients(int numberOfClientsToAwait, long timeout)
+ /**
+ * @return the number of clients that are still absent.
+ */
+ public int awaitClients(final int numberOfClientsToAwait, final long idleTimeout)
{
- final long endTime = System.currentTimeMillis() + timeout;
+ long deadlineForNextRegistration = deadline(idleTimeout);
- int numberOfClientsAbsent = numberOfClientsToAwait - _registeredClientNames.size();
- long remainingTimeout = endTime - System.currentTimeMillis();
+ int numberOfClientsAbsent = numberAbsent(numberOfClientsToAwait);
- while(numberOfClientsAbsent > 0 && remainingTimeout > 0)
+ while(numberOfClientsAbsent > 0 && System.currentTimeMillis() < deadlineForNextRegistration)
{
synchronized (_lock)
{
try
{
- _lock.wait(remainingTimeout);
+ _lock.wait(idleTimeout);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
+ return numberOfClientsAbsent;
}
}
- numberOfClientsAbsent = numberOfClientsToAwait - _registeredClientNames.size();
- remainingTimeout = endTime - System.currentTimeMillis();
+ int newNumberAbsent = numberAbsent(numberOfClientsToAwait);
+ if(newNumberAbsent < numberOfClientsAbsent)
+ {
+ // a registration was received since the last loop, so reset the timeout
+ deadlineForNextRegistration = deadline(idleTimeout);
+ }
+
+ numberOfClientsAbsent = newNumberAbsent;
}
return numberOfClientsAbsent < 0 ? 0 : numberOfClientsAbsent;
}
+
+ private long deadline(final long idleTimeout)
+ {
+ return System.currentTimeMillis() + idleTimeout;
+ }
+
+ private int numberAbsent(int numberOfClientsToAwait)
+ {
+ return numberOfClientsToAwait - _registeredClientNames.size();
+ }
+
private void notifyAllWaiters()
{
synchronized (_lock)
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java
index 6c5ff3450c..d4474e2c12 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java
@@ -21,7 +21,9 @@ package org.apache.qpid.disttest.controller;
import java.util.ArrayList;
import java.util.List;
+import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.results.aggregation.ITestResult;
+import org.apache.qpid.disttest.results.aggregation.TestResultAggregator;
public class ResultsForAllTests
{
@@ -46,4 +48,23 @@ public class ResultsForAllTests
{
return _hasErrors;
}
+
+ public ResultsForAllTests getAllParticipantsResult()
+ {
+ ResultsForAllTests summaryResultsForAllTests = new ResultsForAllTests();
+
+ for (ITestResult testResult : _results)
+ {
+ for(ParticipantResult participantResult : testResult.getParticipantResults())
+ {
+ if(TestResultAggregator.ALL_CONSUMER_PARTICIPANTS_NAME.equals(participantResult.getParticipantName()))
+ {
+ TestResult summaryTestResult = new TestResult(testResult.getName());
+ summaryTestResult.addParticipantResult(participantResult);
+ summaryResultsForAllTests.add(summaryTestResult);
+ }
+ }
+ }
+ return summaryResultsForAllTests;
+ }
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java
index 110de8a4ea..dcccccdd5f 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java
@@ -24,7 +24,6 @@ import org.apache.qpid.disttest.message.CreateConsumerCommand;
public class ConsumerConfig extends ParticipantConfig
{
- private boolean _isTopic;
private boolean _isDurableSubscription;
private boolean _isBrowsingSubscription;
private String _selector;
@@ -35,7 +34,6 @@ public class ConsumerConfig extends ParticipantConfig
// For Gson
public ConsumerConfig()
{
- _isTopic = false;
_isDurableSubscription = false;
_isBrowsingSubscription = false;
_selector = null;
@@ -56,9 +54,8 @@ public class ConsumerConfig extends ParticipantConfig
boolean noLocal,
boolean synchronous)
{
- super(consumerName, destinationName, numberOfMessages, batchSize, maximumDuration);
+ super(consumerName, destinationName, isTopic, numberOfMessages, batchSize, maximumDuration);
- _isTopic = isTopic;
_isDurableSubscription = isDurableSubscription;
_isBrowsingSubscription = isBrowsingSubscription;
_selector = selector;
@@ -73,7 +70,6 @@ public class ConsumerConfig extends ParticipantConfig
setParticipantProperties(createConsumerCommand);
createConsumerCommand.setSessionName(sessionName);
- createConsumerCommand.setTopic(_isTopic);
createConsumerCommand.setDurableSubscription(_isDurableSubscription);
createConsumerCommand.setBrowsingSubscription(_isBrowsingSubscription);
createConsumerCommand.setSelector(_selector);
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java
index 16f7b0d18d..99ae4b7426 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java
@@ -33,6 +33,7 @@ public abstract class ParticipantConfig
private boolean _alreadyLoggedAboutOverriddenDuration;
private String _destinationName;
+ private boolean _isTopic;
private long _numberOfMessages;
private String _name;
private int _batchSize;
@@ -51,12 +52,14 @@ public abstract class ParticipantConfig
public ParticipantConfig(
String name,
String destinationName,
+ boolean isTopic,
long numberOfMessages,
int batchSize,
long maximumDuration)
{
_name = name;
_destinationName = destinationName;
+ _isTopic = isTopic;
_numberOfMessages = numberOfMessages;
_batchSize = batchSize;
_maximumDuration = maximumDuration;
@@ -66,6 +69,7 @@ public abstract class ParticipantConfig
{
createParticipantCommand.setParticipantName(_name);
createParticipantCommand.setDestinationName(_destinationName);
+ createParticipantCommand.setTopic(_isTopic);
createParticipantCommand.setNumberOfMessages(_numberOfMessages);
createParticipantCommand.setBatchSize(_batchSize);
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java
index f2369ed671..88c188d3ac 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java
@@ -59,7 +59,7 @@ public class ProducerConfig extends ParticipantConfig
long startDelay,
String messageProviderName)
{
- super(producerName, destinationName, numberOfMessages, batchSize, maximumDuration);
+ super(producerName, destinationName, false, numberOfMessages, batchSize, maximumDuration);
_deliveryMode = deliveryMode;
_messageSize = messageSize;
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/db/ResultsDbWriter.java b/java/perftests/src/main/java/org/apache/qpid/disttest/db/ResultsDbWriter.java
new file mode 100644
index 0000000000..fdea03ae5e
--- /dev/null
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/db/ResultsDbWriter.java
@@ -0,0 +1,467 @@
+/*
+ * 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.disttest.db;
+
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ACKNOWLEDGE_MODE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.AVERAGE_LATENCY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.BATCH_SIZE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.CONFIGURED_CLIENT_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.DELIVERY_MODE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ERROR_MESSAGE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_BROWSING_SUBSCRIPTION;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_DURABLE_SUBSCRIPTION;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_NO_LOCAL;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_SELECTOR;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_SYNCHRONOUS_CONSUMER;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_TOPIC;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ITERATION_NUMBER;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.LATENCY_STANDARD_DEVIATION;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MAXIMUM_DURATION;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MAX_LATENCY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MIN_LATENCY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PARTICIPANT_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PRIORITY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PRODUCER_INTERVAL;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PRODUCER_START_DELAY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TEST_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.THROUGHPUT;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TIME_TAKEN;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TIME_TO_LIVE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_NUMBER_OF_CONSUMERS;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_NUMBER_OF_PRODUCERS;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_PAYLOAD_PROCESSED;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.TimeZone;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.results.aggregation.ITestResult;
+
+/**
+ * Intended call sequence:
+ * <ul>
+ * <li>{@link #ResultsDbWriter(Context, String)}</li>
+ * <li>{@link #createResultsTableIfNecessary()}</li>
+ * <li>{@link #writeResults(ResultsForAllTests)} (usually multiple times)</li>
+ * </ul>
+ */
+public class ResultsDbWriter
+{
+ private static final Logger _logger = Logger.getLogger(ResultsDbWriter.class);
+
+ private static final String RESULTS_TABLE_NAME = "RESULTS";
+
+ /** column name */
+ static final String INSERTED_TIMESTAMP = "insertedTimestamp";
+ /** column name */
+ static final String RUN_ID = "runId";
+
+ private static final String TABLE_EXISTENCE_QUERY = "SELECT 1 FROM SYS.SYSTABLES WHERE TABLENAME = ?";
+
+ private static final String CREATE_RESULTS_TABLE = String.format(
+ "CREATE TABLE %1$s (" +
+ "%2$s varchar(200) not null" + // TEST_NAME
+ ", %3$s bigint not null" + // ITERATION_NUMBER
+ ", %4$s varchar(200) not null" + // PARTICIPANT_NAME
+ ", %5$s double not null" + // THROUGHPUT
+ ", %6$s double" + // AVERAGE_LATENCY
+ ", %7$s varchar(200)" + // CONFIGURED_CLIENT_NAME
+ ", %8$s bigint" + // NUMBER_OF_MESSAGES_PROCESSED
+ ", %9$s bigint" + // PAYLOAD_SIZE
+ ", %10$s bigint" + // PRIORITY
+ ", %11$s bigint" + // TIME_TO_LIVE
+ ", %12$s bigint" + // ACKNOWLEDGE_MODE
+ ", %13$s bigint" + // DELIVERY_MODE
+ ", %14$s bigint" + // BATCH_SIZE
+ ", %15$s bigint" + // MAXIMUM_DURATION
+ ", %16$s bigint" + // PRODUCER_START_DELAY
+ ", %17$s bigint" + // PRODUCER_INTERVAL
+ ", %18$s bigint" + // IS_TOPIC
+ ", %19$s bigint" + // IS_DURABLE_SUBSCRIPTION
+ ", %20$s bigint" + // IS_BROWSING_SUBSCRIPTION
+ ", %21$s bigint" + // IS_SELECTOR
+ ", %22$s bigint" + // IS_NO_LOCAL
+ ", %23$s bigint" + // IS_SYNCHRONOUS_CONSUMER
+ ", %24$s bigint" + // TOTAL_NUMBER_OF_CONSUMERS
+ ", %25$s bigint" + // TOTAL_NUMBER_OF_PRODUCERS
+ ", %26$s bigint" + // TOTAL_PAYLOAD_PROCESSED
+ ", %27$s bigint" + // TIME_TAKEN
+ ", %28$s varchar(2000)" + // ERROR_MESSAGE
+ ", %29$s bigint" + // MIN_LATENCY
+ ", %30$s bigint" + // MAX_LATENCY
+ ", %31$s double" + // LATENCY_STANDARD_DEVIATION
+ ", %32$s varchar(200) not null" +
+ ", %33$s timestamp not null" +
+ ")",
+ RESULTS_TABLE_NAME,
+ TEST_NAME.getDisplayName(),
+ ITERATION_NUMBER.getDisplayName(),
+ PARTICIPANT_NAME.getDisplayName(),
+ THROUGHPUT.getDisplayName(),
+ AVERAGE_LATENCY.getDisplayName(),
+ CONFIGURED_CLIENT_NAME.getDisplayName(),
+ NUMBER_OF_MESSAGES_PROCESSED.getDisplayName(),
+ PAYLOAD_SIZE.getDisplayName(),
+ PRIORITY.getDisplayName(),
+ TIME_TO_LIVE.getDisplayName(),
+ ACKNOWLEDGE_MODE.getDisplayName(),
+ DELIVERY_MODE.getDisplayName(),
+ BATCH_SIZE.getDisplayName(),
+ MAXIMUM_DURATION.getDisplayName(),
+ PRODUCER_START_DELAY.getDisplayName(),
+ PRODUCER_INTERVAL.getDisplayName(),
+ IS_TOPIC.getDisplayName(),
+ IS_DURABLE_SUBSCRIPTION.getDisplayName(),
+ IS_BROWSING_SUBSCRIPTION.getDisplayName(),
+ IS_SELECTOR.getDisplayName(),
+ IS_NO_LOCAL.getDisplayName(),
+ IS_SYNCHRONOUS_CONSUMER.getDisplayName(),
+ TOTAL_NUMBER_OF_CONSUMERS.getDisplayName(),
+ TOTAL_NUMBER_OF_PRODUCERS.getDisplayName(),
+ TOTAL_PAYLOAD_PROCESSED.getDisplayName(),
+ TIME_TAKEN.getDisplayName(),
+ ERROR_MESSAGE.getDisplayName(),
+ MIN_LATENCY.getDisplayName(),
+ MAX_LATENCY.getDisplayName(),
+ LATENCY_STANDARD_DEVIATION.getDisplayName(),
+ RUN_ID,
+ INSERTED_TIMESTAMP
+ );
+
+ public static final String DRIVER_NAME = "jdbcDriverClass";
+ public static final String URL = "jdbcUrl";
+
+ private final String _url;
+ private final String _runId;
+
+ private final Clock _clock;
+
+ /**
+ * @param runId may be null, in which case a default value is chosen based on current GMT time
+ * @param context must contain environment entries {@value #DRIVER_NAME} and {@value #URL}.
+ */
+ public ResultsDbWriter(Context context, String runId)
+ {
+ this(context, runId, new Clock());
+ }
+
+ /** only call directly from tests */
+ ResultsDbWriter(Context context, String runId, Clock clock)
+ {
+ _clock = clock;
+ _runId = defaultIfNullRunId(runId);
+
+ _url = initialiseJdbc(context);
+ }
+
+ private String defaultIfNullRunId(String runId)
+ {
+ if(runId == null)
+ {
+ Date dateNow = new Date(_clock.currentTimeMillis());
+ Calendar calNow = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+ calNow.setTime(dateNow);
+ return String.format("run %1$tF %1$tT.%tL", calNow);
+ }
+ else
+ {
+ return runId;
+ }
+ }
+
+ public String getRunId()
+ {
+ return _runId;
+ }
+
+ /**
+ * Uses the context's environment to load the JDBC driver class and return the
+ * JDBC URL specified therein.
+ * @return the JDBC URL
+ */
+ private String initialiseJdbc(Context context)
+ {
+ Hashtable<?, ?> environment = null;
+ try
+ {
+ environment = context.getEnvironment();
+
+ String driverName = (String) environment.get(DRIVER_NAME);
+ if(driverName == null)
+ {
+ throw new IllegalArgumentException("JDBC driver name " + DRIVER_NAME
+ + " missing from context environment: " + environment);
+ }
+
+ Class.forName(driverName);
+
+ Object url = environment.get(URL);
+ if(url == null)
+ {
+ throw new IllegalArgumentException("JDBC URL " + URL + " missing from context environment: " + environment);
+ }
+ return (String) url;
+ }
+ catch (NamingException e)
+ {
+ throw constructorRethrow(e, environment);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw constructorRethrow(e, environment);
+ }
+ }
+
+ private RuntimeException constructorRethrow(Exception e, Hashtable<?, ?> environment)
+ {
+ return new RuntimeException("Couldn't initialise ResultsDbWriter from context with environment" + environment, e);
+ }
+
+ public void createResultsTableIfNecessary()
+ {
+ try
+ {
+ Connection connection = null;
+ try
+ {
+ connection = DriverManager.getConnection(_url);
+ if(!tableExists(RESULTS_TABLE_NAME, connection))
+ {
+ Statement statement = connection.createStatement();
+ try
+ {
+ _logger.info("About to create results table using SQL: " + CREATE_RESULTS_TABLE);
+ statement.execute(CREATE_RESULTS_TABLE);
+ }
+ finally
+ {
+ statement.close();
+ }
+ }
+ }
+ finally
+ {
+ if(connection != null)
+ {
+ connection.close();
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new RuntimeException("Couldn't create results table", e);
+ }
+
+ }
+
+ private boolean tableExists(final String tableName, final Connection conn) throws SQLException
+ {
+ PreparedStatement stmt = conn.prepareStatement(TABLE_EXISTENCE_QUERY);
+ try
+ {
+ stmt.setString(1, tableName);
+ ResultSet rs = stmt.executeQuery();
+ try
+ {
+ return rs.next();
+ }
+ finally
+ {
+ rs.close();
+ }
+ }
+ finally
+ {
+ stmt.close();
+ }
+ }
+
+ public void writeResults(ResultsForAllTests results)
+ {
+ try
+ {
+ writeResultsThrowingException(results);
+ }
+ catch (SQLException e)
+ {
+ throw new RuntimeException("Couldn't write results " + results, e);
+ }
+ _logger.info(this + " wrote " + results.getTestResults().size() + " results to database");
+ }
+
+ private void writeResultsThrowingException(ResultsForAllTests results) throws SQLException
+ {
+ Connection connection = null;
+ try
+ {
+ connection = DriverManager.getConnection(_url);
+
+ for (ITestResult testResult : results.getTestResults())
+ {
+ for (ParticipantResult participantResult : testResult.getParticipantResults())
+ {
+ writeParticipantResult(connection, participantResult);
+ }
+ }
+ }
+ finally
+ {
+ if(connection != null)
+ {
+ connection.close();
+ }
+ }
+ }
+
+ private void writeParticipantResult(Connection connection, ParticipantResult participantResult) throws SQLException
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("About to write to DB the following participant result: " + participantResult);
+ }
+
+ PreparedStatement statement = null;
+ try
+ {
+ String sqlTemplate = String.format(
+ "INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) " +
+ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ RESULTS_TABLE_NAME,
+ TEST_NAME.getDisplayName(),
+ ITERATION_NUMBER.getDisplayName(),
+ PARTICIPANT_NAME.getDisplayName(),
+ THROUGHPUT.getDisplayName(),
+ AVERAGE_LATENCY.getDisplayName(),
+ CONFIGURED_CLIENT_NAME.getDisplayName(),
+ NUMBER_OF_MESSAGES_PROCESSED.getDisplayName(),
+ PAYLOAD_SIZE.getDisplayName(),
+ PRIORITY.getDisplayName(),
+ TIME_TO_LIVE.getDisplayName(),
+ ACKNOWLEDGE_MODE.getDisplayName(),
+ DELIVERY_MODE.getDisplayName(),
+ BATCH_SIZE.getDisplayName(),
+ MAXIMUM_DURATION.getDisplayName(),
+ PRODUCER_START_DELAY.getDisplayName(),
+ PRODUCER_INTERVAL.getDisplayName(),
+ IS_TOPIC.getDisplayName(),
+ IS_DURABLE_SUBSCRIPTION.getDisplayName(),
+ IS_BROWSING_SUBSCRIPTION.getDisplayName(),
+ IS_SELECTOR.getDisplayName(),
+ IS_NO_LOCAL.getDisplayName(),
+ IS_SYNCHRONOUS_CONSUMER.getDisplayName(),
+ TOTAL_NUMBER_OF_CONSUMERS.getDisplayName(),
+ TOTAL_NUMBER_OF_PRODUCERS.getDisplayName(),
+ TOTAL_PAYLOAD_PROCESSED.getDisplayName(),
+ TIME_TAKEN.getDisplayName(),
+ ERROR_MESSAGE.getDisplayName(),
+ MIN_LATENCY.getDisplayName(),
+ MAX_LATENCY.getDisplayName(),
+ LATENCY_STANDARD_DEVIATION.getDisplayName(),
+ RUN_ID,
+ INSERTED_TIMESTAMP
+ );
+ statement = connection.prepareStatement(sqlTemplate);
+
+ int columnIndex = 1;
+ statement.setString(columnIndex++, participantResult.getTestName());
+ statement.setInt(columnIndex++, participantResult.getIterationNumber());
+ statement.setString(columnIndex++, participantResult.getParticipantName());
+ statement.setDouble(columnIndex++, participantResult.getThroughput());
+ statement.setDouble(columnIndex++, participantResult.getAverageLatency());
+ statement.setString(columnIndex++, participantResult.getConfiguredClientName());
+ statement.setLong(columnIndex++, participantResult.getNumberOfMessagesProcessed());
+ statement.setLong(columnIndex++, participantResult.getPayloadSize());
+ statement.setLong(columnIndex++, participantResult.getPriority());
+ statement.setLong(columnIndex++, participantResult.getTimeToLive());
+ statement.setLong(columnIndex++, participantResult.getAcknowledgeMode());
+ statement.setLong(columnIndex++, participantResult.getDeliveryMode());
+ statement.setLong(columnIndex++, participantResult.getBatchSize());
+ statement.setLong(columnIndex++, participantResult.getMaximumDuration());
+ statement.setLong(columnIndex++, 0 /* TODO PRODUCER_START_DELAY*/);
+ statement.setLong(columnIndex++, 0 /* TODO PRODUCER_INTERVAL*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_TOPIC*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_DURABLE_SUBSCRIPTION*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_BROWSING_SUBSCRIPTION*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_SELECTOR*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_NO_LOCAL*/);
+ statement.setLong(columnIndex++, 0 /* TODO IS_SYNCHRONOUS_CONSUMER*/);
+ statement.setLong(columnIndex++, participantResult.getTotalNumberOfConsumers());
+ statement.setLong(columnIndex++, participantResult.getTotalNumberOfProducers());
+ statement.setLong(columnIndex++, participantResult.getTotalPayloadProcessed());
+ statement.setLong(columnIndex++, participantResult.getTimeTaken());
+ statement.setString(columnIndex++, participantResult.getErrorMessage());
+ statement.setLong(columnIndex++, participantResult.getMinLatency());
+ statement.setLong(columnIndex++, participantResult.getMaxLatency());
+ statement.setDouble(columnIndex++, participantResult.getLatencyStandardDeviation());
+
+ statement.setString(columnIndex++, _runId);
+ statement.setTimestamp(columnIndex++, new Timestamp(_clock.currentTimeMillis()));
+
+ statement.execute();
+ connection.commit();
+ }
+ catch(SQLException e)
+ {
+ _logger.error("Couldn't write " + participantResult, e);
+ }
+ finally
+ {
+ if (statement != null)
+ {
+ statement.close();
+ }
+ }
+ }
+
+ public static class Clock
+ {
+ public long currentTimeMillis()
+ {
+ return System.currentTimeMillis();
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("runId", _runId)
+ .append("url", _url)
+ .toString();
+ }
+}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java
index 3f8afc9a9a..f242111dc5 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java
@@ -218,7 +218,15 @@ public class ClientJmsDelegate
synchronized(session)
{
- final Destination destination = session.createQueue(command.getDestinationName());
+ final Destination destination;
+ if(command.isTopic())
+ {
+ destination = session.createTopic(command.getDestinationName());
+ }
+ else
+ {
+ destination = session.createQueue(command.getDestinationName());
+ }
final MessageProducer jmsProducer = session.createProducer(destination);
@@ -373,30 +381,6 @@ public class ClientJmsDelegate
}
}
- public void commitOrAcknowledgeMessage(final Message message, final String sessionName)
- {
- try
- {
- final Session session = _testSessions.get(sessionName);
- if (session.getTransacted())
- {
- synchronized(session)
- {
- session.commit();
- }
- }
- else if (message != null && session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
- {
- message.acknowledge();
- }
- }
- catch (final JMSException jmse)
- {
- throw new DistributedTestException("Unable to commit or acknowledge message on session: " +
- sessionName, jmse);
- }
- }
-
public int getAcknowledgeMode(final String sessionName)
{
try
@@ -493,31 +477,36 @@ public class ClientJmsDelegate
}
}
- public void rollbackOrRecover(String sessionName)
+ public void commitOrAcknowledgeMessageIfNecessary(final String sessionName, final Message message)
{
try
{
final Session session = _testSessions.get(sessionName);
- synchronized(session)
+ if (session.getTransacted())
{
- if (session.getTransacted())
- {
- session.rollback();
- }
- else if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ synchronized(session)
{
- session.recover();
+ session.commit();
}
}
+ else if (message != null && session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ {
+ message.acknowledge();
+ }
}
catch (final JMSException jmse)
{
- throw new DistributedTestException("Unable to rollback or recover on session: " +
+ throw new DistributedTestException("Unable to commit or acknowledge message on session: " +
sessionName, jmse);
}
}
- public void releaseMessage(String sessionName)
+ public void commitIfNecessary(final String sessionName)
+ {
+ commitOrAcknowledgeMessageIfNecessary(sessionName, null);
+ }
+
+ public void rollbackOrRecoverIfNecessary(String sessionName)
{
try
{
@@ -528,7 +517,7 @@ public class ClientJmsDelegate
{
session.rollback();
}
- else
+ else if (session.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
{
session.recover();
}
@@ -536,7 +525,8 @@ public class ClientJmsDelegate
}
catch (final JMSException jmse)
{
- LOGGER.warn("Unable to rollback or recover on session: " + sessionName, jmse);
+ throw new DistributedTestException("Unable to rollback or recover on session: " +
+ sessionName, jmse);
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java
index c80e641e5c..782f7ae2fd 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java
@@ -224,12 +224,12 @@ public class ControllerJmsDelegate
public void createQueues(List<QueueConfig> queues)
{
- _queueCreator.createQueues(_session, queues);
+ _queueCreator.createQueues(_connection, _session, queues);
}
public void deleteQueues(List<QueueConfig> queues)
{
- _queueCreator.deleteQueues(_session, queues);
+ _queueCreator.deleteQueues(_connection, _session, queues);
}
public void addCommandListener(CommandListener commandListener)
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/NoOpQueueCreator.java b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/NoOpQueueCreator.java
index 4d4850eccf..d7e0007b28 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/NoOpQueueCreator.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/NoOpQueueCreator.java
@@ -20,18 +20,19 @@ package org.apache.qpid.disttest.jms;
import java.util.List;
+import javax.jms.Connection;
import javax.jms.Session;
import org.apache.qpid.disttest.controller.config.QueueConfig;
public class NoOpQueueCreator implements QueueCreator
{
@Override
- public void createQueues(Session session, List<QueueConfig> configs)
+ public void createQueues(Connection connection, Session session, List<QueueConfig> configs)
{
}
@Override
- public void deleteQueues(Session session, List<QueueConfig> configs)
+ public void deleteQueues(Connection connection, Session session, List<QueueConfig> configs)
{
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java
index 6874abe7d4..ef2cfb6cd4 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java
@@ -20,21 +20,29 @@ package org.apache.qpid.disttest.jms;
import java.util.List;
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
import javax.jms.Session;
+
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.controller.config.QueueConfig;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class QpidQueueCreator implements QueueCreator
{
private static final Logger LOGGER = LoggerFactory.getLogger(QpidQueueCreator.class);
private static final FieldTable EMPTY_QUEUE_BIND_ARGUMENTS = new FieldTable();
+ private static final String QUEUE_CREATOR_DRAIN_POLL_TIMEOUT = "qpid.disttest.queue.creator.drainPollTime";
+ private static int _drainPollTimeout = Integer.getInteger(QUEUE_CREATOR_DRAIN_POLL_TIMEOUT, 500);
@Override
- public void createQueues(Session session, List<QueueConfig> configs)
+ public void createQueues(Connection connection, Session session, List<QueueConfig> configs)
{
AMQSession<?, ?> amqSession = (AMQSession<?, ?>)session;
for (QueueConfig queueConfig : configs)
@@ -44,12 +52,88 @@ public class QpidQueueCreator implements QueueCreator
}
@Override
- public void deleteQueues(Session session, List<QueueConfig> configs)
+ public void deleteQueues(Connection connection, Session session, List<QueueConfig> configs)
{
AMQSession<?, ?> amqSession = (AMQSession<?, ?>)session;
for (QueueConfig queueConfig : configs)
{
- deleteQueue(amqSession, queueConfig);
+ AMQDestination destination = createAMQDestination(amqSession, queueConfig);
+
+ // drainQueue method is added because deletion of queue with a lot
+ // of messages takes time and might cause the timeout exception
+ drainQueue(connection, destination);
+
+ deleteQueue(amqSession, destination.getAMQQueueName());
+ }
+ }
+
+ private AMQDestination createAMQDestination(AMQSession<?, ?> amqSession, QueueConfig queueConfig)
+ {
+ try
+ {
+ return (AMQDestination) amqSession.createQueue(queueConfig.getName());
+ }
+ catch (Exception e)
+ {
+ throw new DistributedTestException("Failed to create amq destionation object:" + queueConfig, e);
+ }
+ }
+
+ private long getQueueDepth(AMQSession<?, ?> amqSession, AMQDestination destination)
+ {
+ try
+ {
+ long queueDepth = amqSession.getQueueDepth(destination);
+ return queueDepth;
+ }
+ catch (Exception e)
+ {
+ throw new DistributedTestException("Failed to query queue depth:" + destination, e);
+ }
+ }
+
+ private void drainQueue(Connection connection, AMQDestination destination)
+ {
+ Session noAckSession = null;
+ try
+ {
+ LOGGER.debug("About to drain the queue {}", destination.getQueueName());
+ noAckSession = connection.createSession(false, org.apache.qpid.jms.Session.NO_ACKNOWLEDGE);
+ MessageConsumer messageConsumer = noAckSession.createConsumer(destination);
+
+ long currentQueueDepth = getQueueDepth((AMQSession<?,?>)noAckSession, destination);
+ int counter = 0;
+ while (currentQueueDepth > 0)
+ {
+ LOGGER.info("Queue {} has {} message(s)", destination.getQueueName(), currentQueueDepth);
+
+ while(messageConsumer.receive(_drainPollTimeout) != null)
+ {
+ counter++;
+ }
+
+ currentQueueDepth = getQueueDepth((AMQSession<?,?>)noAckSession, destination);
+ }
+ LOGGER.info("Drained {} message(s) from queue {} ", counter, destination.getQueueName());
+ messageConsumer.close();
+ }
+ catch (Exception e)
+ {
+ throw new DistributedTestException("Failed to drain queue:" + destination, e);
+ }
+ finally
+ {
+ if (noAckSession != null)
+ {
+ try
+ {
+ noAckSession.close();
+ }
+ catch (JMSException e)
+ {
+ throw new DistributedTestException("Failed to close n/a session:" + noAckSession, e);
+ }
+ }
}
}
@@ -66,7 +150,7 @@ public class QpidQueueCreator implements QueueCreator
EMPTY_QUEUE_BIND_ARGUMENTS, destination.getExchangeName(),
destination, autoDelete);
- LOGGER.debug("Created queue " + queueConfig);
+ LOGGER.debug("Created queue {}", queueConfig);
}
catch (Exception e)
{
@@ -74,20 +158,19 @@ public class QpidQueueCreator implements QueueCreator
}
}
- private void deleteQueue(AMQSession<?, ?> session, QueueConfig queueConfig)
+ private void deleteQueue(AMQSession<?, ?> session, AMQShortString queueName)
{
try
{
// The Qpid AMQSession API currently makes the #deleteQueue method protected and the
// raw protocol method public. This should be changed then we should switch the below to
// use #deleteQueue.
- AMQDestination destination = (AMQDestination) session.createQueue(queueConfig.getName());
- session.sendQueueDelete(destination.getAMQQueueName());
- LOGGER.debug("Deleted queue " + queueConfig.getName());
+ session.sendQueueDelete(queueName);
+ LOGGER.debug("Deleted queue {}", queueName);
}
catch (Exception e)
{
- throw new DistributedTestException("Failed to delete queue:" + queueConfig.getName(), e);
+ throw new DistributedTestException("Failed to delete queue:" + queueName, e);
}
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java
index 0947dd53cb..a37cd7888c 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java
@@ -20,12 +20,13 @@ package org.apache.qpid.disttest.jms;
import java.util.List;
+import javax.jms.Connection;
import javax.jms.Session;
import org.apache.qpid.disttest.controller.config.QueueConfig;
public interface QueueCreator
{
- public void createQueues(final Session session, final List<QueueConfig> configs);
- public void deleteQueues(final Session session, final List<QueueConfig> configs);
+ void createQueues(Connection connection, Session session, List<QueueConfig> configs);
+ void deleteQueues(Connection connection, Session session, List<QueueConfig> configs);
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java
index ad9aa31472..e78f6965d2 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java
@@ -134,6 +134,7 @@ public class ConsumerParticipantResult extends ParticipantResult
_messageLatencies = messageLatencies;
}
+ @Override
@OutputAttribute(attribute=ParticipantAttribute.MIN_LATENCY)
public long getMinLatency()
{
@@ -145,6 +146,7 @@ public class ConsumerParticipantResult extends ParticipantResult
_minLatency = minLatency;
}
+ @Override
@OutputAttribute(attribute=ParticipantAttribute.MAX_LATENCY)
public long getMaxLatency()
{
@@ -156,6 +158,7 @@ public class ConsumerParticipantResult extends ParticipantResult
_maxLatency = maxLatency;
}
+ @Override
@OutputAttribute(attribute=ParticipantAttribute.AVERAGE_LATENCY)
public double getAverageLatency()
{
@@ -167,6 +170,7 @@ public class ConsumerParticipantResult extends ParticipantResult
_averageLatency = averageLatency;
}
+ @Override
@OutputAttribute(attribute=ParticipantAttribute.LATENCY_STANDARD_DEVIATION)
public double getLatencyStandardDeviation()
{
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java
index 68c21fbf83..07a60504c8 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java
@@ -21,7 +21,6 @@ package org.apache.qpid.disttest.message;
public class CreateConsumerCommand extends CreateParticpantCommand
{
- private boolean _isTopic;
private boolean _isDurableSubscription;
private boolean _isBrowsingSubscription;
private String _selector;
@@ -75,16 +74,6 @@ public class CreateConsumerCommand extends CreateParticpantCommand
this._noLocal = noLocal;
}
- public boolean isTopic()
- {
- return _isTopic;
- }
-
- public void setTopic(boolean isTopic)
- {
- this._isTopic = isTopic;
- }
-
public boolean isSynchronous()
{
return _synchronous;
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java
index b1caa6ef75..e7349bf795 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java
@@ -23,6 +23,7 @@ import org.apache.commons.lang.builder.ToStringBuilder;
public abstract class CreateParticpantCommand extends Command
{
+ private boolean _isTopic;
private String _participantName;
private String _sessionName;
private String _destinationName;
@@ -65,6 +66,16 @@ public abstract class CreateParticpantCommand extends Command
_destinationName = destinationName;
}
+ public boolean isTopic()
+ {
+ return _isTopic;
+ }
+
+ public void setTopic(boolean isTopic)
+ {
+ _isTopic = isTopic;
+ }
+
public long getNumberOfMessages()
{
return _numberOfMessages;
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java
index 0418562a2d..1154ff306c 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java
@@ -18,6 +18,8 @@
*/
package org.apache.qpid.disttest.message;
+import java.text.DecimalFormat;
+
import org.apache.qpid.disttest.client.Participant;
/**
@@ -31,6 +33,8 @@ public enum ParticipantAttribute
{
TEST_NAME("testName"),
ITERATION_NUMBER("iterationNumber"),
+ THROUGHPUT("throughputKbPerS", "#"),
+ AVERAGE_LATENCY("averageLatency", "#"),
CONFIGURED_CLIENT_NAME("clientName"),
PARTICIPANT_NAME("participantName"),
NUMBER_OF_MESSAGES_PROCESSED("numberOfMessages"),
@@ -52,24 +56,56 @@ public enum ParticipantAttribute
TOTAL_NUMBER_OF_CONSUMERS("totalNumberOfConsumers"),
TOTAL_NUMBER_OF_PRODUCERS("totalNumberOfProducers"),
TOTAL_PAYLOAD_PROCESSED("totalPayloadProcessedB"),
- THROUGHPUT("throughputKbPerS"),
TIME_TAKEN("timeTakenMs"),
ERROR_MESSAGE("errorMessage"),
MIN_LATENCY("minLatency"),
MAX_LATENCY("maxLatency"),
- AVERAGE_LATENCY("averageLatency"),
- LATENCY_STANDARD_DEVIATION("latencyStandardDeviation")
+ LATENCY_STANDARD_DEVIATION("latencyStandardDeviation"),
+ MESSAGE_THROUGHPUT("throughputMessagesPerS")
;
private String _displayName;
+ private String _decimalFormat;
ParticipantAttribute(String displayName)
{
_displayName = displayName;
}
+ ParticipantAttribute(String displayName, String decimalFormat)
+ {
+ _displayName = displayName;
+ _decimalFormat = decimalFormat;
+ }
+
+ public String getDecimalFormat()
+ {
+ return _decimalFormat;
+ }
+
public String getDisplayName()
{
return _displayName;
}
+
+ public String format(Object attributeValue)
+ {
+ if(attributeValue == null)
+ {
+ return null;
+ }
+
+ String attributeAsString = String.valueOf(attributeValue);
+
+ if(_decimalFormat != null)
+ {
+ DecimalFormat decimalFormat = new DecimalFormat(_decimalFormat);
+ double attributeAsDoule = Double.valueOf(attributeAsString);
+ return decimalFormat.format(attributeAsDoule);
+ }
+ else
+ {
+ return attributeAsString;
+ }
+ }
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java
index a6d3d91bae..0a824a316b 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java
@@ -22,11 +22,12 @@ import static org.apache.qpid.disttest.message.ParticipantAttribute.BATCH_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.CONFIGURED_CLIENT_NAME;
import static org.apache.qpid.disttest.message.ParticipantAttribute.ITERATION_NUMBER;
import static org.apache.qpid.disttest.message.ParticipantAttribute.MAXIMUM_DURATION;
-import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MESSAGE_THROUGHPUT;
import static org.apache.qpid.disttest.message.ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED;
-import static org.apache.qpid.disttest.message.ParticipantAttribute.THROUGHPUT;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PARTICIPANT_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.TEST_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.THROUGHPUT;
import java.util.Comparator;
import java.util.Date;
@@ -49,6 +50,7 @@ public class ParticipantResult extends Response
private long _totalPayloadProcessed;
private int _payloadSize;
private double _throughput;
+ private int _messageThroughput;
private int _totalNumberOfConsumers;
private int _totalNumberOfProducers;
@@ -236,6 +238,17 @@ public class ParticipantResult extends Response
_throughput = throughput;
}
+ @OutputAttribute(attribute=MESSAGE_THROUGHPUT)
+ public int getMessageThroughput()
+ {
+ return _messageThroughput;
+ }
+
+ public void setMessageThroughput(int throughput)
+ {
+ _messageThroughput = throughput;
+ }
+
public void setTotalNumberOfConsumers(int totalNumberOfConsumers)
{
_totalNumberOfConsumers = totalNumberOfConsumers;
@@ -269,4 +282,41 @@ public class ParticipantResult extends Response
_acknowledgeMode = acknowledgeMode;
}
+ public double getLatencyStandardDeviation()
+ {
+ return 0.0;
+ }
+
+ @OutputAttribute(attribute = ParticipantAttribute.MIN_LATENCY)
+ public long getMinLatency()
+ {
+ return 0;
+ }
+
+ @OutputAttribute(attribute = ParticipantAttribute.MAX_LATENCY)
+ public long getMaxLatency()
+ {
+ return 0;
+ }
+
+ @OutputAttribute(attribute = ParticipantAttribute.AVERAGE_LATENCY)
+ public double getAverageLatency()
+ {
+ return 0;
+ }
+
+ public int getPriority()
+ {
+ return 0;
+ }
+
+ public long getTimeToLive()
+ {
+ return 0;
+ }
+
+ public int getDeliveryMode()
+ {
+ return 0;
+ }
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java
index 766c90eec8..2d9399a3d3 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java
@@ -42,6 +42,7 @@ public class ProducerParticipantResult extends ParticipantResult
setParticipantName(participantName);
}
+ @Override
@OutputAttribute(attribute=PRIORITY)
public int getPriority()
{
@@ -53,6 +54,7 @@ public class ProducerParticipantResult extends ParticipantResult
_priority = priority;
}
+ @Override
@OutputAttribute(attribute=TIME_TO_LIVE)
public long getTimeToLive()
{
@@ -86,6 +88,7 @@ public class ProducerParticipantResult extends ParticipantResult
_interval = producerInterval;
}
+ @Override
@OutputAttribute(attribute=DELIVERY_MODE)
public int getDeliveryMode()
{
@@ -96,5 +99,4 @@ public class ProducerParticipantResult extends ParticipantResult
{
this._deliveryMode = deliveryMode;
}
-
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java
index 3f9cdff69d..6230067486 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java
@@ -22,10 +22,8 @@ import java.util.List;
import org.apache.qpid.disttest.message.ParticipantResult;
-// TODO rename me!!
public interface ITestResult
{
-
// TODO should weaken to Collection
List<ParticipantResult> getParticipantResults();
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java
index 4dcabe6c7b..c21a78d359 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java
@@ -142,6 +142,7 @@ public class ParticipantResultAggregator
aggregatedResult.setStartDate(new Date(_minStartDate));
aggregatedResult.setEndDate(new Date(_maxEndDate));
aggregatedResult.setThroughput(calculateThroughputInKiloBytesPerSecond());
+ aggregatedResult.setMessageThroughput(calculateThroughputInMessagesPerSecond());
}
private void setRolledUpConstantAttributes(ParticipantResult aggregatedResult)
@@ -197,4 +198,14 @@ public class ParticipantResultAggregator
return totalPayloadProcessedInKiloBytes/durationInSeconds;
}
+ private int calculateThroughputInMessagesPerSecond()
+ {
+ double durationInMillis = _maxEndDate - _minStartDate;
+ if (durationInMillis == 0 )
+ {
+ return 0;
+ }
+
+ return (int)Math.round((_numberOfMessagesProcessed * 1000.0d)/durationInMillis);
+ }
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java
index 5934e0e997..954828b043 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java
@@ -18,6 +18,9 @@
*/
package org.apache.qpid.disttest.results.aggregation;
+import java.util.List;
+
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.ProducerParticipantResult;
@@ -102,5 +105,26 @@ public class TestResultAggregator
aggregatedAllResult.setNumberOfMessagesProcessed(aggregatedConsumerResult.getNumberOfMessagesProcessed());
aggregatedAllResult.setTotalPayloadProcessed(aggregatedConsumerResult.getTotalPayloadProcessed());
aggregatedAllResult.setThroughput(aggregatedConsumerResult.getThroughput());
+ aggregatedAllResult.setMessageThroughput(aggregatedConsumerResult.getMessageThroughput());
+ }
+
+ /**
+ * Produces a single {@link ResultsForAllTests} from the supplied list, only containing
+ * the "All participants" results.
+ */
+ public ResultsForAllTests aggregateTestResults(List<ResultsForAllTests> allResultsList)
+ {
+ ResultsForAllTests retVal = new ResultsForAllTests();
+
+ for (ResultsForAllTests resultsForAllTests : allResultsList)
+ {
+ ResultsForAllTests allParticipantsResult = resultsForAllTests.getAllParticipantsResult();
+ for (ITestResult testResult : allParticipantsResult.getTestResults())
+ {
+ retVal.add(testResult);
+ }
+ }
+
+ return retVal;
}
}
diff --git a/java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormater.java b/java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormatter.java
index 52e53ca624..ea7a3f78c7 100644
--- a/java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormater.java
+++ b/java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormatter.java
@@ -32,7 +32,7 @@ import org.apache.qpid.disttest.results.aggregation.ITestResult;
/**
* produces CSV output using the ordered enums in {@link ParticipantAttribute}
*/
-public class CSVFormater
+public class CSVFormatter
{
public String format(ResultsForAllTests results)
{
@@ -66,7 +66,9 @@ public class CSVFormater
List<Object> attributeValues = new ArrayList<Object>();
for (ParticipantAttribute attribute : ParticipantAttribute.values())
{
- attributeValues.add(attributeValueMap.get(attribute));
+ Object attributeValue = attributeValueMap.get(attribute);
+ String attributeValueFormatted = attribute.format(attributeValue);
+ attributeValues.add(attributeValueFormatted);
}
String row = StringUtils.join(attributeValues.toArray(), ",");
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelperTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelperTest.java
index a10b3b359e..629442d86c 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelperTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelperTest.java
@@ -39,14 +39,6 @@ public class ConfigFileHelperTest extends QpidTestCase
_testDir = TestFileUtils.createTestDirectory();
}
- public void testGenerateOutputCsvNameFrom()
- {
- String outputDir = "/tmp/outputDir";
-
- assertEquals("/tmp/outputDir/my.json.file.csv", _configFileHelper.generateOutputCsvNameFrom("/tmp/my.json.file.json", outputDir));
- assertEquals("/tmp/outputDir/my.js.file.csv", _configFileHelper.generateOutputCsvNameFrom("/tmp/my.js.file.js", outputDir));
- }
-
public void testGetTestConfigFilesForDirectory() throws Exception
{
String jsFile = createFile("file1.js");
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/ResultsFileWriterTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/ResultsFileWriterTest.java
new file mode 100644
index 0000000000..ab55e8003d
--- /dev/null
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/ResultsFileWriterTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.disttest;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.Arrays;
+
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.disttest.results.aggregation.TestResultAggregator;
+import org.apache.qpid.disttest.results.formatting.CSVFormatter;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
+
+public class ResultsFileWriterTest extends QpidTestCase
+{
+ private CSVFormatter _csvFormater = mock(CSVFormatter.class);
+ private TestResultAggregator _testResultAggregator = mock(TestResultAggregator.class);
+
+ private File _outputDir = TestFileUtils.createTestDirectory();
+
+ private ResultsFileWriter _resultsFileWriter = new ResultsFileWriter(_outputDir);
+
+ @Override
+ public void setUp()
+ {
+ _resultsFileWriter.setCsvFormater(_csvFormater);
+ _resultsFileWriter.setTestResultAggregator(_testResultAggregator);
+ }
+
+ public void testWriteResultsToFile()
+ {
+ ResultsForAllTests resultsForAllTests = mock(ResultsForAllTests.class);
+
+ String expectedCsvContents = "expected-csv-contents";
+ when(_csvFormater.format(resultsForAllTests)).thenReturn(expectedCsvContents);
+
+ _resultsFileWriter.writeResultsToFile(resultsForAllTests, "config.json");
+
+ File resultsFile = new File(_outputDir, "config.csv");
+
+ assertEquals(expectedCsvContents, FileUtils.readFileAsString(resultsFile));
+ }
+
+ public void testWriteResultsSummary()
+ {
+ ResultsForAllTests results1 = mock(ResultsForAllTests.class);
+ ResultsForAllTests results2 = mock(ResultsForAllTests.class);
+ ResultsForAllTests summaryResults = mock(ResultsForAllTests.class);
+
+ when(_testResultAggregator.aggregateTestResults(Arrays.asList(results1, results2)))
+ .thenReturn(summaryResults);
+
+ String expectedSummaryFileContents = "expected-summary-file";
+
+ when(_csvFormater.format(summaryResults))
+ .thenReturn(expectedSummaryFileContents);
+
+ _resultsFileWriter.writeResultsSummary(Arrays.asList(results1, results2));
+
+ File summaryFile = new File(_outputDir, ResultsFileWriter.TEST_SUMMARY_FILE_NAME);
+
+ assertEquals(expectedSummaryFileContents, FileUtils.readFileAsString(summaryFile));
+ }
+
+}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java
index 320e7d8c9d..09f7da4efb 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java
@@ -19,12 +19,11 @@
*/
package org.apache.qpid.disttest;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.Command;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class VisitorTest extends TestCase
+public class VisitorTest extends QpidTestCase
{
public void testStringVisited() throws Exception
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java
index 4a82f6719f..2b29471558 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java
@@ -21,7 +21,6 @@ package org.apache.qpid.disttest.client;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import junit.framework.TestCase;
import org.apache.qpid.disttest.jms.ClientJmsDelegate;
import org.apache.qpid.disttest.message.CreateConnectionCommand;
@@ -32,8 +31,9 @@ import org.apache.qpid.disttest.message.CreateSessionCommand;
import org.apache.qpid.disttest.message.StartTestCommand;
import org.apache.qpid.disttest.message.StopClientCommand;
import org.apache.qpid.disttest.message.TearDownTestCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ClientCommandVisitorTest extends TestCase
+public class ClientCommandVisitorTest extends QpidTestCase
{
private Client _client;
private ClientCommandVisitor _visitor;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java
index dd50766918..8139961fa4 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java
@@ -29,17 +29,16 @@ import java.util.Collections;
import java.util.Timer;
import java.util.TimerTask;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.jms.ClientJmsDelegate;
import org.apache.qpid.disttest.message.Command;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.Response;
import org.apache.qpid.disttest.message.StopClientCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.InOrder;
import org.mockito.Mockito;
-public class ClientTest extends TestCase
+public class ClientTest extends QpidTestCase
{
private Client _client;
private ClientJmsDelegate _delegate;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java
index 58589d36f4..f75415a2bf 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java
@@ -34,16 +34,15 @@ import java.util.Collection;
import javax.jms.Message;
import javax.jms.Session;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.jms.ClientJmsDelegate;
import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.CreateConsumerCommand;
import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.InOrder;
-public class ConsumerParticipantTest extends TestCase
+public class ConsumerParticipantTest extends QpidTestCase
{
private static final String SESSION_NAME1 = "SESSION1";
private static final String PARTICIPANT_NAME1 = "PARTICIPANT_NAME1";
@@ -114,7 +113,7 @@ public class ConsumerParticipantTest extends TestCase
_inOrder.verify(_delegate).consumeMessage(PARTICIPANT_NAME1, RECEIVE_TIMEOUT);
_inOrder.verify(_delegate).calculatePayloadSizeFrom(_mockMessage);
- _inOrder.verify(_delegate).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ _inOrder.verify(_delegate).commitOrAcknowledgeMessageIfNecessary(SESSION_NAME1, _mockMessage);
}
public void testReceiveMessagesForDurationSynch() throws Exception
@@ -129,7 +128,7 @@ public class ConsumerParticipantTest extends TestCase
verify(_delegate, atLeastOnce()).consumeMessage(PARTICIPANT_NAME1, RECEIVE_TIMEOUT);
verify(_delegate, atLeastOnce()).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, atLeastOnce()).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, atLeastOnce()).commitOrAcknowledgeMessageIfNecessary(SESSION_NAME1, _mockMessage);
}
public void testReceiveMessagesBatchedSynch() throws Exception
@@ -147,7 +146,7 @@ public class ConsumerParticipantTest extends TestCase
verify(_delegate, times(numberOfMessages)).consumeMessage(PARTICIPANT_NAME1, RECEIVE_TIMEOUT);
verify(_delegate, times(numberOfMessages)).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, times(4)).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, times(4)).commitOrAcknowledgeMessageIfNecessary(SESSION_NAME1, _mockMessage);
}
public void testReceiveMessagesWithVaryingPayloadSize() throws Exception
@@ -171,7 +170,7 @@ public class ConsumerParticipantTest extends TestCase
verify(_delegate, times(numberOfMessages)).consumeMessage(PARTICIPANT_NAME1, RECEIVE_TIMEOUT);
verify(_delegate, times(numberOfMessages)).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, times(numberOfMessages)).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, times(numberOfMessages)).commitOrAcknowledgeMessageIfNecessary(SESSION_NAME1, _mockMessage);
}
public void testReleaseResources()
@@ -194,7 +193,7 @@ public class ConsumerParticipantTest extends TestCase
_inOrder.verify(_delegate).consumeMessage(PARTICIPANT_NAME1, RECEIVE_TIMEOUT);
_inOrder.verify(_delegate).calculatePayloadSizeFrom(_mockMessage);
- _inOrder.verify(_delegate).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ _inOrder.verify(_delegate).commitOrAcknowledgeMessageIfNecessary(SESSION_NAME1, _mockMessage);
assertTrue("Unexpected consuemr results", result instanceof ConsumerParticipantResult);
Collection<Long> latencies = ((ConsumerParticipantResult)result).getMessageLatencies();
assertNotNull("Message latency is not cllected", latencies);
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java
index 1ff8d3e5d7..8863e0f289 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java
@@ -33,14 +33,13 @@ import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.client.property.ListPropertyValue;
import org.apache.qpid.disttest.client.property.PropertyValue;
import org.apache.qpid.disttest.client.property.SimplePropertyValue;
import org.apache.qpid.disttest.message.CreateProducerCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class MessageProviderTest extends TestCase
+public class MessageProviderTest extends QpidTestCase
{
private Session _session;
private TextMessage _message;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java
index f30e4664ff..6720047cd1 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java
@@ -20,6 +20,7 @@
package org.apache.qpid.disttest.client;
import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -28,14 +29,13 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.ArgumentMatcher;
import org.mockito.InOrder;
-public class ParticipantExecutorTest extends TestCase
+public class ParticipantExecutorTest extends QpidTestCase
{
private static final ResultHasError HAS_ERROR = new ResultHasError();
private static final String CLIENT_NAME = "CLIENT_NAME";
@@ -69,8 +69,8 @@ public class ParticipantExecutorTest extends TestCase
InOrder inOrder = inOrder(_participant, _client);
inOrder.verify(_participant).doIt(CLIENT_NAME);
- inOrder.verify(_client).sendResults(_mockResult);
inOrder.verify(_participant).releaseResources();
+ inOrder.verify(_client).sendResults(_mockResult);
}
public void testParticipantThrowsException() throws Exception
@@ -82,13 +82,28 @@ public class ParticipantExecutorTest extends TestCase
InOrder inOrder = inOrder(_participant, _client);
inOrder.verify(_participant).doIt(CLIENT_NAME);
+ inOrder.verify(_participant).releaseResources();
inOrder.verify(_client).sendResults(argThat(HAS_ERROR));
+ }
+
+ public void testReleaseResourcesThrowsException() throws Exception
+ {
+ when(_participant.doIt(CLIENT_NAME)).thenReturn(_mockResult);
+ doThrow(DistributedTestException.class).when(_participant).releaseResources();
+
+ _participantExecutor.start(_client);
+
+ InOrder inOrder = inOrder(_participant, _client);
+
+ inOrder.verify(_participant).doIt(CLIENT_NAME);
inOrder.verify(_participant).releaseResources();
+
+ // check that sendResults is called even though releaseResources threw an exception
+ inOrder.verify(_client).sendResults(_mockResult);
}
public void testThreadNameAndDaemonness() throws Exception
{
-
ThreadPropertyReportingParticipant participant = new ThreadPropertyReportingParticipant(PARTICIPANT_NAME);
_participantExecutor = new ParticipantExecutor(participant);
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java
index bd0d5a39c8..5cc8d2f30a 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java
@@ -20,9 +20,10 @@
package org.apache.qpid.disttest.client;
import static org.mockito.Mockito.mock;
-import junit.framework.TestCase;
-public class ParticipantRegistryTest extends TestCase
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class ParticipantRegistryTest extends QpidTestCase
{
private ParticipantExecutorRegistry _participantRegistry = new ParticipantExecutorRegistry();
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java
index 3b21834a5c..9eab459443 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java
@@ -22,16 +22,15 @@ import java.util.Date;
import javax.jms.DeliveryMode;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.CreateConsumerCommand;
import org.apache.qpid.disttest.message.CreateParticpantCommand;
import org.apache.qpid.disttest.message.CreateProducerCommand;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.ProducerParticipantResult;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ParticipantResultFactoryTest extends TestCase
+public class ParticipantResultFactoryTest extends QpidTestCase
{
private static final String PARTICIPANT_NAME = "participantName";
private static final String REGISTERED_CLIENT_NAME = "registeredClientName";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java
index a3ac11b756..08ee8715fd 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java
@@ -31,15 +31,14 @@ import javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.Session;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.jms.ClientJmsDelegate;
import org.apache.qpid.disttest.message.CreateProducerCommand;
import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.InOrder;
-public class ProducerParticipantTest extends TestCase
+public class ProducerParticipantTest extends QpidTestCase
{
private ProducerParticipant _producer;
@@ -127,13 +126,13 @@ public class ProducerParticipantTest extends TestCase
_inOrder.verify(_delegate).sendNextMessage(isA(CreateProducerCommand.class));
_inOrder.verify(_delegate).calculatePayloadSizeFrom(_mockMessage);
- _inOrder.verify(_delegate).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ _inOrder.verify(_delegate).commitIfNecessary(SESSION_NAME1);
}
public void testSendMessagesForDuration() throws Exception
{
- final long duration = 100;
+ final long duration = 1000;
_command.setMaximumDuration(duration);
ParticipantResult result = _producer.doIt(CLIENT_NAME);
@@ -142,7 +141,24 @@ public class ProducerParticipantTest extends TestCase
verify(_delegate, atLeastOnce()).sendNextMessage(isA(CreateProducerCommand.class));
verify(_delegate, atLeastOnce()).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, atLeastOnce()).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, atLeastOnce()).commitIfNecessary(SESSION_NAME1);
+ }
+
+ public void testSendMessagesForDurationWithDelayExceedingDuration() throws Exception
+ {
+ final long duration = 100;
+ _command.setMaximumDuration(duration);
+ _command.setStartDelay(150);
+
+ try
+ {
+ _producer.doIt(CLIENT_NAME);
+ fail("Exception should be thrown indicating configuration error");
+ }
+ catch(DistributedTestException e)
+ {
+ assertEquals("Start delay must be less than maximum test duration", e.getMessage());
+ }
}
public void testSendMessageBatches() throws Exception
@@ -161,7 +177,7 @@ public class ProducerParticipantTest extends TestCase
verify(_delegate, times(numberOfMessages)).sendNextMessage(isA(CreateProducerCommand.class));
verify(_delegate, times(numberOfMessages)).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, times(expectedNumberOfCommits)).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, times(expectedNumberOfCommits)).commitIfNecessary(SESSION_NAME1);
}
public void testSendMessageWithPublishInterval() throws Exception
@@ -183,7 +199,7 @@ public class ProducerParticipantTest extends TestCase
verify(_delegate, times(numberOfMessages)).sendNextMessage(isA(CreateProducerCommand.class));
verify(_delegate, times(numberOfMessages)).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, times(4)).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, times(4)).commitIfNecessary(SESSION_NAME1);
}
public void testSendMessageWithVaryingPayloadSize() throws Exception
@@ -208,7 +224,7 @@ public class ProducerParticipantTest extends TestCase
verify(_delegate, times(numberOfMessages)).sendNextMessage(isA(CreateProducerCommand.class));
verify(_delegate, times(numberOfMessages)).calculatePayloadSizeFrom(_mockMessage);
- verify(_delegate, times(numberOfMessages)).commitOrAcknowledgeMessage(_mockMessage, SESSION_NAME1);
+ verify(_delegate, times(numberOfMessages)).commitIfNecessary(SESSION_NAME1);
}
public void testReleaseResources()
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java
index c54355bc76..3172eb07ed 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java
@@ -21,13 +21,9 @@ package org.apache.qpid.disttest.client.property;
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.disttest.client.property.ListPropertyValue;
-import org.apache.qpid.disttest.client.property.PropertyValue;
-import org.apache.qpid.disttest.client.property.SimplePropertyValue;
-
-public class ListPropertyValueTest extends TestCase
+public class ListPropertyValueTest extends QpidTestCase
{
private ListPropertyValue _generator;
private List<PropertyValue> _items;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java
index 17397db5b8..eba1bcc435 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java
@@ -18,9 +18,9 @@
*/
package org.apache.qpid.disttest.client.property;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class PropertyValueFactoryTest extends TestCase
+public class PropertyValueFactoryTest extends QpidTestCase
{
private PropertyValueFactory _factory;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java
index 878141895c..9651dd95ce 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java
@@ -18,11 +18,9 @@
*/
package org.apache.qpid.disttest.client.property;
-import org.apache.qpid.disttest.client.property.RandomPropertyValue;
+import org.apache.qpid.test.utils.QpidTestCase;
-import junit.framework.TestCase;
-
-public class RandomPropertyValueTest extends TestCase
+public class RandomPropertyValueTest extends QpidTestCase
{
private RandomPropertyValue _generator;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java
index 6932919bed..b0649a49ae 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java
@@ -18,11 +18,9 @@
*/
package org.apache.qpid.disttest.client.property;
-import org.apache.qpid.disttest.client.property.RangePropertyValue;
+import org.apache.qpid.test.utils.QpidTestCase;
-import junit.framework.TestCase;
-
-public class RangePropertyValueTest extends TestCase
+public class RangePropertyValueTest extends QpidTestCase
{
private RangePropertyValue _generator;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java
index a347d866c7..f1977015fe 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java
@@ -18,9 +18,9 @@
*/
package org.apache.qpid.disttest.client.property;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class SimplePropertyValueTest extends TestCase
+public class SimplePropertyValueTest extends QpidTestCase
{
public void testGetValue()
{
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithNoLimitsTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithNoLimitsTest.java
index 37820d2582..0880512333 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithNoLimitsTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithNoLimitsTest.java
@@ -25,9 +25,9 @@ import static org.mockito.Mockito.when;
import java.util.concurrent.Callable;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ExecutorWithNoLimitsTest extends TestCase
+public class ExecutorWithNoLimitsTest extends QpidTestCase
{
private final static Object RESULT = new Object();
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithTimeLimitTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithTimeLimitTest.java
index a201a7bacf..2abdba2446 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithTimeLimitTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/client/utils/ExecutorWithTimeLimitTest.java
@@ -20,16 +20,16 @@
package org.apache.qpid.disttest.client.utils;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.never;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ExecutorWithTimeLimitTest extends TestCase
+public class ExecutorWithTimeLimitTest extends QpidTestCase
{
private static final int TIMEOUT = 500;
private static final Object RESULT = new Object();
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java
index cc969e1ef2..c07d9fcb81 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java
@@ -21,14 +21,15 @@ package org.apache.qpid.disttest.controller;
import java.util.Timer;
import java.util.TimerTask;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ClientRegistryTest extends TestCase
+public class ClientRegistryTest extends QpidTestCase
{
private static final String CLIENT1_REGISTERED_NAME = "CLIENT1_REGISTERED_NAME";
private static final String CLIENT2_REGISTERED_NAME = "CLIENT2_REGISTERED_NAME";
+ private static final String CLIENT3_REGISTERED_NAME = "CLIENT3_REGISTERED_NAME";
+
private static final int AWAIT_DELAY = 100;
private ClientRegistry _clientRegistry = new ClientRegistry();
@@ -70,7 +71,7 @@ public class ClientRegistryTest extends TestCase
assertEquals(0, numberOfClientsAbsent);
}
- public void testAwaitTwoClientWhenClientRegistersWhilstWaiting()
+ public void testAwaitTwoClientsWhenClientRegistersWhilstWaiting()
{
_clientRegistry.registerClient(CLIENT1_REGISTERED_NAME);
registerClientLater(CLIENT2_REGISTERED_NAME, 50);
@@ -79,6 +80,41 @@ public class ClientRegistryTest extends TestCase
assertEquals(0, numberOfClientsAbsent);
}
+ public void testAwaitTimeoutForPromptRegistrations()
+ {
+ registerClientsLaterAndAssertResult("Clients registering every 100ms should be within 600ms timeout",
+ new int[] {300, 400, 500},
+ 600,
+ 0);
+ }
+
+ public void testAwaitTimeoutForWhenThirdRegistrationIsLate()
+ {
+ registerClientsLaterAndAssertResult("Third client registering tardily should exceed timeout",
+ new int[] {300, 400, 1500},
+ 600,
+ 1);
+ }
+
+ public void testAwaitTimeoutWhenSecondAndThirdRegistrationsAreLate()
+ {
+ registerClientsLaterAndAssertResult("Second and third clients registering tardily should exceed timeout",
+ new int[] {300, 1500, 1500},
+ 600,
+ 2);
+ }
+
+ private void registerClientsLaterAndAssertResult(String message, int[] registrationDelays, int timeout, int expectedNumberOfAbsentees)
+ {
+ registerClientLater(CLIENT1_REGISTERED_NAME, registrationDelays[0]);
+ registerClientLater(CLIENT2_REGISTERED_NAME, registrationDelays[1]);
+ registerClientLater(CLIENT3_REGISTERED_NAME, registrationDelays[2]);
+
+ int numberOfClientsAbsent = _clientRegistry.awaitClients(3, timeout);
+
+ assertEquals(message, expectedNumberOfAbsentees, numberOfClientsAbsent);
+ }
+
private void registerClientLater(final String clientName, long delayInMillis)
{
doLater(new TimerTask()
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java
index bc58ea41c5..f773c727a1 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java
@@ -19,6 +19,8 @@
*/
package org.apache.qpid.disttest.controller;
+import static org.apache.qpid.systest.disttest.SystemTestConstants.COMMAND_RESPONSE_TIMEOUT;
+import static org.apache.qpid.systest.disttest.SystemTestConstants.REGISTRATION_TIMEOUT;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
@@ -31,8 +33,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.controller.config.Config;
import org.apache.qpid.disttest.controller.config.TestInstance;
@@ -42,16 +42,14 @@ import org.apache.qpid.disttest.message.RegisterClientCommand;
import org.apache.qpid.disttest.message.Response;
import org.apache.qpid.disttest.message.StopClientCommand;
import org.apache.qpid.disttest.results.aggregation.ITestResult;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-public class ControllerTest extends TestCase
+public class ControllerTest extends QpidTestCase
{
private static final String CLIENT1_REGISTERED_NAME = "client-uid1";
- private static final long COMMAND_RESPONSE_TIMEOUT = 1000;
- private static final long REGISTRATION_TIMEOUT = 1000;
-
private Controller _controller;
private ControllerJmsDelegate _respondingJmsDelegate;
private TestRunner _testRunner;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java
index 284db38f44..da180f328f 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java
@@ -25,9 +25,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ParticipatingClientsTest extends TestCase
+public class ParticipatingClientsTest extends QpidTestCase
{
private static final String CLIENT1_CONFIGURED_NAME = "CLIENT1_CONFIGURED_NAME";
private static final String CLIENT2_CONFIGURED_NAME = "CLIENT2_CONFIGURED_NAME";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java
index 983da299b9..d8b25e76fa 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java
@@ -32,8 +32,6 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.controller.config.QueueConfig;
import org.apache.qpid.disttest.controller.config.TestInstance;
@@ -45,10 +43,11 @@ import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.Response;
import org.apache.qpid.disttest.message.StartTestCommand;
import org.apache.qpid.disttest.message.TearDownTestCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-public class TestRunnerTest extends TestCase
+public class TestRunnerTest extends QpidTestCase
{
private static final String TEST_NAME = "TEST_NAME";
private static final String PARTICIPANT_NAME = "TEST_PARTICIPANT_NAME";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java
index d4af439dea..4bf4307eaf 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java
@@ -29,16 +29,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.client.property.PropertyValue;
import org.apache.qpid.disttest.client.property.SimplePropertyValue;
import org.apache.qpid.disttest.controller.CommandForClient;
import org.apache.qpid.disttest.message.Command;
import org.apache.qpid.disttest.message.CreateMessageProviderCommand;
import org.apache.qpid.disttest.message.NoOpCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ClientConfigTest extends TestCase
+public class ClientConfigTest extends QpidTestCase
{
private static final String CLIENT1 = "client1";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest-test-config.js b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest-test-config.js
index 07f8bf9d92..527300eff4 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest-test-config.js
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest-test-config.js
@@ -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.
+ *
+ */
jsonObject = {
"_tests":
QPID.iterations( { "__ACK_MODE": [ 0, 1 ] },
@@ -31,4 +51,4 @@ jsonObject = {
)
})
-} \ No newline at end of file
+}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java
index 257f139849..e208945901 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java
@@ -23,12 +23,12 @@ import java.io.Reader;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.ConfigFileTestHelper;
import org.apache.qpid.disttest.client.property.PropertyValue;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
-public class ConfigReaderTest extends TestCase
+public class ConfigReaderTest extends QpidTestCase
{
private Config _config;
@@ -111,8 +111,9 @@ public class ConfigReaderTest extends TestCase
public void testReadsJS() throws Exception
{
ConfigReader configReader = new ConfigReader();
- String path = getClass().getResource("ConfigReaderTest-test-config.js").toURI().getPath();
+ String path = TestFileUtils.createTempFileFromResource(this, "ConfigReaderTest-test-config.js").getAbsolutePath();
_config = configReader.getConfigFromFile(path);
+
List<TestConfig> testConfigs = _config.getTestConfigs();
assertEquals("Unexpected number of tests", 2, testConfigs.size());
TestConfig testConfig1 = _config.getTestConfigs().get(0);
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java
index 88750b9737..291ce2af78 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java
@@ -24,9 +24,9 @@ import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ConfigTest extends TestCase
+public class ConfigTest extends QpidTestCase
{
public void testGetTestsForTestWithIteratingMessageSizes()
{
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java
index 7c839ed462..0eee80e425 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java
@@ -27,13 +27,12 @@ import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.Command;
import org.apache.qpid.disttest.message.CreateConnectionCommand;
import org.apache.qpid.disttest.message.NoOpCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ConnectionConfigTest extends TestCase
+public class ConnectionConfigTest extends QpidTestCase
{
private static final String CONNECTION_FACTORY_NAME = "ConnectionFactoryName";
private static final String CONNECTION_NAME = "ConnectionName";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java
index c011ff4711..0aa05a176e 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java
@@ -19,11 +19,10 @@
*/
package org.apache.qpid.disttest.controller.config;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.CreateConsumerCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ConsumerConfigTest extends TestCase
+public class ConsumerConfigTest extends QpidTestCase
{
public void testConsumerHasZeroArgConstructorForGson()
{
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest-test-config.js b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest-test-config.js
index f64af82feb..eab98e8bd7 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest-test-config.js
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest-test-config.js
@@ -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.
+ *
+ */
jsonObject = {
"_countries":
QPID.iterations( { "__ITERATING_VALUE": [ 0, 1 ] },
@@ -20,4 +40,4 @@ jsonObject = {
)
})
-} \ No newline at end of file
+}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest.java
index eb4063888b..55c1d4a7bd 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/JavaScriptConfigEvaluatorTest.java
@@ -25,15 +25,16 @@ import static org.apache.commons.beanutils.PropertyUtils.getProperty;
import java.util.List;
import java.util.TreeMap;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
import com.google.gson.Gson;
-public class JavaScriptConfigEvaluatorTest extends TestCase
+public class JavaScriptConfigEvaluatorTest extends QpidTestCase
{
public void testEvaluateJavaScript() throws Exception
{
- String jsFilePath = getClass().getResource("JavaScriptConfigEvaluatorTest-test-config.js").toURI().getPath();
+ String jsFilePath = TestFileUtils.createTempFileFromResource(this, "JavaScriptConfigEvaluatorTest-test-config.js").getAbsolutePath();
String rawConfig = new JavaScriptConfigEvaluator().evaluateJavaScript(jsFilePath);
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java
index a3b367a4b4..148c07b1ca 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java
@@ -21,13 +21,12 @@ package org.apache.qpid.disttest.controller.config;
import java.util.HashMap;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.client.property.PropertyValue;
import org.apache.qpid.disttest.client.property.SimplePropertyValue;
import org.apache.qpid.disttest.message.CreateMessageProviderCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class MessageProviderConfigTest extends TestCase
+public class MessageProviderConfigTest extends QpidTestCase
{
public void testCreateCommandsForMessageProvider()
{
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ParticipantConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ParticipantConfigTest.java
index f58cc628a4..b6efd68cbd 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ParticipantConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ParticipantConfigTest.java
@@ -32,7 +32,7 @@ public class ParticipantConfigTest extends QpidTestCase
setTestSystemProperty(ParticipantConfig.DURATION_OVERRIDE_SYSTEM_PROPERTY, String.valueOf(overriddenDuration));
CreateParticpantCommand createParticipantCommand = mock(CreateParticpantCommand.class);
- ParticipantConfig participantConfig = new ParticipantConfig("name", "destinationName", 1, 2, 5000)
+ ParticipantConfig participantConfig = new ParticipantConfig("name", "destinationName", false, 1, 2, 5000)
{
};
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java
index b9e591f113..44fca4bb7c 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java
@@ -22,11 +22,10 @@ package org.apache.qpid.disttest.controller.config;
import javax.jms.DeliveryMode;
import javax.jms.Message;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.CreateProducerCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ProducerConfigTest extends TestCase
+public class ProducerConfigTest extends QpidTestCase
{
public void testProducerHasZeroArgConstructorForGson()
{
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java
index 8775e4064d..02cdbb8fca 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java
@@ -29,14 +29,13 @@ import java.util.List;
import javax.jms.Session;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.Command;
import org.apache.qpid.disttest.message.CreateConsumerCommand;
import org.apache.qpid.disttest.message.CreateProducerCommand;
import org.apache.qpid.disttest.message.CreateSessionCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class SessionConfigTest extends TestCase
+public class SessionConfigTest extends QpidTestCase
{
private static final String CONNECTION_NAME = "conn1";
private static final String SESSION = "session1";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java
index 1212a57606..be7c7a7c8c 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java
@@ -26,12 +26,11 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.controller.CommandForClient;
import org.apache.qpid.disttest.message.NoOpCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class TestConfigTest extends TestCase
+public class TestConfigTest extends QpidTestCase
{
private static final QueueConfig[] EMPTY_QUEUES_ARRAY = new QueueConfig[0];
private static final String CLIENT1 = "client1";
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java
index 928fbe58cf..187b57c399 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java
@@ -26,14 +26,13 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.controller.CommandForClient;
import org.apache.qpid.disttest.message.CreateConsumerCommand;
import org.apache.qpid.disttest.message.CreateProducerCommand;
import org.apache.qpid.disttest.message.NoOpCommand;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class TestInstanceTest extends TestCase
+public class TestInstanceTest extends QpidTestCase
{
private static final String CLIENT_NAME = "CLIENT_NAME";
private static final int ITERATION_NUMBER = 0;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/db/ResultsDbWriterTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/db/ResultsDbWriterTest.java
new file mode 100644
index 0000000000..abc6b44493
--- /dev/null
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/db/ResultsDbWriterTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.disttest.db;
+
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ITERATION_NUMBER;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PARTICIPANT_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TEST_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.THROUGHPUT;
+import static org.apache.qpid.test.utils.TestFileUtils.createTestDirectory;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.Hashtable;
+import java.util.TimeZone;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.disttest.db.ResultsDbWriter.Clock;
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.results.ResultsTestFixture;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.util.FileUtils;
+
+public class ResultsDbWriterTest extends QpidTestCase
+{
+ private static final long _dummyTimestamp = 1234;
+
+ private File _tempDbDirectory;
+ private Clock _clock = mock(Clock.class);
+ private ResultsTestFixture _resultsTestFixture = new ResultsTestFixture();
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ _tempDbDirectory = createTestDirectory();
+ when(_clock.currentTimeMillis()).thenReturn(_dummyTimestamp);
+ }
+
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ FileUtils.deleteDirectory(_tempDbDirectory.getAbsolutePath());
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+
+ public void testWriteResults() throws Exception
+ {
+ Context context = getContext();
+ ResultsForAllTests results = _resultsTestFixture.createResultsForAllTests();
+ String runId = "myRunId";
+
+ ResultsDbWriter resultsDbWriter = new ResultsDbWriter(context, runId, _clock);
+ resultsDbWriter.createResultsTableIfNecessary();
+
+ resultsDbWriter.writeResults(results);
+
+ ParticipantResult expectedResult = _resultsTestFixture.getFirstParticipantResult(results);
+ assertResultsAreInDb(context, expectedResult, runId);
+ }
+
+ public void testDefaultRunId() throws Exception
+ {
+ TimeZone defaultTimeZone = TimeZone.getDefault();
+ try
+ {
+ // set non-GMT timezone to make the test more rigorous.
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT-05:00"));
+ ResultsDbWriter resultsDbWriter = new ResultsDbWriter(getContext(), null, _clock);
+ String runId = resultsDbWriter.getRunId();
+ assertEquals(
+ "Default run id '" + runId + "' should correspond to dummy timestamp " + _clock.currentTimeMillis(),
+ "run 1970-01-01 00:00:01.234",
+ runId);
+ }
+ finally
+ {
+ TimeZone.setDefault(defaultTimeZone);
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private Context getContext() throws NamingException
+ {
+ Context context = mock(Context.class);
+ Hashtable environment = new Hashtable();
+
+ environment.put(ResultsDbWriter.DRIVER_NAME, "org.apache.derby.jdbc.EmbeddedDriver");
+ environment.put(ResultsDbWriter.URL, "jdbc:derby:" + _tempDbDirectory + "perftestResultsDb;create=true");
+
+ when(context.getEnvironment()).thenReturn(environment);
+ return context;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void assertResultsAreInDb(Context context, ParticipantResult participantResult, String expectedRunId) throws Exception
+ {
+ String driverName = (String) context.getEnvironment().get(ResultsDbWriter.DRIVER_NAME);
+ Class<? extends Driver> driverClass = (Class<? extends Driver>) Class.forName(driverName);
+ driverClass.newInstance();
+ String url = (String) context.getEnvironment().get(ResultsDbWriter.URL);
+
+ Connection connection = DriverManager.getConnection(url);
+ Statement statement = connection.createStatement();
+ ResultSet rs = statement.executeQuery(
+ "SELECT * FROM results WHERE testName='" + participantResult.getTestName() +
+ "' AND runId='" + expectedRunId + "'");
+
+ try
+ {
+ rs.next();
+ assertEquals(participantResult.getTestName(), rs.getString(TEST_NAME.getDisplayName()));
+ assertEquals(participantResult.getIterationNumber(), rs.getInt(ITERATION_NUMBER.getDisplayName()));
+ assertEquals(participantResult.getParticipantName(), rs.getString(PARTICIPANT_NAME.getDisplayName()));
+ assertEquals(participantResult.getThroughput(), rs.getDouble(THROUGHPUT.getDisplayName()));
+ assertEquals(expectedRunId, rs.getString(ResultsDbWriter.RUN_ID));
+ assertEquals(new Timestamp(_dummyTimestamp), rs.getTimestamp(ResultsDbWriter.INSERTED_TIMESTAMP));
+ }
+ finally
+ {
+ connection.close();
+ }
+ }
+}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java
index ab0f52263b..d4f0cb1f22 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java
@@ -18,12 +18,11 @@
*/
package org.apache.qpid.disttest.jms;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.Command;
import org.apache.qpid.disttest.message.CommandType;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class JmsMessageAdaptorTest extends TestCase
+public class JmsMessageAdaptorTest extends QpidTestCase
{
public void testCheckAllCommandTypes()
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java
index 4a56fff8fe..2e0c2e1ecd 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java
@@ -24,14 +24,13 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.qpid.disttest.client.property.ListPropertyValue;
import org.apache.qpid.disttest.client.property.PropertyValue;
import org.apache.qpid.disttest.json.JsonHandler;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class JsonHandlerTest extends TestCase
+public class JsonHandlerTest extends QpidTestCase
{
private JsonHandler _jsonHandler = null;
private SendChristmasCards _testCommand = null;
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java
index 34727a7b8d..e9d444d59c 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java
@@ -18,7 +18,8 @@
*/
package org.apache.qpid.disttest.message;
-import static org.apache.qpid.disttest.message.ParticipantAttribute.*;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ACKNOWLEDGE_MODE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.BATCH_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.CONFIGURED_CLIENT_NAME;
import static org.apache.qpid.disttest.message.ParticipantAttribute.DELIVERY_MODE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.ERROR_MESSAGE;
@@ -30,23 +31,25 @@ import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_SYNCHRONO
import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_TOPIC;
import static org.apache.qpid.disttest.message.ParticipantAttribute.ITERATION_NUMBER;
import static org.apache.qpid.disttest.message.ParticipantAttribute.MAXIMUM_DURATION;
-import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PARTICIPANT_NAME;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PRIORITY;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PRODUCER_INTERVAL;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PRODUCER_START_DELAY;
import static org.apache.qpid.disttest.message.ParticipantAttribute.TEST_NAME;
import static org.apache.qpid.disttest.message.ParticipantAttribute.TIME_TAKEN;
import static org.apache.qpid.disttest.message.ParticipantAttribute.TIME_TO_LIVE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_NUMBER_OF_CONSUMERS;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_NUMBER_OF_PRODUCERS;
import java.util.Date;
import javax.jms.DeliveryMode;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ParticipantResultTest extends TestCase
+public class ParticipantResultTest extends QpidTestCase
{
public void testSharedParticipantResultAttributes() throws Exception
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormaterTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/ResultsTestFixture.java
index 565f59d25b..1edef031bf 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormaterTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/ResultsTestFixture.java
@@ -15,12 +15,15 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
*/
-package org.apache.qpid.disttest.results.formatting;
+package org.apache.qpid.disttest.results;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.ACKNOWLEDGE_MODE;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.AVERAGE_LATENCY;
import static org.apache.qpid.disttest.message.ParticipantAttribute.BATCH_SIZE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.CONFIGURED_CLIENT_NAME;
-import static org.apache.qpid.disttest.message.ParticipantAttribute.*;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.DELIVERY_MODE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.ERROR_MESSAGE;
import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_BROWSING_SUBSCRIPTION;
import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_DURABLE_SUBSCRIPTION;
@@ -29,7 +32,11 @@ import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_SELECTOR;
import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_SYNCHRONOUS_CONSUMER;
import static org.apache.qpid.disttest.message.ParticipantAttribute.IS_TOPIC;
import static org.apache.qpid.disttest.message.ParticipantAttribute.ITERATION_NUMBER;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.LATENCY_STANDARD_DEVIATION;
import static org.apache.qpid.disttest.message.ParticipantAttribute.MAXIMUM_DURATION;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MAX_LATENCY;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MESSAGE_THROUGHPUT;
+import static org.apache.qpid.disttest.message.ParticipantAttribute.MIN_LATENCY;
import static org.apache.qpid.disttest.message.ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PARTICIPANT_NAME;
import static org.apache.qpid.disttest.message.ParticipantAttribute.PAYLOAD_SIZE;
@@ -46,46 +53,41 @@ import static org.apache.qpid.disttest.message.ParticipantAttribute.TOTAL_PAYLOA
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.controller.ResultsForAllTests;
import org.apache.qpid.disttest.controller.TestResult;
import org.apache.qpid.disttest.message.ParticipantAttribute;
import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.results.aggregation.ITestResult;
-public class CSVFormaterTest extends TestCase
+public class ResultsTestFixture
{
+ public static final double THROUGHPUT_VALUE = 2048.49;
+
private static final String TEST1 = "TEST1";
private static final String PARTICIPANT = "PARTICIPANT";
private static final String CONFIGURED_CLIENT1 = "CONFIGURED_CLIENT1";
- private CSVFormater _formatter = new CSVFormater();
-
- public void testResultsFileWithWithOneRow() throws Exception
+ public ResultsForAllTests createResultsForAllTests()
{
ParticipantResult participantResult = mock(ParticipantResult.class);
Map<ParticipantAttribute, Object> participantAttributes = getParticipantAttributes();
when(participantResult.getAttributes()).thenReturn(participantAttributes);
when(participantResult.getParticipantName()).thenReturn(PARTICIPANT);
+ when(participantResult.getTestName()).thenReturn(TEST1);
+ when(participantResult.getIterationNumber()).thenReturn(0);
+ when(participantResult.getThroughput()).thenReturn(THROUGHPUT_VALUE);
TestResult testResult = new TestResult(TEST1);
testResult.addParticipantResult(participantResult);
ResultsForAllTests resultsForAllTests = new ResultsForAllTests();
resultsForAllTests.add(testResult);
-
- String output = _formatter.format(resultsForAllTests);
-
- String expectedOutput = readCsvOutputFileAsString("expectedOutput.csv");
-
- assertEquals(expectedOutput, output);
+ return resultsForAllTests;
}
private Map<ParticipantAttribute, Object> getParticipantAttributes()
@@ -96,7 +98,7 @@ public class CSVFormaterTest extends TestCase
participantAttributes.put(ITERATION_NUMBER, 0);
participantAttributes.put(CONFIGURED_CLIENT_NAME, CONFIGURED_CLIENT1);
participantAttributes.put(PARTICIPANT_NAME, PARTICIPANT);
- participantAttributes.put(NUMBER_OF_MESSAGES_PROCESSED, 0);
+ participantAttributes.put(NUMBER_OF_MESSAGES_PROCESSED, 2);
participantAttributes.put(PAYLOAD_SIZE, 1);
participantAttributes.put(PRIORITY, 2);
participantAttributes.put(TIME_TO_LIVE, 3);
@@ -115,32 +117,22 @@ public class CSVFormaterTest extends TestCase
participantAttributes.put(TOTAL_NUMBER_OF_CONSUMERS, 1);
participantAttributes.put(TOTAL_NUMBER_OF_PRODUCERS, 2);
participantAttributes.put(TOTAL_PAYLOAD_PROCESSED, 1024);
- participantAttributes.put(THROUGHPUT, 2048);
+ participantAttributes.put(THROUGHPUT, THROUGHPUT_VALUE);
participantAttributes.put(TIME_TAKEN, 1000);
participantAttributes.put(ERROR_MESSAGE, "error");
participantAttributes.put(MIN_LATENCY, 2l);
participantAttributes.put(MAX_LATENCY, 9l);
- participantAttributes.put(AVERAGE_LATENCY, 5.0f);
+ participantAttributes.put(AVERAGE_LATENCY, 4.6f);
participantAttributes.put(LATENCY_STANDARD_DEVIATION, 2.0f);
+ participantAttributes.put(MESSAGE_THROUGHPUT, 2);
return participantAttributes;
}
- private String readCsvOutputFileAsString(String filename) throws Exception
+ public ParticipantResult getFirstParticipantResult(ResultsForAllTests results)
{
- InputStream is = getClass().getResourceAsStream(filename);
- assertNotNull(is);
-
- StringBuilder output = new StringBuilder();
-
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- String line = null;
- while((line = br.readLine()) != null)
- {
- output.append(line);
- output.append("\n");
- }
-
- return output.toString();
+ List<ITestResult> testResults = results.getTestResults();
+ ITestResult testResult = testResults.iterator().next();
+ List<ParticipantResult> participantResults = testResult.getParticipantResults();
+ return participantResults.iterator().next();
}
-
}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java
index 393837b4d5..011eb4e68b 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java
@@ -24,11 +24,10 @@ import static org.mockito.Mockito.when;
import java.util.Arrays;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class AggregatorTest extends TestCase
+public class AggregatorTest extends QpidTestCase
{
private Aggregator _aggregator = new Aggregator();
private TestResultAggregator _testResultAggregator = mock(TestResultAggregator.class);
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java
index 72743be1d1..41da1edb33 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java
@@ -24,11 +24,9 @@ import java.util.Date;
import javax.jms.Session;
import org.apache.qpid.disttest.message.ParticipantResult;
-import org.apache.qpid.disttest.results.aggregation.ParticipantResultAggregator;
+import org.apache.qpid.test.utils.QpidTestCase;
-import junit.framework.TestCase;
-
-public class ParticipantResultAggregatorTest extends TestCase
+public class ParticipantResultAggregatorTest extends QpidTestCase
{
private ParticipantResultAggregator _aggregator = new ParticipantResultAggregator(ParticipantResult.class, AGGREGATED_RESULT_NAME);
@@ -39,15 +37,19 @@ public class ParticipantResultAggregatorTest extends TestCase
private static final long PARTICIPANT1_STARTDATE = 50;
private static final long PARTICIPANT1_ENDDATE = 20000;
private static final long PARTICIPANT1_TOTAL_PROCESSED = 1024;
+ private static final int PARTICIPANT1_NUMBER_OF_MESSAGES_PROCESSED = 20000;
private static final long PARTICIPANT2_STARTDATE = 100;
private static final long PARTICIPANT2_ENDDATE = 21000;
private static final long PARTICIPANT2_TOTAL_PROCESSED = 2048;
+ private static final int PARTICIPANT2_NUMBER_OF_MESSAGES_PROCESSED = 950;
private static final long OVERALL_PROCESSED = PARTICIPANT1_TOTAL_PROCESSED + PARTICIPANT2_TOTAL_PROCESSED;
private static final double OVERALL_TIMETAKEN = PARTICIPANT2_ENDDATE - PARTICIPANT1_STARTDATE;
+ private static final long OVERALL_NUMBER_OF_MESSAGES_PROCESSED = PARTICIPANT1_NUMBER_OF_MESSAGES_PROCESSED + PARTICIPANT2_NUMBER_OF_MESSAGES_PROCESSED;
private static final double EXPECTED_AGGREGATED_ALL_THROUGHPUT = ((OVERALL_PROCESSED)/1024)/((OVERALL_TIMETAKEN)/1000);
+ private static final int EXPECTED_AGGREGATED_MESSAGE_THROUGHPUT = (int)(OVERALL_NUMBER_OF_MESSAGES_PROCESSED * 1000.0d/OVERALL_TIMETAKEN);
public void testStartAndEndDateForOneParticipantResult()
{
@@ -128,6 +130,26 @@ public class ParticipantResultAggregatorTest extends TestCase
assertEquals(EXPECTED_AGGREGATED_ALL_THROUGHPUT, aggregratedResult.getThroughput(), 0.1);
}
+ public void testComputeMessageThroughput()
+ {
+ ParticipantResult result1 = new ParticipantResult();
+ result1.setStartDate(new Date(PARTICIPANT1_STARTDATE));
+ result1.setEndDate(new Date(PARTICIPANT1_ENDDATE));
+ result1.setNumberOfMessagesProcessed(PARTICIPANT1_NUMBER_OF_MESSAGES_PROCESSED);
+
+ ParticipantResult result2 = new ParticipantResult();
+ result2.setStartDate(new Date(PARTICIPANT2_STARTDATE));
+ result2.setEndDate(new Date(PARTICIPANT2_ENDDATE));
+ result2.setNumberOfMessagesProcessed(PARTICIPANT2_NUMBER_OF_MESSAGES_PROCESSED);
+
+ _aggregator.aggregate(result1);
+ _aggregator.aggregate(result2);
+
+ ParticipantResult aggregratedResult = _aggregator.getAggregatedResult();
+ assertEquals(EXPECTED_AGGREGATED_MESSAGE_THROUGHPUT, aggregratedResult.getMessageThroughput());
+
+ }
+
public void testConstantTestNameAndIterationNumberRolledUp() throws Exception
{
ParticipantResult result1 = new ParticipantResult();
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/SeriesStatisticsTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/SeriesStatisticsTest.java
index ec8da8418f..7417dddc4f 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/SeriesStatisticsTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/SeriesStatisticsTest.java
@@ -23,9 +23,9 @@ package org.apache.qpid.disttest.results.aggregation;
import java.util.Arrays;
import java.util.Collection;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class SeriesStatisticsTest extends TestCase
+public class SeriesStatisticsTest extends QpidTestCase
{
public static Collection<Long> SERIES = Arrays.asList(new Long[] { 2l, 4l, 4l, 4l, 5l, 5l, 7l, 9l, 5l });
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java
index 9c00e7cf1c..b254a0e3bf 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java
@@ -18,29 +18,30 @@
*/
package org.apache.qpid.disttest.results.aggregation;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
-import junit.framework.TestCase;
-
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
import org.apache.qpid.disttest.controller.TestResult;
import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.ProducerParticipantResult;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class TestResultAggregatorTest extends TestCase
+public class TestResultAggregatorTest extends QpidTestCase
{
-
private static final String TEST1_NAME = "TEST1_NAME";
private static final int TEST1_ITERATION_NUMBER = 1;
-
private static final String CONSUMER_PARTICIPANT_NAME1 = "CONSUMER_PARTICIPANT_NAME1";
private static final String CONSUMER_PARTICIPANT_NAME2 = "CONSUMER_PARTICIPANT_NAME2";
private static final String PRODUCER_PARTICIPANT_NAME = "PRODUCER_PARTICIPANT_NAME";
-
private static final long CONSUMER1_STARTDATE = 50;
private static final long CONSUMER1_ENDDATE = 20000;
@@ -64,6 +65,33 @@ public class TestResultAggregatorTest extends TestCase
private TestResultAggregator _aggregator = new TestResultAggregator();
+ public void testAggregateTestResults()
+ {
+ ResultsForAllTests resultsForAllTests1 = mock(ResultsForAllTests.class);
+ ResultsForAllTests resultsForAllTests2 = mock(ResultsForAllTests.class);
+
+ ResultsForAllTests summaryResult1 = mock(ResultsForAllTests.class);
+ ResultsForAllTests summaryResult2 = mock(ResultsForAllTests.class);
+
+ when(resultsForAllTests1.getAllParticipantsResult()).thenReturn(summaryResult1);
+ when(resultsForAllTests2.getAllParticipantsResult()).thenReturn(summaryResult2);
+
+ ITestResult testResult1 = mock(ITestResult.class);
+ ITestResult testResult2 = mock(ITestResult.class);
+
+ when(summaryResult1.getTestResults()).thenReturn(Arrays.asList(testResult1));
+ when(summaryResult2.getTestResults()).thenReturn(Arrays.asList(testResult2));
+
+ ResultsForAllTests actualSummaryResults = _aggregator.aggregateTestResults(Arrays.asList(
+ resultsForAllTests1,
+ resultsForAllTests2));
+
+ assertEquals(
+ "Summary results should contain the all the 'all participants' test results",
+ Arrays.asList(testResult1, testResult2),
+ actualSummaryResults.getTestResults());
+ }
+
public void testAggregateResultsForTwoConsumerAndOneProducer() throws Exception
{
TestResult originalTestResult = createResultsFromTest();
@@ -141,6 +169,10 @@ public class TestResultAggregatorTest extends TestCase
aggregatedTestResult.getAllParticipantResult(),
TEST1_NAME, TEST1_ITERATION_NUMBER,
BATCH_SIZE, NUMBER_OF_MESSAGES_CONSUMED_IN_TOTAL, 2, 1);
+
+ int expectedThroughtput = (int)Math.round(NUMBER_OF_MESSAGES_PRODUCED * 1000.0d /(CONSUMER2_ENDDATE - PRODUCER_STARTDATE));
+ ParticipantResult result = aggregatedTestResult.getAllParticipantResult();
+ assertEquals("Unexpected message throughtput", expectedThroughtput, result.getMessageThroughput());
}
private void assertLatencyAggregatedResults(ParticipantResult allConsumerParticipantResult)
@@ -197,4 +229,5 @@ public class TestResultAggregatorTest extends TestCase
participantResult.setEndDate(new Date(end));
participantResult.setBatchSize(batchSize);
}
+
}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormatterTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormatterTest.java
new file mode 100644
index 0000000000..bbf73b23d2
--- /dev/null
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormatterTest.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.disttest.results.formatting;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.qpid.disttest.controller.ResultsForAllTests;
+import org.apache.qpid.disttest.results.ResultsTestFixture;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class CSVFormatterTest extends QpidTestCase
+{
+ private CSVFormatter _formatter = new CSVFormatter();
+
+ public void testResultsFileWithWithOneRow() throws Exception
+ {
+ ResultsTestFixture resultsTestFixture = new ResultsTestFixture();
+ ResultsForAllTests resultsForAllTests = resultsTestFixture.createResultsForAllTests();
+
+ String output = _formatter.format(resultsForAllTests);
+
+ String expectedOutput = readCsvOutputFileAsString("expectedOutput.csv");
+
+ assertEquals(expectedOutput, output);
+ }
+
+ private String readCsvOutputFileAsString(String filename) throws Exception
+ {
+ InputStream is = getClass().getResourceAsStream(filename);
+ assertNotNull(is);
+
+ StringBuilder output = new StringBuilder();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line = null;
+ while((line = br.readLine()) != null)
+ {
+ output.append(line);
+ output.append("\n");
+ }
+
+ return output.toString();
+ }
+}
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java
index 6cec4b5245..ed109a2e27 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java
@@ -19,15 +19,13 @@
package org.apache.qpid.disttest.results.formatting;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.message.ConsumerParticipantResult;
import org.apache.qpid.disttest.message.ParticipantResult;
import org.apache.qpid.disttest.message.ProducerParticipantResult;
import org.apache.qpid.disttest.results.aggregation.TestResultAggregator;
-import org.apache.qpid.disttest.results.formatting.CSVOrderParticipantResultComparator;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class CSVOrderParticipantResultComparatorTest extends TestCase
+public class CSVOrderParticipantResultComparatorTest extends QpidTestCase
{
CSVOrderParticipantResultComparator _comparator = new CSVOrderParticipantResultComparator();
diff --git a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv
index ada2303d46..02ea67d56d 100644
--- a/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv
+++ b/java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv
@@ -1,2 +1,2 @@
-testName,iterationNumber,clientName,participantName,numberOfMessages,payloadSizeB,priority,timeToLiveMs,acknowledgeMode,deliveryMode,batchSize,maximumDurationMs,producerStartDelayMs,producerIntervalMs,isTopic,isDurableSubscription,isBrowsingSubscription,isSelector,isNoLocal,isSynchronousConsumer,totalNumberOfConsumers,totalNumberOfProducers,totalPayloadProcessedB,throughputKbPerS,timeTakenMs,errorMessage,minLatency,maxLatency,averageLatency,latencyStandardDeviation
-TEST1,0,CONFIGURED_CLIENT1,PARTICIPANT,0,1,2,3,4,5,6,7,8,9,true,false,true,false,true,false,1,2,1024,2048,1000,error,2,9,5.0,2.0
+testName,iterationNumber,throughputKbPerS,averageLatency,clientName,participantName,numberOfMessages,payloadSizeB,priority,timeToLiveMs,acknowledgeMode,deliveryMode,batchSize,maximumDurationMs,producerStartDelayMs,producerIntervalMs,isTopic,isDurableSubscription,isBrowsingSubscription,isSelector,isNoLocal,isSynchronousConsumer,totalNumberOfConsumers,totalNumberOfProducers,totalPayloadProcessedB,timeTakenMs,errorMessage,minLatency,maxLatency,latencyStandardDeviation,throughputMessagesPerS
+TEST1,0,2048,5,CONFIGURED_CLIENT1,PARTICIPANT,2,1,2,3,4,5,6,7,8,9,true,false,true,false,true,false,1,2,1024,1000,error,2,9,2.0,2
diff --git a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java
index 784e43469e..59396d46c0 100644
--- a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java
@@ -29,7 +29,6 @@ import javax.jms.Session;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.controller.config.QueueConfig;
import org.apache.qpid.disttest.jms.QpidQueueCreator;
@@ -37,6 +36,9 @@ public class QpidQueueCreatorTest extends DistributedTestSystemTestBase
{
private static final Map<String, Object> EMPTY_ATTRIBUTES = Collections.emptyMap();
+ private static final boolean QUEUE_DURABILITY = true;
+
+ private Connection _connection;
private QpidQueueCreator _creator;
private Session _session;
private List<QueueConfig> _configs;
@@ -46,20 +48,20 @@ public class QpidQueueCreatorTest extends DistributedTestSystemTestBase
public void setUp() throws Exception
{
super.setUp();
- Connection connection = getConnection();
- _session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ _connection = getConnection();
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
_creator = new QpidQueueCreator();
_configs = new ArrayList<QueueConfig>();
- _queueName = "direct://amq.direct//" + getTestQueueName();
+ _queueName = "direct://amq.direct//" + getTestQueueName() + "?durable='" + QUEUE_DURABILITY + "'";
}
public void testCreateQueueWithoutAttributes() throws Exception
{
- _configs.add(new QueueConfig(_queueName, true, EMPTY_ATTRIBUTES));
+ _configs.add(new QueueConfig(_queueName, QUEUE_DURABILITY, EMPTY_ATTRIBUTES));
assertQueueBound(_queueName, false);
- _creator.createQueues(_session, _configs);
+ _creator.createQueues(_connection, _session, _configs);
assertQueueBound(_queueName, true);
}
@@ -68,46 +70,28 @@ public class QpidQueueCreatorTest extends DistributedTestSystemTestBase
{
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("x-qpid-priorities", Integer.valueOf(5));
- _configs.add(new QueueConfig(_queueName, true, attributes));
+ _configs.add(new QueueConfig(_queueName, QUEUE_DURABILITY, attributes));
assertQueueBound(_queueName, false);
- _creator.createQueues(_session, _configs);
+ _creator.createQueues(_connection, _session, _configs);
assertQueueBound(_queueName, true);
}
public void testDeleteQueues() throws Exception
{
- _configs.add(new QueueConfig(_queueName, true, EMPTY_ATTRIBUTES));
+ _configs.add(new QueueConfig(_queueName, QUEUE_DURABILITY, EMPTY_ATTRIBUTES));
assertQueueBound(_queueName, false);
- _creator.createQueues(_session, _configs);
+ _creator.createQueues(_connection, _session, _configs);
assertQueueBound(_queueName, true);
- _creator.deleteQueues(_session, _configs);
+ _creator.deleteQueues(_connection, _session, _configs);
assertQueueBound(_queueName, false);
}
- public void testDeleteQueueThatDoesNotExist() throws Exception
- {
- String queueThatDoesNotExist = _queueName;
- List<QueueConfig> configs = new ArrayList<QueueConfig>();
- Map<String, Object> attributes = Collections.emptyMap();
- configs.add(new QueueConfig(queueThatDoesNotExist, true, attributes));
-
- try
- {
- _creator.deleteQueues(_session, configs);
- fail("Exception not thrown");
- }
- catch (DistributedTestException e)
- {
- // PASS
- }
- }
-
private void assertQueueBound(String queueName, boolean isBound) throws Exception
{
AMQDestination destination = (AMQDestination)_session.createQueue(queueName);
diff --git a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java
index 808b428bc9..b06ab0c735 100644
--- a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java
+++ b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java
@@ -21,8 +21,8 @@ package org.apache.qpid.systest.disttest;
public abstract class SystemTestConstants
{
- public static final long REGISTRATION_TIMEOUT = 5000;
- public static final long COMMAND_RESPONSE_TIMEOUT = 10000;
- public static final long TEST_RESULT_TIMEOUT = 5000;
+ public static final long REGISTRATION_TIMEOUT = 20000;
+ public static final long COMMAND_RESPONSE_TIMEOUT = 30000;
+ public static final long TEST_RESULT_TIMEOUT = 20000;
}
diff --git a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java
index 7e58e1b5b1..a0c2a4b342 100644
--- a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java
+++ b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java
@@ -20,7 +20,9 @@ package org.apache.qpid.systest.disttest.endtoend;
import static org.apache.qpid.disttest.AbstractRunner.JNDI_CONFIG_PROP;
import static org.apache.qpid.disttest.ControllerRunner.OUTPUT_DIR_PROP;
+import static org.apache.qpid.disttest.ControllerRunner.RUN_ID;
import static org.apache.qpid.disttest.ControllerRunner.TEST_CONFIG_PROP;
+import static org.apache.qpid.disttest.ControllerRunner.WRITE_TO_DB;
import java.io.File;
import java.io.IOException;
@@ -36,6 +38,7 @@ public class EndToEndTest extends QpidBrokerTestCase
private ControllerRunner _runner;
private static final String TEST_CONFIG = "perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/endtoend.json";
private static final String JNDI_CONFIG_FILE = "perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties";
+ private static final String RUN1 = "run1";
public void testRunner() throws Exception
{
@@ -44,6 +47,8 @@ public class EndToEndTest extends QpidBrokerTestCase
final String[] args = new String[] {TEST_CONFIG_PROP + "=" + TEST_CONFIG,
JNDI_CONFIG_PROP + "=" + JNDI_CONFIG_FILE,
+ WRITE_TO_DB + "=true",
+ RUN_ID + "=" + RUN1,
OUTPUT_DIR_PROP + "=" + csvOutputDir.getAbsolutePath()};
_runner = new ControllerRunner();
_runner.parseArgumentsIntoConfig(args);
@@ -76,10 +81,10 @@ public class EndToEndTest extends QpidBrokerTestCase
String[] cells = csvLine.split(",", DONT_STRIP_EMPTY_LAST_FIELD_FLAG);
// All attributes become cells in the CSV, so this will be true
assertEquals("Unexpected number of cells in CSV line " + csvLine, ParticipantAttribute.values().length, cells.length);
- assertEquals("Unexpected test name in CSV line " + csvLine, testName, cells[0]);
- assertEquals("Unexpected client name in CSV line " + csvLine, clientName, cells[2]);
- assertEquals("Unexpected participant name in CSV line " + csvLine, participantName, cells[3]);
- assertEquals("Unexpected number of messages processed in CSV line " + csvLine, String.valueOf(expectedNumberOfMessagesProcessed), cells[4]);
+ assertEquals("Unexpected test name in CSV line " + csvLine, testName, cells[ParticipantAttribute.TEST_NAME.ordinal()]);
+ assertEquals("Unexpected client name in CSV line " + csvLine, clientName, cells[ParticipantAttribute.CONFIGURED_CLIENT_NAME.ordinal()]);
+ assertEquals("Unexpected participant name in CSV line " + csvLine, participantName, cells[ParticipantAttribute.PARTICIPANT_NAME.ordinal()]);
+ assertEquals("Unexpected number of messages processed in CSV line " + csvLine, String.valueOf(expectedNumberOfMessagesProcessed), cells[ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED.ordinal()]);
}
diff --git a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties
index b5d053227c..149e632048 100644
--- a/java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties
+++ b/java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties
@@ -24,3 +24,6 @@ java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextF
connectionfactory.connectionfactory = amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:15672'
destination.controllerqueue = direct://amq.direct//controllerqueue
+
+jdbcDriverClass=org.apache.derby.jdbc.EmbeddedDriver
+jdbcUrl=jdbc:derby:/tmp/tempDbDirectory/perftestResultsDb;create=true
diff --git a/java/perftests/visualisation-jfc/build.xml b/java/perftests/visualisation-jfc/build.xml
index 02c9f5dcbd..04deb39d36 100644
--- a/java/perftests/visualisation-jfc/build.xml
+++ b/java/perftests/visualisation-jfc/build.xml
@@ -17,8 +17,8 @@
- under the License.
-->
<project name="visualisation-jfc" xmlns:ivy="antlib:org.apache.ivy.ant" default="build">
- <property name="module.depends" value="common perftests" />
- <property name="module.test.depends" value="test common/test" />
+ <property name="module.depends" value="perftests" />
+ <property name="module.test.depends" value="common common/tests" />
<property name="module.manifest" value="true" />
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java
index ed09f4a77e..5a77f22148 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java
@@ -21,5 +21,5 @@ package org.apache.qpid.disttest.charting;
public enum ChartType
{
- LINE, LINE3D, BAR, BAR3D, XYLINE, STATISTICAL_BAR
+ LINE, LINE3D, BAR, BAR3D, XYLINE, TIMELINE, STATISTICAL_BAR
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java
index e00859855e..91eafe324b 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java
@@ -30,7 +30,8 @@ import org.apache.qpid.disttest.charting.chartbuilder.ChartBuilder;
import org.apache.qpid.disttest.charting.chartbuilder.ChartBuilderFactory;
import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator;
-import org.apache.qpid.disttest.charting.seriesbuilder.JdbcCsvSeriesBuilder;
+import org.apache.qpid.disttest.charting.seriesbuilder.JdbcSeriesBuilder;
+import org.apache.qpid.disttest.charting.seriesbuilder.JdbcUrlGenerator;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
import org.apache.qpid.disttest.charting.writer.ChartWriter;
import org.jfree.chart.JFreeChart;
@@ -44,24 +45,46 @@ import org.slf4j.LoggerFactory;
* The following arguments are understood:
* </p>
* <ol>
- * <li>chart-defs=<i>directory contain chartdef file(s)</i></li>
- * <li>output-dir=<i>directory in which to produce the PNGs</i></li>
+ * <li>{@link #OUTPUT_DIR_PROP}</li>
+ * <li>{@link #CHART_DEFINITIONS_PROP}</li>
+ * <li>{@link #SUMMARY_TITLE_PROP}</li>
+ * <li>{@link #JDBC_DRIVER_NAME_PROP}</li>
+ * <li>{@link #JDBC_URL_PROP}</li>
* </ol>
+ * Default values are indicated by the similarly named constants in this class.
*/
public class ChartingUtil
{
private static final Logger LOGGER = LoggerFactory.getLogger(ChartingUtil.class);
+ /** directory in which to produce the PNGs */
public static final String OUTPUT_DIR_PROP = "outputdir";
public static final String OUTPUT_DIR_DEFAULT = ".";
+ /** the path to the directory containing the chart definition files */
public static final String CHART_DEFINITIONS_PROP = "chart-defs";
public static final String CHART_DEFINITIONS_DEFAULT = ".";
+ public static final String SUMMARY_TITLE_PROP = "summary-title";
+ public static final String SUMMARY_TITLE_DEFAULT = "Performance Charts";
+
+ /** the class name of the JDBC driver to use for reading the chart data */
+ public static final String JDBC_DRIVER_NAME_PROP = "jdbcDriverClass";
+ public static final String JDBC_DRIVER_NAME_DEFAULT = JdbcUrlGenerator.DEFAULT_JDBC_DRIVER_NAME;
+
+ /** the JDBC URL of the data to be charted */
+ public static final String JDBC_URL_PROP = "jdbcUrl";
+ public static final String JDBC_URL_DEFAULT = null;
+
+
private Map<String,String> _cliOptions = new HashMap<String, String>();
+
{
_cliOptions.put(OUTPUT_DIR_PROP, OUTPUT_DIR_DEFAULT);
_cliOptions.put(CHART_DEFINITIONS_PROP, CHART_DEFINITIONS_DEFAULT);
+ _cliOptions.put(SUMMARY_TITLE_PROP, SUMMARY_TITLE_DEFAULT);
+ _cliOptions.put(JDBC_DRIVER_NAME_PROP, JDBC_DRIVER_NAME_DEFAULT);
+ _cliOptions.put(JDBC_URL_PROP, JDBC_URL_DEFAULT);
}
public static void main(String[] args) throws Exception
@@ -82,26 +105,38 @@ public class ChartingUtil
private void produceAllCharts()
{
- final String chartingDefsDir = _cliOptions.get(CHART_DEFINITIONS_PROP);
- final File chartDirectory = new File(_cliOptions.get(OUTPUT_DIR_PROP));
- LOGGER.info("Chart chartdef directory/file: {} output directory : {}", chartingDefsDir, chartDirectory);
-
- List<ChartingDefinition> definitions = loadChartDefinitions(chartingDefsDir);
-
- LOGGER.info("There are {} chart(s) to produce", definitions.size());
final ChartWriter writer = new ChartWriter();
- writer.setOutputDirectory(chartDirectory);
+ writer.setOutputDirectory(new File(_cliOptions.get(OUTPUT_DIR_PROP)));
+
+ SeriesBuilder seriesBuilder = new JdbcSeriesBuilder(
+ _cliOptions.get(JDBC_DRIVER_NAME_PROP),
+ _cliOptions.get(JDBC_URL_PROP));
- final SeriesBuilder seriesBuilder = new JdbcCsvSeriesBuilder();
- for (ChartingDefinition chartingDefinition : definitions)
+ for (ChartingDefinition chartingDefinition : loadChartDefinitions())
{
- ChartBuilder chartBuilder = ChartBuilderFactory.createChartBuilder(chartingDefinition.getChartType(), seriesBuilder);
+ ChartBuilder chartBuilder = ChartBuilderFactory.createChartBuilder(
+ chartingDefinition.getChartType(),
+ seriesBuilder);
+
JFreeChart chart = chartBuilder.buildChart(chartingDefinition);
- writer.writeChartToFileSystem(chart, chartingDefinition.getChartStemName());
+ writer.writeChartToFileSystem(chart, chartingDefinition);
}
- writer.writeHtmlSummaryToFileSystem();
+ final String summaryChartTitle = _cliOptions.get(SUMMARY_TITLE_PROP);
+ writer.writeHtmlSummaryToFileSystem(summaryChartTitle);
+ }
+
+ private List<ChartingDefinition> loadChartDefinitions()
+ {
+ final String chartingDefsDir = _cliOptions.get(CHART_DEFINITIONS_PROP);
+
+ LOGGER.info("Chart chartdef directory/file: {}", chartingDefsDir);
+
+ List<ChartingDefinition> definitions = loadChartDefinitions(chartingDefsDir);
+
+ LOGGER.info("There are {} chart(s) to produce", definitions.size());
+ return definitions;
}
private List<ChartingDefinition> loadChartDefinitions(String chartingDefsDir)
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChart3DBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChart3DBuilder.java
index 491bb1c67d..b10fd477ed 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChart3DBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChart3DBuilder.java
@@ -36,7 +36,7 @@ public class BarChart3DBuilder extends CategoryDataSetBasedChartBuilder
}
@Override
- public JFreeChart createChartImpl(String title, String xAxisTitle,
+ protected JFreeChart createCategoryChart(String title, String xAxisTitle,
String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation,
boolean showLegend, boolean showToolTips, boolean showUrls)
{
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java
index b5c6a38067..7705ef5d3a 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java
@@ -35,7 +35,7 @@ public class BarChartBuilder extends CategoryDataSetBasedChartBuilder
}
@Override
- public JFreeChart createChartImpl(String title, String xAxisTitle,
+ protected JFreeChart createCategoryChart(String title, String xAxisTitle,
String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation,
boolean showLegend, boolean showToolTips, boolean showUrls)
{
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilder.java
index def87f5840..9cadf0ec3c 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilder.java
@@ -23,6 +23,9 @@ import java.awt.Color;
import java.awt.GradientPaint;
import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.ShortTextTitle;
@@ -30,12 +33,67 @@ import org.jfree.data.general.Dataset;
public abstract class BaseChartBuilder implements ChartBuilder
{
- private static final GradientPaint BLUE_GRADIENT = new GradientPaint(0, 0, Color.white, 0, 1000, Color.blue);
+ static final GradientPaint BLUE_GRADIENT = new GradientPaint(0, 0, Color.white, 0, 1000, Color.blue);
- public void addCommonChartAttributes(JFreeChart chart, ChartingDefinition chartingDefinition)
+ private SeriesPainter _seriesPainter = new SeriesPainter();
+
+ private final SeriesBuilder _seriesBuilder;
+
+ protected BaseChartBuilder(SeriesBuilder seriesBuilder)
+ {
+ _seriesBuilder = seriesBuilder;
+ }
+
+ @Override
+ public JFreeChart buildChart(ChartingDefinition chartingDefinition)
+ {
+ _seriesBuilder.setDatasetHolder(newDatasetHolder());
+ Dataset dataset = _seriesBuilder.build(chartingDefinition.getSeriesDefinitions());
+
+ JFreeChart chart = createChart(chartingDefinition, dataset);
+ return chart;
+ }
+
+
+ /**
+ * return a holder of an empty dataset suitable for use with the chart type
+ * returned by {@link #createChartImpl(String, String, String, Dataset, PlotOrientation, boolean, boolean, boolean)}.
+ */
+ protected abstract DatasetHolder newDatasetHolder();
+
+ /**
+ * Create a chart with the supplied parameters.
+ *
+ * For ease of implementation, the signature is intentionally similar
+ * to {@link ChartFactory}'s factory methods.
+ */
+ protected abstract JFreeChart createChartImpl(
+ String title, String xAxisTitle, String yAxisTitle,
+ final Dataset dataset,
+ PlotOrientation plotOrientation, boolean showLegend, boolean showToolTips, boolean showUrls);
+
+ /**
+ * Create a {@link SeriesStrokeAndPaintApplier} that will be used to format a chart
+ */
+ protected abstract SeriesStrokeAndPaintApplier newStrokeAndPaintApplier();
+
+
+ private JFreeChart createChart(ChartingDefinition chartingDefinition, final Dataset dataset)
{
+ String title = chartingDefinition.getChartTitle();
+ String xAxisTitle = chartingDefinition.getXAxisTitle();
+ String yAxisTitle = chartingDefinition.getYAxisTitle();
+
+ final JFreeChart chart = createChartImpl(
+ title, xAxisTitle, yAxisTitle,
+ dataset,
+ PLOT_ORIENTATION, SHOW_LEGEND, SHOW_TOOL_TIPS, SHOW_URLS);
+
addSubtitle(chart, chartingDefinition);
- setBackgroundColour(chart);
+ chart.setBackgroundPaint(BLUE_GRADIENT);
+ _seriesPainter.applySeriesAppearance(chart, chartingDefinition.getSeriesDefinitions(), newStrokeAndPaintApplier());
+
+ return chart;
}
private void addSubtitle(JFreeChart chart, ChartingDefinition chartingDefinition)
@@ -46,13 +104,9 @@ public abstract class BaseChartBuilder implements ChartBuilder
}
}
- private void setBackgroundColour(JFreeChart chart)
+ void setSeriesPainter(SeriesPainter seriesPainter)
{
- chart.setBackgroundPaint(BLUE_GRADIENT);
+ _seriesPainter = seriesPainter;
}
- public abstract JFreeChart createChartImpl(String title, String xAxisTitle,
- String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation, boolean showLegend, boolean showToolTips,
- boolean showUrls);
-
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryDataSetBasedChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryDataSetBasedChartBuilder.java
index a6c63f4560..0d08fd8ad1 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryDataSetBasedChartBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryDataSetBasedChartBuilder.java
@@ -20,40 +20,36 @@
package org.apache.qpid.disttest.charting.chartbuilder;
-import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
-import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilderCallback;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryLabelPositions;
+import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
+import org.jfree.data.general.Dataset;
public abstract class CategoryDataSetBasedChartBuilder extends BaseChartBuilder
{
- private final SeriesBuilder _seriesBuilder;
-
public CategoryDataSetBasedChartBuilder(SeriesBuilder seriesBuilder)
{
- _seriesBuilder = seriesBuilder;
+ super(seriesBuilder);
}
@Override
- public JFreeChart buildChart(ChartingDefinition chartingDefinition)
+ protected DatasetHolder newDatasetHolder()
{
- String title = chartingDefinition.getChartTitle();
- String xAxisTitle = chartingDefinition.getXAxisTitle();
- String yAxisTitle = chartingDefinition.getYAxisTitle();
-
- final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
-
- _seriesBuilder.setSeriesBuilderCallback(new SeriesBuilderCallback()
+ return new DatasetHolder()
{
+ final private DefaultCategoryDataset _dataset = new DefaultCategoryDataset();
+
@Override
- public void addDataPointToSeries(SeriesDefinition seriesDefinition, Object[] row)
+ public void addDataPointToSeries(SeriesDefinition seriesDefinition, SeriesRow row)
{
- String x = String.valueOf(row[0]);
- double y = Double.parseDouble(row[1].toString());
- dataset.addValue( y, seriesDefinition.getSeriesLegend(), x);
+ String x = row.dimensionAsString(0);
+ double y = row.dimensionAsDouble(1);
+ _dataset.addValue(y, seriesDefinition.getSeriesLegend(), x);
}
@Override
@@ -68,17 +64,33 @@ public abstract class CategoryDataSetBasedChartBuilder extends BaseChartBuilder
// unused
}
- });
+ @Override
+ public int getNumberOfDimensions()
+ {
+ return 2;
+ }
- _seriesBuilder.build(chartingDefinition.getSeries());
+ @Override
+ public Dataset getPopulatedDataset()
+ {
+ return _dataset;
+ }
+ };
+ }
- JFreeChart chart = createChartImpl(title, xAxisTitle, yAxisTitle,
- dataset, PLOT_ORIENTATION, SHOW_LEGEND, SHOW_TOOL_TIPS, SHOW_URLS);
+ @Override
+ protected SeriesStrokeAndPaintApplier newStrokeAndPaintApplier()
+ {
+ return new CategoryStrokeAndPaintApplier();
+ }
+ @Override
+ protected final JFreeChart createChartImpl(String title, String xAxisTitle, String yAxisTitle, Dataset dataset, PlotOrientation plotOrientation, boolean showLegend, boolean showToolTips, boolean showUrls)
+ {
+ JFreeChart chart = createCategoryChart(title, xAxisTitle, yAxisTitle, dataset, plotOrientation, showLegend, showToolTips, showUrls);
chart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
-
- addCommonChartAttributes(chart, chartingDefinition);
-
return chart;
}
+
+ protected abstract JFreeChart createCategoryChart(String title, String xAxisTitle, String yAxisTitle, Dataset dataset, PlotOrientation plotOrientation, boolean showLegend, boolean showToolTips, boolean showUrls);
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryStrokeAndPaintApplier.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryStrokeAndPaintApplier.java
new file mode 100644
index 0000000000..cbf5cbe515
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/CategoryStrokeAndPaintApplier.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.disttest.charting.chartbuilder;
+
+import java.awt.Color;
+import java.awt.Stroke;
+
+import org.jfree.chart.JFreeChart;
+
+class CategoryStrokeAndPaintApplier implements SeriesStrokeAndPaintApplier
+{
+ @Override
+ public void setSeriesStroke(int seriesIndex, Stroke stroke, JFreeChart targetChart)
+ {
+ targetChart.getCategoryPlot().getRenderer().setSeriesStroke(seriesIndex, stroke);
+ }
+
+ @Override
+ public void setSeriesPaint(int seriesIndex, Color colour, JFreeChart targetChart)
+ {
+ targetChart.getCategoryPlot().getRenderer().setSeriesPaint(seriesIndex, colour);
+ }
+} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java
index f4e11a2c4d..63a0573676 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java
@@ -39,8 +39,10 @@ public class ChartBuilderFactory
return new BarChart3DBuilder(seriesBuilder);
case XYLINE:
return new XYLineChartBuilder(seriesBuilder);
+ case TIMELINE:
+ return new TimeSeriesLineChartBuilder(seriesBuilder);
case STATISTICAL_BAR:
- return new StatisticalBarCharBuilder(seriesBuilder);
+ return new StatisticalBarChartBuilder(seriesBuilder);
default:
throw new IllegalArgumentException("Unknown chart type " + chartType);
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactory.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactory.java
new file mode 100644
index 0000000000..49d777c506
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactory.java
@@ -0,0 +1,66 @@
+/*
+ * 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.disttest.charting.chartbuilder;
+
+import java.awt.Color;
+
+public class ColorFactory
+{
+ /**
+ * Converts a colour name known to the JDK into a {@link Color} instance. Additionally,
+ * if the work dark_ is prepended to the colour, a darker shade of the same colour is
+ * produced.
+ *
+ * @param colourName
+ * @return colour instance
+ */
+ public static Color toColour(String colourName)
+ {
+ boolean darkVersion = false;
+ if (colourName.toLowerCase().startsWith("dark_"))
+ {
+ colourName = colourName.replaceFirst("(?i)dark_", "");
+ darkVersion = true;
+ }
+
+ Color colour = getColourFromStaticField(colourName);
+ if (darkVersion)
+ {
+ return colour.darker();
+ }
+ else
+ {
+ return colour;
+ }
+ }
+
+ private static Color getColourFromStaticField(String colourName)
+ {
+ try
+ {
+ return (Color) Color.class.getField(colourName.toLowerCase()).get(null);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Could not find colour for " + colourName, e);
+ }
+ }
+
+}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChart3DBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChart3DBuilder.java
index 27fff12da0..b92a25f5ac 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChart3DBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChart3DBuilder.java
@@ -34,7 +34,7 @@ public class LineChart3DBuilder extends CategoryDataSetBasedChartBuilder
}
@Override
- public JFreeChart createChartImpl(String title, String xAxisTitle,
+ protected JFreeChart createCategoryChart(String title, String xAxisTitle,
String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation,
boolean showLegend, boolean showToolTips, boolean showUrls)
{
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java
index 40f3a09b6b..3f5b18acda 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java
@@ -35,7 +35,7 @@ public class LineChartBuilder extends CategoryDataSetBasedChartBuilder
}
@Override
- public JFreeChart createChartImpl(String title, String xAxisTitle,
+ protected JFreeChart createCategoryChart(String title, String xAxisTitle,
String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation,
boolean showLegend, boolean showToolTips, boolean showUrls)
{
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesPainter.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesPainter.java
new file mode 100644
index 0000000000..854635dc87
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesPainter.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.disttest.charting.chartbuilder;
+
+import java.awt.BasicStroke;
+import java.util.List;
+
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.jfree.chart.JFreeChart;
+
+public class SeriesPainter
+{
+ public void applySeriesAppearance(JFreeChart chart, List<SeriesDefinition> seriesDefinitions, SeriesStrokeAndPaintApplier strokeAndPaintApplier)
+ {
+ for (int i = 0; i < seriesDefinitions.size(); i++)
+ {
+ SeriesDefinition seriesDefinition = seriesDefinitions.get(i);
+ if (seriesDefinition.getSeriesColourName() != null)
+ {
+ strokeAndPaintApplier.setSeriesPaint(i, ColorFactory.toColour(seriesDefinition.getSeriesColourName()), chart);
+ }
+ if (seriesDefinition.getStrokeWidth() != null)
+ {
+ // Negative width used to signify dashed
+ boolean dashed = seriesDefinition.getStrokeWidth() < 0;
+ float width = Math.abs(seriesDefinition.getStrokeWidth());
+ BasicStroke stroke = buildStrokeOfWidth(width, dashed);
+ strokeAndPaintApplier.setSeriesStroke(i, stroke, chart);
+ }
+ }
+ }
+
+ private BasicStroke buildStrokeOfWidth(float width, boolean dashed)
+ {
+ final BasicStroke stroke;
+ if (dashed)
+ {
+ stroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f, new float[] {5.0f, 3.0f}, 0.0f);
+ }
+ else
+ {
+ stroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+ }
+ return stroke;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesStrokeAndPaintApplier.java
index fe81cba282..4d6c37a9f4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesStrokeAndPaintApplier.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -18,13 +17,19 @@
* under the License.
*
*/
-package org.apache.qpid.server.security;
+package org.apache.qpid.disttest.charting.chartbuilder;
+
+import java.awt.Color;
+import java.awt.Stroke;
-import org.apache.qpid.server.plugins.PluginFactory;
+import org.jfree.chart.JFreeChart;
/**
- * The factory that generates instances of security plugins. Usually implemented as a static member class in the plugin itself.
+ * Applies the supplied stroke and color to a series in the target chart.
+ * Multiple implementations exist to because of the various chart types.
*/
-public interface SecurityPluginFactory<S extends SecurityPlugin> extends PluginFactory<S>
+public interface SeriesStrokeAndPaintApplier
{
+ void setSeriesStroke(int seriesIndex, Stroke stroke, JFreeChart targetChart);
+ void setSeriesPaint(int seriesIndex, Color color, JFreeChart targetChart);
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarCharBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarChartBuilder.java
index 86c3f62e09..c5ad2d7dad 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarCharBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/StatisticalBarChartBuilder.java
@@ -22,10 +22,10 @@ package org.apache.qpid.disttest.charting.chartbuilder;
import java.awt.Font;
-import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
-import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilderCallback;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
@@ -39,33 +39,27 @@ import org.jfree.data.general.Dataset;
import org.jfree.data.statistics.DefaultStatisticalCategoryDataset;
import org.jfree.data.statistics.StatisticalCategoryDataset;
-public class StatisticalBarCharBuilder extends BaseChartBuilder
+public class StatisticalBarChartBuilder extends BaseChartBuilder
{
- private final SeriesBuilder _seriesBuilder;
-
- public StatisticalBarCharBuilder(SeriesBuilder seriesBuilder)
+ public StatisticalBarChartBuilder(SeriesBuilder seriesBuilder)
{
- _seriesBuilder = seriesBuilder;
+ super(seriesBuilder);
}
@Override
- public JFreeChart buildChart(ChartingDefinition chartingDefinition)
+ protected DatasetHolder newDatasetHolder()
{
- String title = chartingDefinition.getChartTitle();
- String xAxisTitle = chartingDefinition.getXAxisTitle();
- String yAxisTitle = chartingDefinition.getYAxisTitle();
-
- final DefaultStatisticalCategoryDataset dataset = new DefaultStatisticalCategoryDataset();
-
- _seriesBuilder.setSeriesBuilderCallback(new SeriesBuilderCallback()
+ return new DatasetHolder()
{
+ private final DefaultStatisticalCategoryDataset _dataset = new DefaultStatisticalCategoryDataset();
+
@Override
- public void addDataPointToSeries(SeriesDefinition seriesDefinition, Object[] row)
+ public void addDataPointToSeries(SeriesDefinition seriesDefinition, SeriesRow row)
{
- String x = String.valueOf(row[0]);
- double mean = Double.parseDouble(row[1].toString());
- double stdDev = Double.parseDouble(row[2].toString());
- dataset.add(mean, stdDev, seriesDefinition.getSeriesLegend(), x);
+ String x = row.dimensionAsString(0);
+ double mean = row.dimensionAsDouble(1);
+ double stdDev = row.dimensionAsDouble(2);
+ _dataset.add(mean, stdDev, seriesDefinition.getSeriesLegend(), x);
}
@Override
@@ -80,18 +74,24 @@ public class StatisticalBarCharBuilder extends BaseChartBuilder
// unused
}
- });
-
- _seriesBuilder.build(chartingDefinition.getSeries());
-
- JFreeChart chart = createChartImpl(title, xAxisTitle, yAxisTitle, dataset, PLOT_ORIENTATION, SHOW_LEGEND,
- SHOW_TOOL_TIPS, SHOW_URLS);
-
- chart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
+ @Override
+ public int getNumberOfDimensions()
+ {
+ return 3;
+ }
- addCommonChartAttributes(chart, chartingDefinition);
+ @Override
+ public Dataset getPopulatedDataset()
+ {
+ return _dataset;
+ }
+ };
+ }
- return chart;
+ @Override
+ protected SeriesStrokeAndPaintApplier newStrokeAndPaintApplier()
+ {
+ return new CategoryStrokeAndPaintApplier();
}
@Override
@@ -105,6 +105,9 @@ public class StatisticalBarCharBuilder extends BaseChartBuilder
CategoryPlot plot = new CategoryPlot((StatisticalCategoryDataset) dataset, xAxis, yAxis, renderer);
JFreeChart chart = new JFreeChart(title, new Font("Arial", Font.PLAIN, 10), plot, true);
+
+ chart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
+
return chart;
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesHolder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesHolder.java
new file mode 100644
index 0000000000..803a098dfa
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesHolder.java
@@ -0,0 +1,70 @@
+/*
+ * 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.disttest.charting.chartbuilder;
+
+import java.util.Date;
+
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
+import org.jfree.data.general.Dataset;
+import org.jfree.data.time.Millisecond;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+class TimeSeriesHolder implements DatasetHolder
+{
+ private final TimeSeriesCollection _timeSeriesCollection = new TimeSeriesCollection();
+ private TimeSeries _timeSeries;
+
+ @Override
+ public void beginSeries(SeriesDefinition seriesDefinition)
+ {
+ _timeSeries = new TimeSeries(seriesDefinition.getSeriesLegend());
+ }
+
+ @Override
+ public void addDataPointToSeries(SeriesDefinition seriesDefinition, SeriesRow row)
+ {
+ Date x = row.dimensionAsDate(0);
+ double y = row.dimensionAsDouble(1);
+ RegularTimePeriod jfreeChartDate = new Millisecond(x);
+ _timeSeries.add(jfreeChartDate, y);
+ }
+
+ @Override
+ public void endSeries(SeriesDefinition seriesDefinition)
+ {
+ _timeSeriesCollection.addSeries(_timeSeries);
+ }
+
+ @Override
+ public int getNumberOfDimensions()
+ {
+ return 2;
+ }
+
+ @Override
+ public Dataset getPopulatedDataset()
+ {
+ return _timeSeriesCollection;
+ }
+} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesLineChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesLineChartBuilder.java
new file mode 100644
index 0000000000..7249ae6332
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesLineChartBuilder.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.disttest.charting.chartbuilder;
+
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.data.general.Dataset;
+import org.jfree.data.xy.XYDataset;
+
+public class TimeSeriesLineChartBuilder extends XYDataSetBasedChartBuilder
+{
+ public TimeSeriesLineChartBuilder(SeriesBuilder seriesBuilder)
+ {
+ super(seriesBuilder);
+ }
+
+ @Override
+ protected DatasetHolder newDatasetHolder()
+ {
+ return new TimeSeriesHolder();
+ }
+
+ @Override
+ public JFreeChart createChartImpl(String title, String xAxisTitle,
+ String yAxisTitle, final Dataset dataset, PlotOrientation plotOrientation,
+ boolean showLegend, boolean showToolTips, boolean showUrls)
+ {
+ JFreeChart chart = ChartFactory.createTimeSeriesChart(
+ title,
+ xAxisTitle,
+ yAxisTitle,
+ (XYDataset)dataset,
+ showLegend,
+ showToolTips,
+ showUrls);
+
+ return chart;
+ }
+}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/XYDataSetBasedChartBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/XYDataSetBasedChartBuilder.java
index 87d61ca2ee..575712f06c 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/XYDataSetBasedChartBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/XYDataSetBasedChartBuilder.java
@@ -19,38 +19,34 @@
*/
package org.apache.qpid.disttest.charting.chartbuilder;
+import java.awt.Color;
+import java.awt.Stroke;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
-import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilderCallback;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.CategoryLabelPositions;
+import org.jfree.data.general.Dataset;
import org.jfree.data.xy.DefaultXYDataset;
public abstract class XYDataSetBasedChartBuilder extends BaseChartBuilder
{
- private final SeriesBuilder _seriesBuilder;
-
public XYDataSetBasedChartBuilder(SeriesBuilder seriesBuilder)
{
- this._seriesBuilder = seriesBuilder;
+ super(seriesBuilder);
}
@Override
- public JFreeChart buildChart(ChartingDefinition chartingDefinition)
+ protected DatasetHolder newDatasetHolder()
{
- String title = chartingDefinition.getChartTitle();
- String xAxisTitle = chartingDefinition.getXAxisTitle();
- String yAxisTitle = chartingDefinition.getYAxisTitle();
-
- final DefaultXYDataset dataset = new DefaultXYDataset();
- _seriesBuilder.setSeriesBuilderCallback(new SeriesBuilderCallback()
+ return new DatasetHolder()
{
+ private final DefaultXYDataset _dataset = new DefaultXYDataset();
private List<Double[]> _xyPairs = null;
@Override
@@ -60,20 +56,24 @@ public abstract class XYDataSetBasedChartBuilder extends BaseChartBuilder
}
@Override
- public void addDataPointToSeries(SeriesDefinition seriesDefinition,
- Object[] row)
+ public void addDataPointToSeries(SeriesDefinition seriesDefinition, SeriesRow row)
{
- double x = Double.parseDouble(row[0].toString());
- double y = Double.parseDouble(row[1].toString());
+ double x = row.dimensionAsDouble(0);
+ double y = row.dimensionAsDouble(1);
_xyPairs.add(new Double[] {x, y});
}
-
@Override
public void endSeries(SeriesDefinition seriesDefinition)
{
double[][] seriesData = listToSeriesDataArray();
- dataset.addSeries(seriesDefinition.getSeriesLegend(), seriesData);
+ _dataset.addSeries(seriesDefinition.getSeriesLegend(), seriesData);
+ }
+
+ @Override
+ public int getNumberOfDimensions()
+ {
+ return 2;
}
private double[][] listToSeriesDataArray()
@@ -86,18 +86,34 @@ public abstract class XYDataSetBasedChartBuilder extends BaseChartBuilder
seriesData[0][i] = xyPair[0];
seriesData[1][i] = xyPair[1];
i++;
- }
+ }
return seriesData;
}
- });
-
- _seriesBuilder.build(chartingDefinition.getSeries());
- JFreeChart chart = createChartImpl(title, xAxisTitle, yAxisTitle,
- dataset, PLOT_ORIENTATION, SHOW_LEGEND, SHOW_TOOL_TIPS, SHOW_URLS);
+ @Override
+ public Dataset getPopulatedDataset()
+ {
+ return _dataset;
+ }
+ };
+ }
- addCommonChartAttributes(chart, chartingDefinition);
+ @Override
+ protected SeriesStrokeAndPaintApplier newStrokeAndPaintApplier()
+ {
+ return new SeriesStrokeAndPaintApplier()
+ {
+ @Override
+ public void setSeriesStroke(int seriesIndex, Stroke stroke, JFreeChart targetChart)
+ {
+ targetChart.getXYPlot().getRenderer().setSeriesStroke(seriesIndex, stroke);
+ }
- return chart;
+ @Override
+ public void setSeriesPaint(int seriesIndex, Color colour, JFreeChart targetChart)
+ {
+ targetChart.getXYPlot().getRenderer().setSeriesPaint(seriesIndex, colour);
+ }
+ };
}
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java
index 04b3f7ed3b..bfe47e598e 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java
@@ -30,6 +30,7 @@ public class ChartingDefinition
private final ChartType _chartType;
private final String _chartTitle;
private final String _chartSubtitle;
+ private final String _chartDescription;
private final String _xaxisTitle;
private final String _yaxisTitle;
private final List<SeriesDefinition> _seriesDefinitions;
@@ -39,12 +40,14 @@ public class ChartingDefinition
final ChartType chartType,
final String chartTitle,
final String chartSubtitle,
+ final String chartDescription,
final String xaxisTitle, final String yaxisTitle, List<SeriesDefinition> seriesDefinitions)
{
_chartStemName = chartStemName;
_chartType = chartType;
_chartTitle = chartTitle;
_chartSubtitle = chartSubtitle;
+ _chartDescription = chartDescription;
_xaxisTitle = xaxisTitle;
_yaxisTitle = yaxisTitle;
_seriesDefinitions = seriesDefinitions;
@@ -65,6 +68,10 @@ public class ChartingDefinition
return _chartSubtitle;
}
+ public String getChartDescription()
+ {
+ return _chartDescription;
+ }
public String getXAxisTitle()
{
@@ -77,17 +84,14 @@ public class ChartingDefinition
return _yaxisTitle;
}
-
-
public ChartType getChartType()
{
return _chartType;
}
- public List<SeriesDefinition> getSeries()
+ public List<SeriesDefinition> getSeriesDefinitions()
{
return Collections.unmodifiableList(_seriesDefinitions);
}
-
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java
index 4cbc9318a9..1988f561b6 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java
@@ -39,6 +39,7 @@ public class ChartingDefinitionCreator
public static final String CHART_TYPE_KEY = "chartType";
public static final String CHART_TITLE_KEY = "chartTitle";
public static final String CHART_SUBTITLE_KEY = "chartSubtitle";
+ public static final String CHART_DESCRIPTION_KEY = "chartDescription";
public static final String XAXIS_TITLE_KEY = "xAxisTitle";
public static final String YAXIS_TITLE_KEY = "yAxisTitle";
@@ -82,6 +83,7 @@ public class ChartingDefinitionCreator
final ChartType chartType = ChartType.valueOf(props.getProperty(CHART_TYPE_KEY));
final String chartTitle = props.getProperty(CHART_TITLE_KEY);
final String chartSubtitle = props.getProperty(CHART_SUBTITLE_KEY);
+ final String chartDescription = props.getProperty(CHART_DESCRIPTION_KEY);
final String xAxisTitle = props.getProperty(XAXIS_TITLE_KEY);
final String yAxisTitle = props.getProperty(YAXIS_TITLE_KEY);
@@ -91,8 +93,8 @@ public class ChartingDefinitionCreator
chartType,
chartTitle,
chartSubtitle,
- xAxisTitle,
- yAxisTitle, seriesDefinitions);
+ chartDescription,
+ xAxisTitle, yAxisTitle, seriesDefinitions);
return chartDefinition;
}
catch (IOException e)
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java
index a39e906957..d89ff855e2 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java
@@ -19,17 +19,24 @@
*/
package org.apache.qpid.disttest.charting.definition;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
public class SeriesDefinition
{
private final String _seriesStatement;
private final String _seriesLegend;
private final String _seriesDirectory;
+ private final String _seriesColourName;
+ private final Integer _seriesStrokeWidth;
- public SeriesDefinition(String seriesStatement, String seriesLegend, String seriesDirectory)
+ public SeriesDefinition(String seriesStatement, String seriesLegend, String seriesDirectory, String seriesColourName, Integer seriesStrokeWidth)
{
_seriesStatement = seriesStatement;
_seriesLegend = seriesLegend;
_seriesDirectory = seriesDirectory;
+ _seriesColourName = seriesColourName;
+ _seriesStrokeWidth = seriesStrokeWidth;
}
public String getSeriesStatement()
@@ -47,4 +54,22 @@ public class SeriesDefinition
return _seriesDirectory;
}
+ public String getSeriesColourName()
+ {
+ return _seriesColourName;
+ }
+
+ public Integer getStrokeWidth()
+ {
+ return _seriesStrokeWidth;
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("seriesLegend", _seriesLegend)
+ .append("seriesStatement", _seriesStatement)
+ .append("seriesDirectory", _seriesDirectory).toString();
+ }
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java
index fcc11807c8..d47e7488e1 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java
@@ -30,6 +30,8 @@ public class SeriesDefinitionCreator
public static final String SERIES_STATEMENT_KEY_FORMAT = "series.%d.statement";
public static final String SERIES_LEGEND_KEY_FORMAT = "series.%d.legend";
public static final String SERIES_DIRECTORY_KEY_FORMAT = "series.%d.dir";
+ public static final String SERIES_COLOUR_NAME_FORMAT = "series.%d.colourName";
+ public static final String SERIES_STROKE_WIDTH_FORMAT = "series.%d.strokeWidth";
public List<SeriesDefinition> createFromProperties(Properties properties)
{
@@ -42,10 +44,13 @@ public class SeriesDefinitionCreator
String seriesStatement = properties.getProperty(String.format(SERIES_STATEMENT_KEY_FORMAT, index));
String seriesLegend = properties.getProperty(String.format(SERIES_LEGEND_KEY_FORMAT, index));
String seriesDir = StrSubstitutor.replaceSystemProperties(properties.getProperty(String.format(SERIES_DIRECTORY_KEY_FORMAT, index)));
+ String seriesColourName = properties.getProperty(String.format(SERIES_COLOUR_NAME_FORMAT, index));
+ Integer seriesStrokeWidth = properties.getProperty(String.format(SERIES_STROKE_WIDTH_FORMAT, index)) == null
+ ? null : Integer.parseInt(properties.getProperty(String.format(SERIES_STROKE_WIDTH_FORMAT, index)));
if (seriesStatement != null)
{
- final SeriesDefinition seriesDefinition = new SeriesDefinition(seriesStatement, seriesLegend, seriesDir);
+ final SeriesDefinition seriesDefinition = new SeriesDefinition(seriesStatement, seriesLegend, seriesDir, seriesColourName, seriesStrokeWidth);
seriesDefinitions.add(seriesDefinition);
}
else
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilderCallback.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/DatasetHolder.java
index 7e23953fdb..14fd50facc 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilderCallback.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/DatasetHolder.java
@@ -20,11 +20,18 @@
package org.apache.qpid.disttest.charting.seriesbuilder;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.jfree.data.general.Dataset;
-public interface SeriesBuilderCallback
+/**
+ * Accepts data in the form of {@link SeriesDefinition}s and {@link SeriesRow}s,
+ * and returns it as a {@link Dataset} for use by a JFreeChart chart.
+ */
+public interface DatasetHolder
{
- public void beginSeries(SeriesDefinition seriesDefinition);
- public void addDataPointToSeries(SeriesDefinition seriesDefinition, Object[] row);
- public void endSeries(SeriesDefinition seriesDefinition);
+ int getNumberOfDimensions();
+ void beginSeries(SeriesDefinition seriesDefinition);
+ void addDataPointToSeries(SeriesDefinition seriesDefinition, SeriesRow row);
+ void endSeries(SeriesDefinition seriesDefinition);
+ Dataset getPopulatedDataset();
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilder.java
index a9adce0afc..180aa54c6d 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilder.java
@@ -19,7 +19,6 @@
*/
package org.apache.qpid.disttest.charting.seriesbuilder;
-import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
@@ -28,33 +27,52 @@ import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.qpid.disttest.charting.ChartingException;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.jfree.data.general.Dataset;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class JdbcCsvSeriesBuilder implements SeriesBuilder
+/**
+ * A {@link SeriesBuilder} that uses JDBC to read series data.
+ * The actual JDBC URL used is determined by my {@link JdbcUrlGenerator}.
+ */
+public class JdbcSeriesBuilder implements SeriesBuilder
{
+ private static final Logger LOGGER = LoggerFactory.getLogger(JdbcSeriesBuilder.class);
+
+ private DatasetHolder _datasetHolder;
- static
+ private final JdbcUrlGenerator _jdbcUrlGenerator;
+
+ /**
+ * @param providedJdbcUrl the JDBC URL. Provide null if the value should be
+ * inferred by {@link #_jdbcUrlGenerator}.
+ */
+ public JdbcSeriesBuilder(String jdbcDriverClass, String providedJdbcUrl)
{
- registerCsvDriver();
+ registerDriver(jdbcDriverClass);
+ _jdbcUrlGenerator = new JdbcUrlGenerator(providedJdbcUrl);
+ LOGGER.info("Created: " + this);
}
- private SeriesBuilderCallback _callback;
-
@Override
- public void setSeriesBuilderCallback(SeriesBuilderCallback callback)
+ public void setDatasetHolder(DatasetHolder callback)
{
- this._callback = callback;
+ _datasetHolder = callback;
}
@Override
- public void build(List<SeriesDefinition> seriesDefinitions)
+ public Dataset build(List<SeriesDefinition> seriesDefinitions)
{
for (Iterator<SeriesDefinition> iterator = seriesDefinitions.iterator(); iterator.hasNext();)
{
SeriesDefinition series = iterator.next();
buildDataSetForSingleSeries(series);
}
+ return _datasetHolder.getPopulatedDataset();
}
private void buildDataSetForSingleSeries(SeriesDefinition seriesDefinition)
@@ -63,16 +81,15 @@ public class JdbcCsvSeriesBuilder implements SeriesBuilder
Statement stmt = null;
try
{
- File seriesDir = getValidatedSeriesDirectory(seriesDefinition);
-
- conn = DriverManager.getConnection("jdbc:relique:csv:" + seriesDir.getAbsolutePath());
+ String jdbcUrl = _jdbcUrlGenerator.getJdbcUrl(seriesDefinition);
+ conn = DriverManager.getConnection(jdbcUrl);
final String seriesStatement = seriesDefinition.getSeriesStatement();
stmt = conn.createStatement();
ResultSet results = stmt.executeQuery(seriesStatement);
int columnCount = results.getMetaData().getColumnCount();
- _callback.beginSeries(seriesDefinition);
+ _datasetHolder.beginSeries(seriesDefinition);
while (results.next())
{
Object[] row = new Object[columnCount];
@@ -81,9 +98,10 @@ public class JdbcCsvSeriesBuilder implements SeriesBuilder
row[i] = results.getObject(i+1);
}
- _callback.addDataPointToSeries(seriesDefinition, row);
+ SeriesRow seriesRow = SeriesRow.createValidSeriesRow(_datasetHolder.getNumberOfDimensions(), row);
+ _datasetHolder.addDataPointToSeries(seriesDefinition, seriesRow);
}
- _callback.endSeries(seriesDefinition);
+ _datasetHolder.endSeries(seriesDefinition);
}
catch (SQLException e)
{
@@ -116,26 +134,24 @@ public class JdbcCsvSeriesBuilder implements SeriesBuilder
}
}
- private File getValidatedSeriesDirectory(SeriesDefinition series)
- {
- File seriesDir = new File(series.getSeriesDirectory());
- if (!seriesDir.isDirectory())
- {
- throw new ChartingException("seriesDirectory must be a directory : " + seriesDir);
- }
- return seriesDir;
- }
-
- private static void registerCsvDriver() throws ExceptionInInitializerError
+ private void registerDriver(String driverClassName) throws ExceptionInInitializerError
{
try
{
- Class.forName("org.relique.jdbc.csv.CsvDriver");
+ Class.forName(driverClassName);
+ LOGGER.info("Loaded JDBC driver class " + driverClassName);
}
catch (ClassNotFoundException e)
{
- throw new RuntimeException("Could not load CSV/JDBC driver", e);
+ throw new RuntimeException("Could not load JDBC driver " + driverClassName, e);
}
}
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("jdbcUrlGenerator", _jdbcUrlGenerator)
+ .toString();
+ }
}
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGenerator.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGenerator.java
new file mode 100644
index 0000000000..77f367b0f1
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGenerator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.disttest.charting.seriesbuilder;
+
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+
+public class JdbcUrlGenerator
+{
+ private String _providedJdbdUrl;
+
+ public static final String DEFAULT_JDBC_DRIVER_NAME = "org.relique.jdbc.csv.CsvDriver";
+
+ /**
+ * Used to create the JDBC URL if one has not been passed in.
+ */
+ private static final String CSV_JDBC_URL_BASE = "jdbc:relique:csv:";
+
+ /**
+ * @param providedJdbcUrl the JDBC URL. Provide null if the value should be
+ * inferred.
+ */
+ public JdbcUrlGenerator(String providedJdbcUrl)
+ {
+ _providedJdbdUrl = providedJdbcUrl;
+ }
+
+ /**
+ * Returns either the provided value ({@link #_providedJdbdUrl})
+ * or a CSV JDBC URL pointing at {@link SeriesDefinition#getSeriesDirectory()} value.
+ */
+ public String getJdbcUrl(SeriesDefinition seriesDefinition)
+ {
+ String seriesDir = seriesDefinition.getSeriesDirectory();
+
+ if(_providedJdbdUrl == null)
+ {
+ if(isBlank(seriesDir))
+ {
+ throw new IllegalArgumentException("Neither a series directory nor a JDBC url have been specified. Series definition: " + seriesDefinition);
+ }
+ return CSV_JDBC_URL_BASE + seriesDir;
+ }
+ else
+ {
+ if(isNotBlank(seriesDir))
+ {
+ throw new IllegalArgumentException("Both a series directory '" + seriesDir + "' and a JDBC url have been specified. Series definition: " + seriesDefinition);
+ }
+ return _providedJdbdUrl;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("providedJdbdUrl", _providedJdbdUrl)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilder.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilder.java
index 86e471efaf..a865c838c6 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilder.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesBuilder.java
@@ -22,11 +22,20 @@ package org.apache.qpid.disttest.charting.seriesbuilder;
import java.util.List;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.jfree.data.general.Dataset;
public interface SeriesBuilder
{
- void build(List<SeriesDefinition> seriesDefinitions);
-
- void setSeriesBuilderCallback(SeriesBuilderCallback seriesBuilderCallback);
+ /**
+ * Uses the supplied {@link SeriesDefinition}s to read the series data
+ * and pass it to the dataset holder set up in {@link #setDatasetHolder(DatasetHolder)}.
+ *
+ * @return the populated dataset
+ */
+ Dataset build(List<SeriesDefinition> seriesDefinitions);
+ /**
+ * Stores the supplied dataset holder so it can be populated in {@link #build(List)}.
+ */
+ void setDatasetHolder(DatasetHolder datasetHolder);
} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRow.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRow.java
new file mode 100644
index 0000000000..9c16866939
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRow.java
@@ -0,0 +1,98 @@
+/*
+ * 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.disttest.charting.seriesbuilder;
+
+import java.util.Arrays;
+import java.util.Date;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ * A data point in a chart. Thinly wraps an array to provide a convenient place to validate the number of dimensions,
+ * and to access dimensions in a typesafe manner.
+ */
+public class SeriesRow
+{
+ private final Object[] _dimensions;
+
+ public static SeriesRow createValidSeriesRow(int expectedNumberOfDimensions, Object[] dimensions)
+ {
+ int actualNumberOfDimensions = dimensions.length;
+ if(expectedNumberOfDimensions != actualNumberOfDimensions)
+ {
+ throw new IllegalArgumentException("Expected " + expectedNumberOfDimensions
+ + " dimensions but found " + actualNumberOfDimensions
+ + " in: " + Arrays.asList(dimensions));
+ }
+ return new SeriesRow(dimensions);
+ }
+
+ public SeriesRow(Object... dimensions)
+ {
+ _dimensions = dimensions;
+ }
+
+ public Object dimension(int dimension)
+ {
+ return _dimensions[dimension];
+ }
+
+ public String dimensionAsString(int dimension)
+ {
+ return String.valueOf(dimension(dimension));
+ }
+
+ public double dimensionAsDouble(int dimension)
+ {
+ return Double.parseDouble(dimensionAsString(dimension));
+ }
+
+ public Date dimensionAsDate(int dimension)
+ {
+ return (Date) dimension(dimension);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_dimensions).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ SeriesRow rhs = (SeriesRow) obj;
+ return new EqualsBuilder().append(_dimensions, rhs._dimensions).isEquals();
+ }
+
+
+} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/writer/ChartWriter.java b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/writer/ChartWriter.java
index 5d4a9b6b7e..341f01ccd1 100644
--- a/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/writer/ChartWriter.java
+++ b/java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/writer/ChartWriter.java
@@ -26,10 +26,11 @@ import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.SortedMap;
+import java.util.TreeMap;
import org.apache.qpid.disttest.charting.ChartingException;
+import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.slf4j.Logger;
@@ -42,19 +43,19 @@ public class ChartWriter
static final String SUMMARY_FILE_NAME = "chart-summary.html";
private File _chartDirectory = new File(".");
- private SortedSet<File> _chartFiles = new TreeSet<File>();
+ private SortedMap<File,ChartingDefinition> _chartFilesToChartDef = new TreeMap<File, ChartingDefinition>();
- public void writeChartToFileSystem(JFreeChart chart, String chartStemName)
+ public void writeChartToFileSystem(JFreeChart chart, ChartingDefinition chartDef)
{
OutputStream pngOutputStream = null;
try
{
- File pngFile = new File(_chartDirectory, chartStemName + ".png");
+ File pngFile = new File(_chartDirectory, chartDef.getChartStemName() + ".png");
pngOutputStream = new BufferedOutputStream(new FileOutputStream(pngFile));
ChartUtilities.writeChartAsPNG(pngOutputStream, chart, 600, 400, true, 0);
pngOutputStream.close();
- _chartFiles.add(pngFile);
+ _chartFilesToChartDef.put(pngFile, chartDef);
LOGGER.info("Written {} chart", pngFile);
}
@@ -78,20 +79,21 @@ public class ChartWriter
}
}
- public void writeHtmlSummaryToFileSystem()
+ public void writeHtmlSummaryToFileSystem(String summaryPageTitle)
{
- if(_chartFiles.size() < 2)
+ if(_chartFilesToChartDef.size() < 2)
{
- LOGGER.info("Only " + _chartFiles.size() + " chart image(s) have been written so no HTML summary file will be produced");
+ LOGGER.info("Only {} chart image(s) have been written so no HTML summary file will be produced", _chartFilesToChartDef.size());
return;
}
- String htmlHeader =
+ String htmlHeader = String.format(
"<html>\n" +
" <head>\n" +
- " <title>Performance Charts</title>\n" +
+ " <title>%s</title>\n" +
+ " <style type='text/css'>figure { float: left; display: table; width: 87px;}</style>\n" +
" </head>\n" +
- " <body>\n";
+ " <body>\n", summaryPageTitle);
String htmlFooter =
" </body>\n" +
@@ -101,22 +103,29 @@ public class ChartWriter
try
{
File summaryFile = new File(_chartDirectory, SUMMARY_FILE_NAME);
- LOGGER.debug("About to produce HTML summary file " + summaryFile.getAbsolutePath() + " from charts " + _chartFiles);
+ LOGGER.debug("About to produce HTML summary file " + summaryFile.getAbsolutePath() + " from charts " + _chartFilesToChartDef);
writer = new BufferedWriter(new FileWriter(summaryFile));
writer.write(htmlHeader);
writer.write(" <ul>\n");
- for (File chartFile : _chartFiles)
+ for (File chartFile : _chartFilesToChartDef.keySet())
{
writer.write(" <li><a href='#"+ chartFile.getName() +"'>" + chartFile.getName() + "</a></li>\n");
}
writer.write(" </ul>\n");
- for (File chartFile : _chartFiles)
+ for (File chartFile : _chartFilesToChartDef.keySet())
{
- writer.write(" <a name='" + chartFile.getName() + "'/>\n");
- writer.write(" <img src='" + chartFile.getName() + "'/>\n");
+ ChartingDefinition def = _chartFilesToChartDef.get(chartFile);
+ writer.write(" <figure>\n");
+ writer.write(" <a name='" + chartFile.getName() + "'/>\n");
+ writer.write(" <img src='" + chartFile.getName() + "'/>\n");
+ if (def.getChartDescription() != null)
+ {
+ writer.write(" <figcaption>" + def.getChartDescription() + "</figcaption>\n");
+ }
+ writer.write(" </figure>\n");
}
writer.write(htmlFooter);
writer.close();
@@ -144,5 +153,6 @@ public class ChartWriter
public void setOutputDirectory(final File chartDirectory)
{
_chartDirectory = chartDirectory;
+ LOGGER.info("Set chart directory: {}", chartDirectory);
}
}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilderTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilderTest.java
new file mode 100644
index 0000000000..c8a98aafa0
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/BaseChartBuilderTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.disttest.charting.chartbuilder;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+
+import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.Plot;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.general.Dataset;
+
+public class BaseChartBuilderTest extends QpidTestCase
+{
+ private static final String CHART_TITLE = "CHART_TITLE";
+ private static final String CHART_SUB_TITLE = "CHART_SUB_TITLE";
+ private static final String X_TITLE = "X_TITLE";
+ private static final String Y_TITLE = "Y_TITLE";
+
+ @SuppressWarnings("unchecked")
+ private List<SeriesDefinition> _seriesDefinitions = mock(List.class);
+
+ private ChartingDefinition _chartingDefinition = mock(ChartingDefinition.class);
+ private SeriesStrokeAndPaintApplier _strokeAndPaintApplier = mock(SeriesStrokeAndPaintApplier.class);
+ private DatasetHolder _datasetHolder = mock(DatasetHolder.class);
+ private SeriesPainter _seriesPainter = mock(SeriesPainter.class);
+
+ private SeriesBuilder _seriesBuilder = mock(SeriesBuilder.class);
+
+ private JFreeChart _jFreeChart;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ Plot plot = new CategoryPlot();
+ _jFreeChart = new JFreeChart(plot);
+
+ when(_chartingDefinition.getChartTitle()).thenReturn(CHART_TITLE);
+ when(_chartingDefinition.getChartSubtitle()).thenReturn(CHART_SUB_TITLE);
+ when(_chartingDefinition.getXAxisTitle()).thenReturn(X_TITLE);
+ when(_chartingDefinition.getYAxisTitle()).thenReturn(Y_TITLE);
+ when(_chartingDefinition.getSeriesDefinitions()).thenReturn(_seriesDefinitions );
+ }
+
+ public void testBuildChart()
+ {
+ BaseChartBuilder chartBuilder = new ChartBuilder(_seriesBuilder, _strokeAndPaintApplier, _datasetHolder)
+ {
+ @Override
+ protected JFreeChart createChartImpl(String title, String xAxisTitle, String yAxisTitle, Dataset dataset, PlotOrientation plotOrientation, boolean showLegend, boolean showToolTips, boolean showUrls)
+ {
+ assertEquals(CHART_TITLE, title);
+ assertEquals(X_TITLE, xAxisTitle);
+ assertEquals(Y_TITLE, yAxisTitle);
+
+ return _jFreeChart;
+ }
+ };
+
+ JFreeChart chart = chartBuilder.buildChart(_chartingDefinition);
+
+ assertEquals(BaseChartBuilder.BLUE_GRADIENT, chart.getBackgroundPaint());
+ assertEquals("The *second* subtitle of the generated chart should have the text from the chart definition",
+ CHART_SUB_TITLE, ((TextTitle)chart.getSubtitle(1)).getText());
+ verify(_seriesPainter).applySeriesAppearance(_jFreeChart, _seriesDefinitions, _strokeAndPaintApplier);
+ }
+
+ /**
+ * Extends BaseChartBuilder to allow us to plug in in mock dependencies
+ */
+ private abstract class ChartBuilder extends BaseChartBuilder
+ {
+ private SeriesStrokeAndPaintApplier _seriesStrokeAndPaintApplier;
+ private DatasetHolder _datasetHolder;
+
+ private ChartBuilder(SeriesBuilder seriesBuilder, SeriesStrokeAndPaintApplier seriesStrokeAndPaintApplier, DatasetHolder datasetHolder)
+ {
+ super(seriesBuilder);
+ _seriesStrokeAndPaintApplier = seriesStrokeAndPaintApplier;
+ _datasetHolder = datasetHolder;
+ setSeriesPainter(_seriesPainter);
+ }
+
+ @Override
+ protected SeriesStrokeAndPaintApplier newStrokeAndPaintApplier()
+ {
+ return _seriesStrokeAndPaintApplier;
+ }
+
+ @Override
+ protected DatasetHolder newDatasetHolder()
+ {
+ return _datasetHolder;
+ }
+ }
+}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java
index e735fb58c6..14f81566a6 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java
@@ -19,14 +19,13 @@
*/
package org.apache.qpid.disttest.charting.chartbuilder;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
import org.apache.qpid.disttest.charting.ChartType;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.apache.qpid.test.utils.QpidTestCase;
-import junit.framework.TestCase;
-
-public class ChartBuilderFactoryTest extends TestCase
+public class ChartBuilderFactoryTest extends QpidTestCase
{
private SeriesBuilder _seriesBuilder = mock(SeriesBuilder.class);
@@ -59,4 +58,10 @@ public class ChartBuilderFactoryTest extends TestCase
ChartBuilder builder = ChartBuilderFactory.createChartBuilder(ChartType.XYLINE, _seriesBuilder);
assertTrue(builder instanceof XYLineChartBuilder);
}
+
+ public void testTimeSeriesLineChart()
+ {
+ ChartBuilder builder = ChartBuilderFactory.createChartBuilder(ChartType.TIMELINE, _seriesBuilder);
+ assertTrue(builder instanceof TimeSeriesLineChartBuilder);
+ }
}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartProductionTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartProductionTest.java
index 2744e17404..7af3a6b35e 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartProductionTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartProductionTest.java
@@ -19,33 +19,35 @@
*/
package org.apache.qpid.disttest.charting.chartbuilder;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.util.Collections;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.qpid.disttest.charting.ChartType;
import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
-import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilderCallback;
+import org.apache.qpid.disttest.charting.seriesbuilder.DatasetHolder;
import org.apache.qpid.disttest.charting.seriesbuilder.SeriesBuilder;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
import org.apache.qpid.disttest.charting.writer.ChartWriter;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestFileUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.ShortTextTitle;
-
-import junit.framework.TestCase;
+import org.jfree.data.general.Dataset;
/**
* Tests the production of the different chart types. To manually
* verify the generated output, set the system property {@link #RETAIN_TEST_CHARTS}
* to prevent the automatic deletion of the test chart directory.
- *
*/
-public class ChartProductionTest extends TestCase
+public class ChartProductionTest extends QpidTestCase
{
private static final String TEST_CHARTTITLE = "TEST_CHARTTITLE";
private static final String TEST_CHARTSUBTITLE = "TEST_CHARTSUBTITLE";
@@ -54,6 +56,16 @@ public class ChartProductionTest extends TestCase
private static final String TEST_SERIESLEGEND = "TEST_SERIESLEGEND";
+ private static final SeriesRow[] SIMPLE_SERIES_ROWS = new SeriesRow[]
+ {
+ new SeriesRow(1d, 1d),
+ new SeriesRow(2d, 2d),
+ new SeriesRow(3d, 3d),
+ new SeriesRow(4d, 4d),
+ new SeriesRow(5d, 5d),
+ new SeriesRow(6d, 6d),
+ };
+
private static final String RETAIN_TEST_CHARTS = "retainTestCharts";
private SeriesDefinition _seriesDefinition = mock(SeriesDefinition.class);
@@ -66,12 +78,15 @@ public class ChartProductionTest extends TestCase
super.setUp();
when(_seriesDefinition.getSeriesLegend()).thenReturn(TEST_SERIESLEGEND);
+ when(_seriesDefinition.getStrokeWidth()).thenReturn(null);
+ when(_seriesDefinition.getSeriesColourName()).thenReturn(null);
+ when(_chartingDefinition.getChartStemName()).thenReturn(getName());
when(_chartingDefinition.getChartTitle()).thenReturn(TEST_CHARTTITLE);
when(_chartingDefinition.getChartSubtitle()).thenReturn(TEST_CHARTSUBTITLE);
when(_chartingDefinition.getXAxisTitle()).thenReturn(TEST_XAXIS);
when(_chartingDefinition.getYAxisTitle()).thenReturn(TEST_YAXIS);
- when(_chartingDefinition.getSeries()).thenReturn(Collections.singletonList(_seriesDefinition));
+ when(_chartingDefinition.getSeriesDefinitions()).thenReturn(Collections.singletonList(_seriesDefinition));
File chartDir = TestFileUtils.createTestDirectory("charts", false);
if (!System.getProperties().containsKey(RETAIN_TEST_CHARTS))
@@ -88,7 +103,7 @@ public class ChartProductionTest extends TestCase
public void testBarChart() throws Exception
{
- ChartBuilder builder = ChartBuilderFactory.createChartBuilder(ChartType.BAR, new SampleSeriesBuilder());
+ ChartBuilder builder = ChartBuilderFactory.createChartBuilder(ChartType.BAR, new SampleSeriesBuilder(SIMPLE_SERIES_ROWS));
assertChartTitlesAndWriteToFile(builder);
}
@@ -116,36 +131,47 @@ public class ChartProductionTest extends TestCase
assertChartTitlesAndWriteToFile(builder);
}
- public void testStatiscticalBarChart() throws Exception
+ public void testXYLineChartWithColourAndWidth() throws Exception
+ {
+ when(_seriesDefinition.getStrokeWidth()).thenReturn(3);
+ when(_seriesDefinition.getSeriesColourName()).thenReturn("dark_orange");
+
+ ChartBuilder builder = ChartBuilderFactory.createChartBuilder(ChartType.XYLINE, new SampleSeriesBuilder());
+ assertChartTitlesAndWriteToFile(builder);
+ }
+
+ public void testTimeSeriesLineChart() throws Exception
{
+ SeriesRow[] timelineSeriesRows = new SeriesRow[]
+ {
+ new SeriesRow(new Date(1), 1d),
+ new SeriesRow(new Date(2), 2d),
+ new SeriesRow(new Date(3), 3d),
+ new SeriesRow(new Date(4), 4d),
+ new SeriesRow(new Date(5), 5d),
+ new SeriesRow(new Date(6), 6d),
+ };
+ ChartBuilder builder = ChartBuilderFactory.createChartBuilder(
+ ChartType.TIMELINE,
+ new SampleSeriesBuilder(timelineSeriesRows));
+
+ assertChartTitlesAndWriteToFile(builder);
+ }
+
+ public void testStatisticalBarChart() throws Exception
+ {
+ SeriesRow[] statisticalSeriesRows = new SeriesRow[]
+ {
+ new SeriesRow(1d, 1d, 0.5d),
+ new SeriesRow(2d, 2d, 0.4d),
+ new SeriesRow(4d, 4d, 0.3d),
+ new SeriesRow(5d, 5d, 0.2d),
+ new SeriesRow(6d, 6d, 0.1d)
+ };
+
ChartBuilder builder = ChartBuilderFactory.createChartBuilder(
ChartType.STATISTICAL_BAR,
- new SeriesBuilder()
- {
- private SeriesBuilderCallback _dataPointCallback;
-
- @Override
- public void build(List<SeriesDefinition> seriesDefinitions)
- {
- for (Iterator<SeriesDefinition> iterator = seriesDefinitions.iterator(); iterator.hasNext();)
- {
- SeriesDefinition seriesDefinition = iterator.next();
- _dataPointCallback.beginSeries(seriesDefinition);
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{1d, 1d, 0.5d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{2d, 2d, 0.4d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{4d, 4d, 0.3d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{5d, 5d, 0.2d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{6d, 3d, 0.1d});
- _dataPointCallback.endSeries(seriesDefinition);
- }
- }
-
- @Override
- public void setSeriesBuilderCallback(SeriesBuilderCallback dataPointCallback)
- {
- _dataPointCallback = dataPointCallback;
- }
- });
+ new SampleSeriesBuilder(statisticalSeriesRows));
assertChartTitlesAndWriteToFile(builder);
}
@@ -166,33 +192,43 @@ public class ChartProductionTest extends TestCase
assertEquals(1, chart.getCategoryPlot().getDatasetCount());
}
- _writer.writeChartToFileSystem(chart, getName());
+ _writer.writeChartToFileSystem(chart, _chartingDefinition);
}
private class SampleSeriesBuilder implements SeriesBuilder
{
- private SeriesBuilderCallback _dataPointCallback;
+ private DatasetHolder _datasetHolder;
+ private SeriesRow[] _sampleSeriesRows = SIMPLE_SERIES_ROWS;
+
+ public SampleSeriesBuilder()
+ {
+ }
+
+ public SampleSeriesBuilder(SeriesRow[] sampleSeriesRows)
+ {
+ _sampleSeriesRows = sampleSeriesRows;
+ }
@Override
- public void build(List<SeriesDefinition> seriesDefinitions)
+ public Dataset build(List<SeriesDefinition> seriesDefinitions)
{
for (Iterator<SeriesDefinition> iterator = seriesDefinitions.iterator(); iterator.hasNext();)
{
SeriesDefinition seriesDefinition = iterator.next();
- _dataPointCallback.beginSeries(seriesDefinition);
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{1d, 1d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{2d, 2d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{4d, 4d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{5d, 5d});
- _dataPointCallback.addDataPointToSeries(seriesDefinition, new Object[]{6d, 3d});
- _dataPointCallback.endSeries(seriesDefinition);
+ _datasetHolder.beginSeries(seriesDefinition);
+ for(SeriesRow seriesRow : _sampleSeriesRows)
+ {
+ _datasetHolder.addDataPointToSeries(seriesDefinition, seriesRow);
+ }
+ _datasetHolder.endSeries(seriesDefinition);
}
+ return _datasetHolder.getPopulatedDataset();
}
@Override
- public void setSeriesBuilderCallback(SeriesBuilderCallback dataPointCallback)
+ public void setDatasetHolder(DatasetHolder dataPointCallback)
{
- _dataPointCallback = dataPointCallback;
+ _datasetHolder = dataPointCallback;
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactoryTest.java
index 4f143701af..2656c780bb 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ColorFactoryTest.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -18,37 +17,26 @@
* under the License.
*
*/
+package org.apache.qpid.disttest.charting.chartbuilder;
-package org.apache.qpid.qmf;
+import java.awt.Color;
-import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.test.utils.QpidTestCase;
-public abstract class QMFCommand
+public class ColorFactoryTest extends QpidTestCase
{
-
- private final QMFCommandHeader _header;
-
- protected QMFCommand(QMFCommandHeader header)
- {
- _header = header;
- }
-
-
- public void process(final VirtualHost virtualHost, final ServerMessage message)
+ public void testBlue()
{
- throw new UnsupportedOperationException();
+ assertEquals(Color.blue, ColorFactory.toColour("blue"));
+ assertEquals(Color.blue, ColorFactory.toColour("BLUE"));
+ assertEquals(Color.blue, ColorFactory.toColour("Blue"));
}
- public void encode(BBEncoder encoder)
+ public void testDarkBlue()
{
- _header.encode(encoder);
-
+ assertEquals(Color.blue.darker(), ColorFactory.toColour("dark_blue"));
+ assertEquals(Color.blue.darker(), ColorFactory.toColour("DARK_BLUE"));
+ assertEquals(Color.blue.darker(), ColorFactory.toColour("Dark_Blue"));
}
- public QMFCommandHeader getHeader()
- {
- return _header;
- }
-}
+} \ No newline at end of file
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesBuilderCallbackTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesBuilderCallbackTest.java
new file mode 100644
index 0000000000..cb89511389
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/TimeSeriesBuilderCallbackTest.java
@@ -0,0 +1,72 @@
+package org.apache.qpid.disttest.charting.chartbuilder;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.apache.qpid.disttest.charting.seriesbuilder.SeriesRow;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.data.time.TimeSeriesDataItem;
+
+public class TimeSeriesBuilderCallbackTest extends QpidTestCase
+{
+ private static final String SERIES_LEGEND = "mySeriesLegend";
+
+ private static final int NUMBER_OF_DATA_POINTS = 3;
+
+ private Date[] _dates;
+ private double[] _values;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+
+ calendar.set(2013, Calendar.JANUARY, 1);
+ Date jan1 = calendar.getTime();
+
+ calendar.set(2013, Calendar.JANUARY, 2);
+ Date jan2 = calendar.getTime();
+
+ calendar.set(2013, Calendar.JANUARY, 3);
+ Date jan3 = calendar.getTime();
+
+ _dates = new Date[] {jan1, jan2, jan3};
+ _values = new double[] {2.0, 4.0, 8.0};
+ }
+
+
+ public void testAddPointToSeries()
+ {
+ TimeSeriesHolder timeSeriesHolder = new TimeSeriesHolder();
+
+ SeriesDefinition seriesDefinition = mock(SeriesDefinition.class);
+ when(seriesDefinition.getSeriesLegend()).thenReturn(SERIES_LEGEND);
+
+ timeSeriesHolder.beginSeries(seriesDefinition);
+
+ timeSeriesHolder.addDataPointToSeries(seriesDefinition, new SeriesRow(_dates[0], _values[0]));
+ timeSeriesHolder.addDataPointToSeries(seriesDefinition, new SeriesRow(_dates[1], _values[1]));
+ timeSeriesHolder.addDataPointToSeries(seriesDefinition, new SeriesRow(_dates[2], _values[2]));
+
+ timeSeriesHolder.endSeries(seriesDefinition);
+
+ TimeSeriesCollection timeSeriesCollection = (TimeSeriesCollection) timeSeriesHolder.getPopulatedDataset();
+
+ TimeSeries actualTimeSeries = timeSeriesCollection.getSeries(SERIES_LEGEND);
+ for(int i = 0; i < NUMBER_OF_DATA_POINTS; i++)
+ {
+ TimeSeriesDataItem dataItem0 = actualTimeSeries.getDataItem(i);
+ assertEquals(_dates[i].getTime(), dataItem0.getPeriod().getMiddleMillisecond());
+ assertEquals(_values[i], dataItem0.getValue());
+ }
+ }
+
+}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java
index 5371f3df45..e4b4d4d272 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java
@@ -19,8 +19,9 @@
*/
package org.apache.qpid.disttest.charting.definition;
-import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.CHART_TITLE_KEY;
+import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.CHART_DESCRIPTION_KEY;
import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.CHART_SUBTITLE_KEY;
+import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.CHART_TITLE_KEY;
import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.CHART_TYPE_KEY;
import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.XAXIS_TITLE_KEY;
import static org.apache.qpid.disttest.charting.definition.ChartingDefinitionCreator.YAXIS_TITLE_KEY;
@@ -31,15 +32,15 @@ import java.io.FileWriter;
import java.util.List;
import java.util.Properties;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.charting.ChartType;
import org.apache.qpid.disttest.charting.ChartingException;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class ChartingDefinitionCreatorTest extends TestCase
+public class ChartingDefinitionCreatorTest extends QpidTestCase
{
private static final String TEST_CHART_TITLE = "CHART_TITLE";
private static final String TEST_CHART_SUBTITLE = "CHART_SUBTITLE";
+ private static final String TEST_CHART_DESCRIPTION = "CHART_DESCRIPTION";
private static final String TEST_XAXIS_TITLE = "XAXIS_TITLE";
private static final String TEST_YAXIS_TITLE = "YAXIS_TITLE";
private static final ChartType TEST_CHART_TYPE = ChartType.LINE;
@@ -86,6 +87,7 @@ public class ChartingDefinitionCreatorTest extends TestCase
ChartingDefinition definition1 = definitions.get(0);
assertEquals(TEST_CHART_TITLE, definition1.getChartTitle());
assertEquals(TEST_CHART_SUBTITLE, definition1.getChartSubtitle());
+ assertEquals(TEST_CHART_DESCRIPTION, definition1.getChartDescription());
assertEquals(TEST_XAXIS_TITLE, definition1.getXAxisTitle());
assertEquals(TEST_YAXIS_TITLE, definition1.getYAxisTitle());
assertEquals(TEST_CHART_TYPE, definition1.getChartType());
@@ -93,7 +95,7 @@ public class ChartingDefinitionCreatorTest extends TestCase
String stemOnly = testDefFile.getName().replaceFirst("\\.chartdef", "");
assertEquals(stemOnly, definition1.getChartStemName());
- final List<SeriesDefinition> seriesDefinitions = definition1.getSeries();
+ final List<SeriesDefinition> seriesDefinitions = definition1.getSeriesDefinitions();
assertEquals(1, seriesDefinitions.size());
SeriesDefinition seriesDefinition = seriesDefinitions.get(0);
assertEquals(TEST_SERIES_SELECT_STATEMENT, seriesDefinition.getSeriesStatement());
@@ -125,6 +127,7 @@ public class ChartingDefinitionCreatorTest extends TestCase
props.setProperty(CHART_TYPE_KEY, TEST_CHART_TYPE.name());
props.setProperty(CHART_TITLE_KEY, TEST_CHART_TITLE);
props.setProperty(CHART_SUBTITLE_KEY, TEST_CHART_SUBTITLE);
+ props.setProperty(CHART_DESCRIPTION_KEY, TEST_CHART_DESCRIPTION);
props.setProperty(XAXIS_TITLE_KEY, TEST_XAXIS_TITLE);
props.setProperty(YAXIS_TITLE_KEY, TEST_YAXIS_TITLE);
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java
index 2187793c53..ef605024cc 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java
@@ -19,20 +19,24 @@
*/
package org.apache.qpid.disttest.charting.definition;
+import static org.apache.qpid.disttest.charting.definition.SeriesDefinitionCreator.SERIES_COLOUR_NAME_FORMAT;
import static org.apache.qpid.disttest.charting.definition.SeriesDefinitionCreator.SERIES_DIRECTORY_KEY_FORMAT;
import static org.apache.qpid.disttest.charting.definition.SeriesDefinitionCreator.SERIES_LEGEND_KEY_FORMAT;
import static org.apache.qpid.disttest.charting.definition.SeriesDefinitionCreator.SERIES_STATEMENT_KEY_FORMAT;
+import static org.apache.qpid.disttest.charting.definition.SeriesDefinitionCreator.SERIES_STROKE_WIDTH_FORMAT;
import java.util.List;
import java.util.Properties;
-import junit.framework.TestCase;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class SeriesDefinitionCreatorTest extends TestCase
+public class SeriesDefinitionCreatorTest extends QpidTestCase
{
private static final String TEST_SERIES_1_SELECT_STATEMENT = "SERIES_1_SELECT_STATEMENT";
private static final String TEST_SERIES_1_LEGEND = "SERIES_1_LEGEND";
private static final String TEST_SERIES_1_DIR = "SERIES_1_DIR";
+ private static final String TEST_SERIES_1_COLOUR_NAME = "seriesColourName";
+ private static final Integer TEST_SERIES_1_STROKE_WIDTH = 1;;
private static final String TEST_SERIES_1_DIR_WITH_SYSPROP = "${java.io.tmpdir}/mydir";
@@ -52,7 +56,7 @@ public class SeriesDefinitionCreatorTest extends TestCase
public void testOneSeriesDefinition() throws Exception
{
- createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR);
+ createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR, TEST_SERIES_1_COLOUR_NAME, TEST_SERIES_1_STROKE_WIDTH);
List<SeriesDefinition> definitions = _seriesDefinitionLoader.createFromProperties(_properties);
assertEquals(1, definitions.size());
@@ -61,12 +65,14 @@ public class SeriesDefinitionCreatorTest extends TestCase
assertEquals(TEST_SERIES_1_SELECT_STATEMENT, definition.getSeriesStatement());
assertEquals(TEST_SERIES_1_LEGEND, definition.getSeriesLegend());
assertEquals(TEST_SERIES_1_DIR, definition.getSeriesDirectory());
+ assertEquals(TEST_SERIES_1_COLOUR_NAME, definition.getSeriesColourName());
+ assertEquals(TEST_SERIES_1_STROKE_WIDTH, definition.getStrokeWidth());
}
public void testTwoSeriesDefinitions() throws Exception
{
- createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR);
- createTestProperties(2, TEST_SERIES_2_SELECT_STATEMENT, TEST_SERIES_2_LEGEND, TEST_SERIES_2_DIR);
+ createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR, TEST_SERIES_1_COLOUR_NAME, TEST_SERIES_1_STROKE_WIDTH);
+ createTestProperties(2, TEST_SERIES_2_SELECT_STATEMENT, TEST_SERIES_2_LEGEND, TEST_SERIES_2_DIR, null, null);
List<SeriesDefinition> definitions = _seriesDefinitionLoader.createFromProperties(_properties);
assertEquals(2, definitions.size());
@@ -84,8 +90,8 @@ public class SeriesDefinitionCreatorTest extends TestCase
public void testNonSequentialSeriesDefinitionsIgnored() throws Exception
{
- createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR);
- createTestProperties(3, TEST_SERIES_2_SELECT_STATEMENT, TEST_SERIES_2_LEGEND, TEST_SERIES_2_DIR);
+ createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR, TEST_SERIES_1_COLOUR_NAME, TEST_SERIES_1_STROKE_WIDTH);
+ createTestProperties(3, TEST_SERIES_2_SELECT_STATEMENT, TEST_SERIES_2_LEGEND, TEST_SERIES_2_DIR, null, null);
List<SeriesDefinition> definitions = _seriesDefinitionLoader.createFromProperties(_properties);
assertEquals(1, definitions.size());
@@ -94,7 +100,7 @@ public class SeriesDefinitionCreatorTest extends TestCase
public void testSeriesDirectorySubstitution() throws Exception
{
final String tmpDir = System.getProperty("java.io.tmpdir");
- createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR_WITH_SYSPROP);
+ createTestProperties(1, TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, TEST_SERIES_1_DIR_WITH_SYSPROP, null, null);
List<SeriesDefinition> definitions = _seriesDefinitionLoader.createFromProperties(_properties);
assertEquals(1, definitions.size());
@@ -103,11 +109,19 @@ public class SeriesDefinitionCreatorTest extends TestCase
assertTrue(seriesDefinition1.getSeriesDirectory().startsWith(tmpDir));
}
- private void createTestProperties(int index, String selectStatement, String seriesLegend, String seriesDir) throws Exception
+ private void createTestProperties(int index, String selectStatement, String seriesLegend, String seriesDir, String seriesColourName, Integer seriesStrokeWidth) throws Exception
{
_properties.setProperty(String.format(SERIES_STATEMENT_KEY_FORMAT, index), selectStatement);
_properties.setProperty(String.format(SERIES_LEGEND_KEY_FORMAT, index), seriesLegend);
_properties.setProperty(String.format(SERIES_DIRECTORY_KEY_FORMAT, index), seriesDir);
+ if (seriesColourName != null)
+ {
+ _properties.setProperty(String.format(SERIES_COLOUR_NAME_FORMAT, index), seriesColourName);
+ }
+ if (seriesStrokeWidth != null)
+ {
+ _properties.setProperty(String.format(SERIES_STROKE_WIDTH_FORMAT, index), seriesStrokeWidth.toString());
+ }
}
}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilderTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilderTest.java
index 5148a25bec..b6b4dbe56b 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcCsvSeriesBuilderTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcSeriesBuilderTest.java
@@ -21,6 +21,7 @@ package org.apache.qpid.disttest.charting.seriesbuilder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.BufferedWriter;
import java.io.File;
@@ -28,18 +29,17 @@ import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Collections;
-import junit.framework.TestCase;
-
import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
-import org.apache.qpid.disttest.charting.seriesbuilder.JdbcCsvSeriesBuilder;
+import org.apache.qpid.test.utils.QpidTestCase;
-public class JdbcCsvSeriesBuilderTest extends TestCase
+public class JdbcSeriesBuilderTest extends QpidTestCase
{
private static final String TEST_SERIES_1_SELECT_STATEMENT = "SELECT A, B FROM test";
private static final String TEST_SERIES_1_LEGEND = "SERIES_1_LEGEND";
+ private static final String TEST_SERIES1_COLOUR_NAME = "blue";
+ private static final Integer TEST_SERIES1_STROKE_WIDTH = 3;
- private SeriesBuilderCallback _seriesWalkerCallback = mock(SeriesBuilderCallback.class);
- private JdbcCsvSeriesBuilder _seriesBuilder = new JdbcCsvSeriesBuilder();
+ private DatasetHolder _seriesWalkerCallback = mock(DatasetHolder.class);
private File _testTempDir;
@@ -47,21 +47,25 @@ public class JdbcCsvSeriesBuilderTest extends TestCase
protected void setUp() throws Exception
{
super.setUp();
- _seriesBuilder.setSeriesBuilderCallback(_seriesWalkerCallback);
+ when(_seriesWalkerCallback.getNumberOfDimensions()).thenReturn(2);
_testTempDir = createTestTemporaryDirectory();
+ createTestCsvIn(_testTempDir);
}
public void testBuildOneSeries() throws Exception
{
- createTestCsvIn(_testTempDir);
SeriesDefinition seriesDefinition = createTestSeriesDefinition();
- _seriesBuilder.build(Collections.singletonList(seriesDefinition));
+ JdbcSeriesBuilder seriesBuilder = new JdbcSeriesBuilder("org.relique.jdbc.csv.CsvDriver", null);
+
+ seriesBuilder.setDatasetHolder(_seriesWalkerCallback);
+
+ seriesBuilder.build(Collections.singletonList(seriesDefinition));
verify(_seriesWalkerCallback).beginSeries(seriesDefinition);
- verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new Object[]{"elephant", "2"});
- verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new Object[]{"lion", "3"});
- verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new Object[]{"tiger", "4"});
+ verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new SeriesRow("elephant", "2"));
+ verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new SeriesRow("lion", "3"));
+ verify(_seriesWalkerCallback).addDataPointToSeries(seriesDefinition, new SeriesRow("tiger", "4"));
verify(_seriesWalkerCallback).endSeries(seriesDefinition);
}
@@ -79,7 +83,12 @@ public class JdbcCsvSeriesBuilderTest extends TestCase
private SeriesDefinition createTestSeriesDefinition()
{
- SeriesDefinition definition = new SeriesDefinition(TEST_SERIES_1_SELECT_STATEMENT, TEST_SERIES_1_LEGEND, _testTempDir.getAbsolutePath());
+ SeriesDefinition definition = new SeriesDefinition(
+ TEST_SERIES_1_SELECT_STATEMENT,
+ TEST_SERIES_1_LEGEND,
+ _testTempDir.getAbsolutePath(),
+ TEST_SERIES1_COLOUR_NAME,
+ TEST_SERIES1_STROKE_WIDTH);
return definition;
}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGeneratorTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGeneratorTest.java
new file mode 100644
index 0000000000..d53d0ccfe1
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/JdbcUrlGeneratorTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.disttest.charting.seriesbuilder;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.qpid.disttest.charting.definition.SeriesDefinition;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class JdbcUrlGeneratorTest extends QpidTestCase
+{
+ public void testGetJdbcUrlWithoutProvidingAUrlReturnsCsvUrlWithCorrectDirectory()
+ {
+ JdbcUrlGenerator jdbcUrlGenerator = new JdbcUrlGenerator(null);
+ SeriesDefinition seriesDefinition = mock(SeriesDefinition.class);
+ when(seriesDefinition.getSeriesDirectory()).thenReturn("mydir");
+
+ String jdbcUrl = jdbcUrlGenerator.getJdbcUrl(seriesDefinition);
+
+ assertEquals("jdbc:relique:csv:mydir", jdbcUrl);
+ }
+
+ public void testGetJdbcUrlReturnsProvidedUrl()
+ {
+ String urlTemplate = "urlTemplate";
+ JdbcUrlGenerator jdbcUrlGenerator = new JdbcUrlGenerator(urlTemplate);
+ SeriesDefinition seriesDefinition = mock(SeriesDefinition.class);
+
+ String jdbcUrl = jdbcUrlGenerator.getJdbcUrl(seriesDefinition);
+
+ assertEquals(urlTemplate, jdbcUrl);
+ }
+
+ public void testGetJdbcUrlThrowsExceptionIfUrlProvidedAndSeriesDirectorySpecified()
+ {
+ String urlTemplate = "urlTemplate";
+ JdbcUrlGenerator jdbcUrlGenerator = new JdbcUrlGenerator(urlTemplate);
+ SeriesDefinition seriesDefinition = mock(SeriesDefinition.class);
+ when(seriesDefinition.getSeriesDirectory()).thenReturn("mydir");
+
+ try
+ {
+ jdbcUrlGenerator.getJdbcUrl(seriesDefinition);
+ fail("Expected exception not thrown");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+
+ public void testGetJdbcUrlThrowsExceptionWithoutAProvidedUrlOrSeriesDirectory()
+ {
+ JdbcUrlGenerator jdbcUrlGenerator = new JdbcUrlGenerator(null);
+ SeriesDefinition seriesDefinition = mock(SeriesDefinition.class);
+ when(seriesDefinition.getSeriesDirectory()).thenReturn(null);
+
+ try
+ {
+ jdbcUrlGenerator.getJdbcUrl(seriesDefinition);
+ fail("Expected exception not thrown");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRowTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRowTest.java
new file mode 100644
index 0000000000..064971aa35
--- /dev/null
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/seriesbuilder/SeriesRowTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.disttest.charting.seriesbuilder;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class SeriesRowTest extends QpidTestCase
+{
+ private static final Integer[] PAIR = new Integer[] {10, 11};
+
+ public void testValidSeriesRow()
+ {
+ assertEquals(11, SeriesRow.createValidSeriesRow(2, PAIR).dimension(1));
+ }
+
+ public void testValidSeriesRowThrowsExceptionIfArrayTooSmall()
+ {
+ try
+ {
+ SeriesRow.createValidSeriesRow(1, PAIR);
+ fail("Expected exception not thrown");
+ }
+ catch(IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+
+ public void testDimension()
+ {
+ SeriesRow seriesRow = new SeriesRow(10, 11);
+ assertEquals(10, seriesRow.dimension(0));
+ assertEquals(11, seriesRow.dimension(1));
+ }
+
+ public void testDimensionAsString()
+ {
+ SeriesRow seriesRow = new SeriesRow(10);
+ assertEquals("10", seriesRow.dimensionAsString(0));
+ }
+
+ public void testDimensionAsDouble()
+ {
+ SeriesRow seriesRow = new SeriesRow(10.1);
+ assertEquals(10.1, seriesRow.dimensionAsDouble(0), 0.0);
+ }
+
+}
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/ChartWriterTest.java b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/ChartWriterTest.java
index 0e176d326b..9703c66e1f 100644
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/ChartWriterTest.java
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/ChartWriterTest.java
@@ -20,20 +20,23 @@
*/
package org.apache.qpid.disttest.charting.writer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.Scanner;
-import junit.framework.TestCase;
-
+import org.apache.qpid.disttest.charting.definition.ChartingDefinition;
+import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.test.utils.TestFileUtils;
import org.apache.qpid.util.FileUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
-public class ChartWriterTest extends TestCase
+public class ChartWriterTest extends QpidTestCase
{
private JFreeChart _chart1;
private JFreeChart _chart2;
@@ -59,24 +62,34 @@ public class ChartWriterTest extends TestCase
public void testWriteChartToFileSystem()
{
+ ChartingDefinition chartDef1 = mock(ChartingDefinition.class);
+ when(chartDef1.getChartStemName()).thenReturn("chart1");
+
File chart1File = new File(_chartDir, "chart1.png");
assertFalse("chart1 png should not exist yet", chart1File.exists());
- _writer.writeChartToFileSystem(_chart1, "chart1");
+ _writer.writeChartToFileSystem(_chart1, chartDef1);
assertTrue("chart1 png does not exist", chart1File.exists());
}
public void testWriteHtmlSummaryToFileSystemOverwritingExistingFile() throws Exception
{
+ ChartingDefinition chartDef1 = mock(ChartingDefinition.class);
+ when(chartDef1.getChartStemName()).thenReturn("chart1");
+ when(chartDef1.getChartDescription()).thenReturn("chart description1");
+
+ ChartingDefinition chartDef2 = mock(ChartingDefinition.class);
+ when(chartDef2.getChartStemName()).thenReturn("chart2");
+
File summaryFile = new File(_chartDir, ChartWriter.SUMMARY_FILE_NAME);
writeDummyContentToSummaryFileToEnsureItGetsOverwritten(summaryFile);
- _writer.writeChartToFileSystem(_chart2, "chart2");
- _writer.writeChartToFileSystem(_chart1, "chart1");
+ _writer.writeChartToFileSystem(_chart2, chartDef2);
+ _writer.writeChartToFileSystem(_chart1, chartDef1);
- _writer.writeHtmlSummaryToFileSystem();
+ _writer.writeHtmlSummaryToFileSystem("Performance Charts");
InputStream expectedSummaryFileInputStream = getClass().getResourceAsStream("expected-chart-summary.html");
String expectedSummaryContent = new Scanner(expectedSummaryFileInputStream).useDelimiter("\\A").next();
@@ -87,11 +100,15 @@ public class ChartWriterTest extends TestCase
public void testWriteHtmlSummaryToFileSystemDoesNothingIfLessThanTwoCharts()
{
+ ChartingDefinition chartDef1 = mock(ChartingDefinition.class);
+ when(chartDef1.getChartStemName()).thenReturn("chart1");
+ when(chartDef1.getChartDescription()).thenReturn("chart description1");
+
File summaryFile = new File(_chartDir, ChartWriter.SUMMARY_FILE_NAME);
- _writer.writeChartToFileSystem(_chart1, "chart1");
+ _writer.writeChartToFileSystem(_chart1, chartDef1);
- _writer.writeHtmlSummaryToFileSystem();
+ _writer.writeHtmlSummaryToFileSystem("Performance Charts");
assertFalse("Only one chart generated so no summary file should have been written",
summaryFile.exists());
diff --git a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/expected-chart-summary.html b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/expected-chart-summary.html
index 89c508a77e..e7dadcb05b 100755
--- a/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/expected-chart-summary.html
+++ b/java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/writer/expected-chart-summary.html
@@ -1,15 +1,21 @@
<html>
<head>
<title>Performance Charts</title>
+ <style type='text/css'>figure { float: left; display: table; width: 87px;}</style>
</head>
<body>
<ul>
<li><a href='#chart1.png'>chart1.png</a></li>
<li><a href='#chart2.png'>chart2.png</a></li>
</ul>
- <a name='chart1.png'/>
- <img src='chart1.png'/>
- <a name='chart2.png'/>
- <img src='chart2.png'/>
+ <figure>
+ <a name='chart1.png'/>
+ <img src='chart1.png'/>
+ <figcaption>chart description1</figcaption>
+ </figure>
+ <figure>
+ <a name='chart2.png'/>
+ <img src='chart2.png'/>
+ </figure>
</body>
</html> \ No newline at end of file
diff --git a/java/systests/build.xml b/java/systests/build.xml
index 57337bdc55..dee73b2e1e 100644
--- a/java/systests/build.xml
+++ b/java/systests/build.xml
@@ -32,7 +32,9 @@ nn - or more contributor license agreements. See the NOTICE file
</or>
</condition>
- <property name="module.depends" value="client management/common broker broker/test common amqp-1-0-common common/test jca ${systests.optional.depends}"/>
+ <!-- The jca module is unusual in that it produces a jar with the name ra rather than jca. Unfortunately this means we
+ need to add both jca (finds jca's jar dependencies) and ra (to find the qpid-ra jar file itself). -->
+ <property name="module.depends" value="client management/common broker broker/tests common amqp-1-0-common common/tests jca ra broker-plugins/access-control broker-plugins/management-http broker-plugins/management-jmx ${systests.optional.depends}"/>
<property name="module.test.src" location="src/main/java"/>
<property name="module.test.excludes"
value="**/DropInTest.java,**/TestClientControlledTest.java"/>
diff --git a/java/systests/etc/config-systests-derby.xml b/java/systests/etc/config-systests-derby.xml
deleted file mode 100644
index 21a7a8cabe..0000000000
--- a/java/systests/etc/config-systests-derby.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-derby-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- </override>
-</configuration>
diff --git a/java/systests/etc/config-systests-firewall-2.xml b/java/systests/etc/config-systests-firewall-2.xml
deleted file mode 100644
index 5167d88f12..0000000000
--- a/java/systests/etc/config-systests-firewall-2.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disasble Non-SSL port set sslOnly to true -->
- <ssl>
- <enabled>false</enabled>
- <port>8672</port>
- <sslOnly>false</sslOnly>
- <keyStorePath>/path/to/keystore.ks</keyStorePath>
- <keyStorePassword>keystorepass</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>false</enabled>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <msg-auth>false</msg-auth>
-
- <firewall default-action="deny"/>
- </security>
-
- <virtualhosts>${conf}/virtualhosts-systests-firewall-2.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
-
-
diff --git a/java/systests/etc/config-systests-firewall-3.xml b/java/systests/etc/config-systests-firewall-3.xml
deleted file mode 100644
index 2bcbf53a39..0000000000
--- a/java/systests/etc/config-systests-firewall-3.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disable Non-SSL port set sslOnly to true -->
- <ssl>
- <enabled>false</enabled>
- <port>8672</port>
- <sslOnly>false</sslOnly>
- <keyStorePath>/path/to/keystore.ks</keyStorePath>
- <keyStorePassword>keystorepass</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>false</enabled>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <msg-auth>false</msg-auth>
-
- <firewall default-action="deny">
- <rule access="allow" network="127.0.0.1"/>
- </firewall>
- </security>
-
- <virtualhosts>${conf}/virtualhosts-systests-firewall-3.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
-
-
diff --git a/java/systests/etc/config-systests-firewall-settings.xml b/java/systests/etc/config-systests-firewall-settings.xml
deleted file mode 100644
index aa73be0646..0000000000
--- a/java/systests/etc/config-systests-firewall-settings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <security>
- <firewall>
- <rule access="allow" network="127.0.0.1"/>
- </firewall>
- </security>
-
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-firewall.xml</virtualhosts>
-</broker>
diff --git a/java/systests/etc/config-systests-firewall.xml b/java/systests/etc/config-systests-firewall.xml
deleted file mode 100644
index a884a39614..0000000000
--- a/java/systests/etc/config-systests-firewall.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_FIREWALL_CONFIG_SETTINGS}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-firewall-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- </override>
-</configuration>
diff --git a/java/systests/etc/config-systests-settings.xml b/java/systests/etc/config-systests-settings.xml
deleted file mode 100644
index 0b65ad83c3..0000000000
--- a/java/systests/etc/config-systests-settings.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
-
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
-
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disable Non-SSL port set sslOnly to true -->
- <ssl>
- <port>15671</port>
- <enabled>false</enabled>
- <sslOnly>false</sslOnly>
- <keyStorePath>${QPID_HOME}/../test-profiles/test_resources/ssl/java_broker_keystore.jks</keyStorePath>
- <keyStorePassword>password</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>false</enabled>
- <jmxport>
- <registryServer>8999</registryServer>
- <!--
- If unspecified, connectorServer defaults to 100 + registryServer port.
- <connectorServer>9099</connectionServer>
- -->
- </jmxport>
- <ssl>
- <enabled>false</enabled>
- <keyStorePath>${QPID_HOME}/../test-profiles/test_resources/ssl/java_broker_keystore.jks</keyStorePath>
- <keyStorePassword>password</keyStorePassword>
- </ssl>
- <http>
- <enabled>false</enabled>
- </http>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <!-- By default, all authenticated users have permissions to perform all actions -->
-
- <!-- ACL Example
- This example illustrates securing the both Management (JMX) and Messaging.
- <acl>${conf}/broker_example.acl</acl>
- -->
-
- <msg-auth>false</msg-auth>
- </security>
-
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
diff --git a/java/systests/etc/config-systests.json b/java/systests/etc/config-systests.json
new file mode 100644
index 0000000000..a5b85a2050
--- /dev/null
+++ b/java/systests/etc/config-systests.json
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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.
+ *
+ */
+{
+ "name": "QpidBroker",
+ "defaultAuthenticationProvider" : "plain",
+ "defaultVirtualHost" : "test",
+ "keyStorePath": "${QPID_HOME}/../test-profiles/test_resources/ssl/java_broker_keystore.jks",
+ "keyStorePassword": "password",
+ "trustStorePath": "${QPID_HOME}/../test-profiles/test_resources/ssl/java_client_truststore.jks",
+ "trustStorePassword": "password",
+ "authenticationproviders" : [ {
+ "name" : "plain",
+ "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider",
+ "path" : "${QPID_HOME}/etc/passwd"
+ } ],
+ "ports" : [ {
+ "name" : "amqp",
+ "port" : "${test.port}"
+ }, {
+ "name" : "http",
+ "port" : "${test.hport}",
+ "protocols" : [ "HTTP" ]
+ }, {
+ "name" : "rmi",
+ "port" : "${test.mport}",
+ "protocols" : [ "RMI" ]
+ }, {
+ "name" : "jmx",
+ "port" : "${test.cport}",
+ "protocols" : [ "JMX_RMI" ]
+ }],
+ "virtualhosts" : [ {
+ "name" : "test",
+ "configPath" : "${broker.virtualhosts-config}"
+ } ]
+ /*
+,
+ "plugins" : [ {
+ "pluginType" : "MANAGEMENT-HTTP",
+ "name" : "httpManagement"
+ }, {
+ "pluginType" : "MANAGEMENT-JMX",
+ "name" : "jmxManagement"
+ } ]
+ */
+} \ No newline at end of file
diff --git a/java/systests/etc/groups-systests b/java/systests/etc/groups-systests
new file mode 100644
index 0000000000..e3912ece99
--- /dev/null
+++ b/java/systests/etc/groups-systests
@@ -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.
+#
+
+#
+# To define a group, use the format:
+#
+# <groupname>.users=<user1>,<user2>,...,<usern>
+#
+
+messaging-users.users=guest,client,server
+administrators.users=admin
+webadmins.users=webadmin
+
diff --git a/java/systests/etc/virtualhosts-systests-bdb-settings.xml b/java/systests/etc/virtualhosts-systests-bdb-settings.xml
index ce16523f13..350f05c178 100644
--- a/java/systests/etc/virtualhosts-systests-bdb-settings.xml
+++ b/java/systests/etc/virtualhosts-systests-bdb-settings.xml
@@ -20,37 +20,13 @@
-
-->
<virtualhosts>
- <work>${QPID_WORK}</work>
-
- <virtualhost>
- <name>localhost</name>
- <localhost>
- <store>
- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
- <environment-path>${work}/bdbstore/localhost-store</environment-path>
- </store>
- </localhost>
- </virtualhost>
-
- <virtualhost>
- <name>development</name>
- <development>
- <store>
- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
- <environment-path>${work}/bdbstore/development-store</environment-path>
- </store>
- </development>
- </virtualhost>
-
<virtualhost>
<name>test</name>
<test>
<store>
<class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class>
- <environment-path>${work}/bdbstore/test-store</environment-path>
+ <environment-path>${QPID_WORK}/test-store</environment-path>
</store>
</test>
</virtualhost>
</virtualhosts>
-
-
diff --git a/java/systests/etc/virtualhosts-systests-derby-mem-settings.xml b/java/systests/etc/virtualhosts-systests-derby-mem-settings.xml
index 74189ad5e9..4e28f6d330 100644
--- a/java/systests/etc/virtualhosts-systests-derby-mem-settings.xml
+++ b/java/systests/etc/virtualhosts-systests-derby-mem-settings.xml
@@ -20,35 +20,12 @@
-
-->
<virtualhosts>
- <directory>${QPID_HOME}/virtualhosts</directory>
- <default>test</default>
-
- <virtualhost>
- <localhost>
- <store>
- <factoryclass>org.apache.qpid.server.store.derby.DerbyMessageStoreFactory</factoryclass>
- <environment-path>:memory:</environment-path>
- </store>
- </localhost>
- </virtualhost>
-
- <virtualhost>
- <development>
- <store>
- <factoryclass>org.apache.qpid.server.store.derby.DerbyMessageStoreFactory</factoryclass>
- <environment-path>:memory:</environment-path>
- </store>
- </development>
- </virtualhost>
-
<virtualhost>
<test>
<store>
- <factoryclass>org.apache.qpid.server.store.derby.DerbyMessageStoreFactory</factoryclass>
+ <class>org.apache.qpid.server.store.derby.DerbyMessageStore</class>
<environment-path>:memory:</environment-path>
</store>
</test>
</virtualhost>
</virtualhosts>
-
-
diff --git a/java/systests/etc/virtualhosts-systests-derby-settings.xml b/java/systests/etc/virtualhosts-systests-derby-settings.xml
index 08a40ca812..f9cc3d2336 100644
--- a/java/systests/etc/virtualhosts-systests-derby-settings.xml
+++ b/java/systests/etc/virtualhosts-systests-derby-settings.xml
@@ -20,35 +20,12 @@
-
-->
<virtualhosts>
- <directory>${QPID_HOME}/virtualhosts</directory>
- <default>test</default>
-
- <virtualhost>
- <localhost>
- <store>
- <class>org.apache.qpid.server.store.derby.DerbyMessageStore</class>
- <environment-path>${QPID_WORK}/derbyDB/localhost-store</environment-path>
- </store>
- </localhost>
- </virtualhost>
-
- <virtualhost>
- <development>
- <store>
- <class>org.apache.qpid.server.store.derby.DerbyMessageStore</class>
- <environment-path>${QPID_WORK}/derbyDB/development-store</environment-path>
- </store>
- </development>
- </virtualhost>
-
<virtualhost>
<test>
<store>
<class>org.apache.qpid.server.store.derby.DerbyMessageStore</class>
- <environment-path>${QPID_WORK}/derbyDB/test-store</environment-path>
+ <environment-path>${QPID_WORK}/test-store</environment-path>
</store>
</test>
</virtualhost>
</virtualhosts>
-
-
diff --git a/java/systests/etc/virtualhosts-systests-settings.xml b/java/systests/etc/virtualhosts-systests-settings.xml
index 0ec16b31ef..5d4ec28b71 100644
--- a/java/systests/etc/virtualhosts-systests-settings.xml
+++ b/java/systests/etc/virtualhosts-systests-settings.xml
@@ -22,136 +22,11 @@
<virtualhosts>
<default>test</default>
<virtualhost>
- <name>localhost</name>
- <localhost>
- <store>
- <class>org.apache.qpid.server.store.MemoryMessageStore</class>
- </store>
-
- <housekeeping>
- <threadCount>2</threadCount>
- <checkPeriod>20000</checkPeriod>
- </housekeeping>
-
- <exchanges>
- <exchange>
- <type>direct</type>
- <name>test.direct</name>
- <durable>true</durable>
- </exchange>
- <exchange>
- <type>topic</type>
- <name>test.topic</name>
- </exchange>
- </exchanges>
- <queues>
- <exchange>amq.direct</exchange>
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 4Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 2Mb -->
- <maximumMessageAge>600000</maximumMessageAge>
- <!-- 10 mins -->
- <maximumMessageCount>50</maximumMessageCount>
- <!-- 50 messages -->
-
- <queue>
- <name>queue</name>
- </queue>
- <queue>
- <name>ping</name>
- </queue>
- <queue>
- <name>test-queue</name>
- <test-queue>
- <exchange>test.direct</exchange>
- <durable>true</durable>
- </test-queue>
- </queue>
- <queue>
- <name>test-ping</name>
- <test-ping>
- <exchange>test.direct</exchange>
- </test-ping>
- </queue>
-
- </queues>
- </localhost>
- </virtualhost>
-
-
- <virtualhost>
- <name>development</name>
- <development>
- <store>
- <class>org.apache.qpid.server.store.MemoryMessageStore</class>
- </store>
-
- <queues>
- <minimumAlertRepeatGap>30000</minimumAlertRepeatGap>
- <maximumMessageCount>50</maximumMessageCount>
- <queue>
- <name>queue</name>
- <queue>
- <exchange>amq.direct</exchange>
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 4Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 2Mb -->
- <maximumMessageAge>600000</maximumMessageAge>
- <!-- 10 mins -->
- </queue>
- </queue>
- <queue>
- <name>ping</name>
- <ping>
- <exchange>amq.direct</exchange>
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 4Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 2Mb -->
- <maximumMessageAge>600000</maximumMessageAge>
- <!-- 10 mins -->
- </ping>
- </queue>
- </queues>
- </development>
- </virtualhost>
- <virtualhost>
<name>test</name>
<test>
<store>
<class>org.apache.qpid.server.store.MemoryMessageStore</class>
</store>
-
- <queues>
- <minimumAlertRepeatGap>30000</minimumAlertRepeatGap>
- <maximumMessageCount>50</maximumMessageCount>
- <queue>
- <name>queue</name>
- <queue>
- <exchange>amq.direct</exchange>
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 4Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 2Mb -->
- <maximumMessageAge>600000</maximumMessageAge>
- <!-- 10 mins -->
- </queue>
- </queue>
- <queue>
- <name>ping</name>
- <ping>
- <exchange>amq.direct</exchange>
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 4Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 2Mb -->
- <maximumMessageAge>600000</maximumMessageAge>
- <!-- 10 mins -->
- </ping>
- </queue>
- </queues>
</test>
</virtualhost>
</virtualhosts>
diff --git a/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java b/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
index 6655202067..3025414e4a 100644
--- a/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
@@ -27,7 +27,6 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import javax.jms.Connection;
-import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
@@ -72,10 +71,11 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase
for (int i = start; i < end && !interrupted(); i++)
{
producer.send(session.createTextMessage(Integer.toString(i)));
+ ((AMQSession<?, ?>)session).sync();
}
this._logger.info("Sent " + (end - start) + " messages");
}
- catch (JMSException e)
+ catch (Exception e)
{
throw new RuntimeException(e);
}
@@ -101,7 +101,7 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase
con.start();
}
- public void testPausedOrder() throws Exception
+ public void testMessagesSentByTwoThreadsAreDeliveredInOrder() throws Exception
{
// Setup initial messages
@@ -121,9 +121,9 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase
for (int i = 0; i < numMessages; i++)
{
Message msg = consumer.receive(3000);
- assertNotNull("Message should not be null", msg);
- assertTrue("Message should be a text message", msg instanceof TextMessage);
- assertEquals("Message content does not match expected", Integer.toString(i), ((TextMessage) msg).getText());
+ assertNotNull("Message " + i + " should not be null", msg);
+ assertTrue("Message " + i + " should be a text message", msg instanceof TextMessage);
+ assertEquals("Message content " + i + "does not match expected", Integer.toString(i), ((TextMessage) msg).getText());
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java b/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java
new file mode 100644
index 0000000000..0e01bda8d0
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.client;
+
+import javax.jms.Destination;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class HeartbeatTest extends QpidBrokerTestCase
+{
+ public void testHeartbeats() throws Exception
+ {
+ setTestSystemProperty("amqj.heartbeat.delay", "1");
+ AMQConnection conn = (AMQConnection) getConnection();
+ TestListener listener = new TestListener();
+ conn.setHeartbeatListener(listener);
+ conn.start();
+
+ Thread.sleep(2500);
+
+ assertTrue("Too few heartbeats received: "+listener._heartbeatsReceived+" (expected at least 2)", listener._heartbeatsReceived>=2);
+ assertTrue("Too few heartbeats sent "+listener._heartbeatsSent+" (expected at least 2)", listener._heartbeatsSent>=2);
+
+ conn.close();
+ }
+
+ public void testNoHeartbeats() throws Exception
+ {
+ setTestSystemProperty("amqj.heartbeat.delay", "0");
+ AMQConnection conn = (AMQConnection) getConnection();
+ TestListener listener = new TestListener();
+ conn.setHeartbeatListener(listener);
+ conn.start();
+
+ Thread.sleep(2500);
+
+ assertEquals("Heartbeats unexpectedly received", 0, listener._heartbeatsReceived);
+ assertEquals("Heartbeats unexpectedly sent ", 0, listener._heartbeatsSent);
+
+ conn.close();
+ }
+
+ public void testReadOnlyConnectionHeartbeats() throws Exception
+ {
+ setTestSystemProperty("amqj.heartbeat.delay","1");
+ AMQConnection receiveConn = (AMQConnection) getConnection();
+ AMQConnection sendConn = (AMQConnection) getConnection();
+ Destination destination = getTestQueue();
+ TestListener receiveListener = new TestListener();
+ TestListener sendListener = new TestListener();
+
+
+ Session receiveSession = receiveConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ Session senderSession = sendConn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer consumer = receiveSession.createConsumer(destination);
+ MessageProducer producer = senderSession.createProducer(destination);
+
+ receiveConn.setHeartbeatListener(receiveListener);
+ sendConn.setHeartbeatListener(sendListener);
+ receiveConn.start();
+
+ for(int i = 0; i < 5; i++)
+ {
+ producer.send(senderSession.createTextMessage("Msg " + i));
+ Thread.sleep(500);
+ assertNotNull("Expected to received message", consumer.receive(500));
+ }
+
+
+
+ assertTrue("Too few heartbeats sent "+receiveListener._heartbeatsSent+" (expected at least 2)", receiveListener._heartbeatsSent>=2);
+ assertEquals("Unexpected sent at the sender: ",0,sendListener._heartbeatsSent);
+
+ assertTrue("Too few heartbeats received at the sender "+sendListener._heartbeatsReceived+" (expected at least 2)", sendListener._heartbeatsReceived>=2);
+ assertEquals("Unexpected received at the receiver: ",0,receiveListener._heartbeatsReceived);
+
+ receiveConn.close();
+ sendConn.close();
+ }
+
+ private class TestListener implements HeartbeatListener
+ {
+ int _heartbeatsReceived;
+ int _heartbeatsSent;
+ @Override
+ public void heartbeatReceived()
+ {
+ _heartbeatsReceived++;
+ }
+
+ @Override
+ public void heartbeatSent()
+ {
+ _heartbeatsSent++;
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java b/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java
index 4b766864b4..4f8a6ee54a 100644
--- a/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java
@@ -25,11 +25,12 @@ import org.apache.qpid.client.AMQSession;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionListener;
-import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.FailoverPolicy;
import org.apache.qpid.test.utils.FailoverBaseCase;
+import org.apache.qpid.url.URLSyntaxException;
import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
@@ -929,18 +930,22 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
return queue;
}
- private AMQConnection createConnectionWithFailover() throws NamingException, JMSException
+ private AMQConnection createConnectionWithFailover() throws NamingException, JMSException, URLSyntaxException
{
- AMQConnection connection;
- AMQConnectionFactory connectionFactory = (AMQConnectionFactory)getConnectionFactory("default");
- ConnectionURL connectionURL = connectionFactory.getConnectionURL();
- connectionURL.setOption(ConnectionURL.OPTIONS_FAILOVER, "singlebroker");
- connectionURL.setOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE, "2");
- BrokerDetails details = connectionURL.getBrokerDetails(0);
- details.setProperty(BrokerDetails.OPTIONS_RETRY, "200");
- details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "1000");
+ BrokerDetails origBrokerDetails = ((AMQConnectionFactory) getConnectionFactory("default")).getConnectionURL().getBrokerDetails(0);
- connection = (AMQConnection)connectionFactory.createConnection("admin", "admin");
+ String retries = "200";
+ String connectdelay = "1000";
+ String cycleCount = "2";
+
+ String newUrlFormat="amqp://username:password@clientid/test?brokerlist=" +
+ "'tcp://%s:%s?retries='%s'&connectdelay='%s''&failover='singlebroker?cyclecount='%s''";
+
+ String newUrl = String.format(newUrlFormat, origBrokerDetails.getHost(), origBrokerDetails.getPort(),
+ retries, connectdelay, cycleCount);
+
+ ConnectionFactory connectionFactory = new AMQConnectionFactory(newUrl);
+ AMQConnection connection = (AMQConnection) connectionFactory.createConnection("admin", "admin");
connection.setConnectionListener(this);
return connection;
}
@@ -1313,7 +1318,7 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
* @param acknowledgeMode session acknowledge mode
* @throws JMSException
*/
- private void sessionCloseWhileFailoverImpl(int acknowledgeMode) throws JMSException
+ private void sessionCloseWhileFailoverImpl(int acknowledgeMode) throws Exception
{
initDelayedFailover(acknowledgeMode);
@@ -1324,9 +1329,14 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
failBroker(getFailingPort());
+ // wait until failover is started
+ _failoverStarted.await(5, TimeUnit.SECONDS);
+
// test whether session#close blocks while failover is in progress
_consumerSession.close();
+ assertTrue("Failover has not completed yet but session was closed", _failoverComplete.await(5, TimeUnit.SECONDS));
+
assertFailoverException();
}
@@ -1360,10 +1370,8 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
* @param acknowledgeMode session acknowledge mode
* @throws JMSException
*/
- private void browserCloseWhileFailoverImpl(int acknowledgeMode) throws JMSException
+ private void browserCloseWhileFailoverImpl(int acknowledgeMode) throws Exception
{
- setDelayedFailoverPolicy();
-
QueueBrowser browser = prepareQueueBrowser(acknowledgeMode);
@SuppressWarnings("unchecked")
@@ -1373,8 +1381,13 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
failBroker(getFailingPort());
+ // wait until failover is started
+ _failoverStarted.await(5, TimeUnit.SECONDS);
+
browser.close();
+ assertTrue("Failover has not completed yet but browser was closed", _failoverComplete.await(5, TimeUnit.SECONDS));
+
assertFailoverException();
}
@@ -1402,5 +1415,11 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio
((AMQConnection) _connection).setFailoverPolicy(failoverPolicy);
return failoverPolicy;
}
-
+
+ @Override
+ public void failBroker(int port)
+ {
+ killBroker(port);
+ }
+
}
diff --git a/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java b/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java
new file mode 100644
index 0000000000..a0fd093bfe
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java
@@ -0,0 +1,285 @@
+/*
+ *
+ * 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.client.failover;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.jms.ConnectionListener;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestUtils;
+import org.apache.qpid.util.FileUtils;
+
+public class MultipleBrokersFailoverTest extends QpidBrokerTestCase implements ConnectionListener
+{
+ private static final Logger _logger = Logger.getLogger(MultipleBrokersFailoverTest.class);
+
+ private static final String FAILOVER_VIRTUAL_HOST = "failover";
+ private static final String NON_FAILOVER_VIRTUAL_HOST = "nonfailover";
+ private static final String BROKER_PORTION_FORMAT = "tcp://localhost:%d?connectdelay='%d',retries='%d'";
+ private static final int FAILOVER_RETRIES = 1;
+ private static final int FAILOVER_CONNECTDELAY = 1000;
+ private int[] _brokerPorts;
+ private AMQConnectionURL _connectionURL;
+ private Connection _connection;
+ private CountDownLatch _failoverComplete;
+ private CountDownLatch _failoverStarted;
+ private Session _consumerSession;
+ private Destination _destination;
+ private MessageConsumer _consumer;
+ private Session _producerSession;
+ private MessageProducer _producer;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ int numBrokers = 4;
+ int port = findFreePort();
+ _brokerPorts = new int[numBrokers];
+
+ // we need to create 4 brokers:
+ // 1st broker will be running in test JVM and will not have failover host (only tcp connection will established, amqp connection will be closed)
+ // 2d broker will be spawn in separate JVM and should have a failover host (amqp connection should be established)
+ // 3d broker will be spawn in separate JVM and should not have a failover host (only tcp connection will established, amqp connection will be closed)
+ // 4d broker will be spawn in separate JVM and should have a failover host (amqp connection should be established)
+
+ // the test should connect to the second broker first and fail over to the forth broker
+ // after unsuccessful try to establish the connection to the 3d broker
+ for (int i = 0; i < numBrokers; i++)
+ {
+ if (i > 0)
+ {
+ port = getNextAvailable(port + 1);
+ }
+ _brokerPorts[i] = port;
+
+ createBrokerConfiguration(port);
+ String host = null;
+ if (i == 1 || i == _brokerPorts.length - 1)
+ {
+ host = FAILOVER_VIRTUAL_HOST;
+ }
+ else
+ {
+ host = NON_FAILOVER_VIRTUAL_HOST;
+ }
+ createTestVirtualHost(port, host);
+
+ startBroker(port);
+ revertSystemProperties();
+ }
+
+ _connectionURL = new AMQConnectionURL(generateUrlString(numBrokers));
+
+ _connection = getConnection(_connectionURL);
+ ((AMQConnection) _connection).setConnectionListener(this);
+ _failoverComplete = new CountDownLatch(1);
+ _failoverStarted = new CountDownLatch(1);
+ }
+
+ public void startBroker() throws Exception
+ {
+ // noop, prevent the broker startup in super.setUp()
+ }
+
+ private String generateUrlString(int numBrokers)
+ {
+ String baseString = "amqp://guest:guest@test/" + FAILOVER_VIRTUAL_HOST
+ + "?&failover='roundrobin?cyclecount='1''&brokerlist='";
+ StringBuffer buffer = new StringBuffer(baseString);
+
+ for(int i = 0; i< numBrokers ; i++)
+ {
+ if(i != 0)
+ {
+ buffer.append(";");
+ }
+
+ String broker = String.format(BROKER_PORTION_FORMAT, _brokerPorts[i],
+ FAILOVER_CONNECTDELAY, FAILOVER_RETRIES);
+ buffer.append(broker);
+ }
+ buffer.append("'");
+
+ return buffer.toString();
+ }
+
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ for (int i = 0; i < _brokerPorts.length; i++)
+ {
+ if (_brokerPorts[i] > 0)
+ {
+ stopBrokerSafely(_brokerPorts[i]);
+ FileUtils.deleteDirectory(System.getProperty("QPID_WORK") + "/" + getFailingPort());
+ }
+ }
+
+ }
+ }
+
+
+ public void testFailoverOnBrokerKill() throws Exception
+ {
+ init(Session.SESSION_TRANSACTED, true);
+ assertConnectionPort(_brokerPorts[1]);
+
+ assertSendReceive(0);
+
+ killBroker(_brokerPorts[1]);
+
+ awaitForFailoverCompletion(FAILOVER_CONNECTDELAY * _brokerPorts.length * 2);
+ assertEquals("Failover is not started as expected", 0, _failoverStarted.getCount());
+
+ assertSendReceive(2);
+ assertConnectionPort(_brokerPorts[_brokerPorts.length - 1]);
+ }
+
+ public void testFailoverOnBrokerStop() throws Exception
+ {
+ init(Session.SESSION_TRANSACTED, true);
+ assertConnectionPort(_brokerPorts[1]);
+
+ assertSendReceive(0);
+
+ stopBroker(_brokerPorts[1]);
+
+ awaitForFailoverCompletion(FAILOVER_CONNECTDELAY * _brokerPorts.length * 2);
+ assertEquals("Failover is not started as expected", 0, _failoverStarted.getCount());
+
+ assertSendReceive(1);
+ assertConnectionPort(_brokerPorts[_brokerPorts.length - 1]);
+ }
+
+ private void assertConnectionPort(int brokerPort)
+ {
+ int connectionPort = ((AMQConnection)_connection).getActiveBrokerDetails().getPort();
+ assertEquals("Unexpected broker port", brokerPort, connectionPort);
+ }
+
+ private void assertSendReceive(int index) throws JMSException
+ {
+ Message message = createNextMessage(_producerSession, index);
+ _producer.send(message);
+ if (_producerSession.getTransacted())
+ {
+ _producerSession.commit();
+ }
+ Message receivedMessage = _consumer.receive(1000l);
+ assertReceivedMessage(receivedMessage, index);
+ if (_consumerSession.getTransacted())
+ {
+ _consumerSession.commit();
+ }
+ }
+
+ private void awaitForFailoverCompletion(long delay)
+ {
+ _logger.info("Awaiting Failover completion..");
+ try
+ {
+ if (!_failoverComplete.await(delay, TimeUnit.MILLISECONDS))
+ {
+ _logger.warn("Test thread stack:\n\n" + TestUtils.dumpThreads());
+ fail("Failover did not complete");
+ }
+ }
+ catch (InterruptedException e)
+ {
+ fail("Test was interrupted:" + e.getMessage());
+ }
+ }
+
+ private void assertReceivedMessage(Message receivedMessage, int messageIndex)
+ {
+ assertNotNull("Expected message [" + messageIndex + "] is not received!", receivedMessage);
+ assertTrue(
+ "Failure to receive message [" + messageIndex + "], expected TextMessage but received " + receivedMessage,
+ receivedMessage instanceof TextMessage);
+ }
+
+ private void init(int acknowledgeMode, boolean startConnection) throws JMSException
+ {
+ boolean isTransacted = acknowledgeMode == Session.SESSION_TRANSACTED ? true : false;
+
+ _consumerSession = _connection.createSession(isTransacted, acknowledgeMode);
+ _destination = _consumerSession.createQueue(getTestQueueName());
+ _consumer = _consumerSession.createConsumer(_destination);
+
+ if (startConnection)
+ {
+ _connection.start();
+ }
+
+ _producerSession = _connection.createSession(isTransacted, acknowledgeMode);
+ _producer = _producerSession.createProducer(_destination);
+
+ }
+
+ @Override
+ public void bytesSent(long count)
+ {
+ }
+
+ @Override
+ public void bytesReceived(long count)
+ {
+ }
+
+ @Override
+ public boolean preFailover(boolean redirect)
+ {
+ _failoverStarted.countDown();
+ return true;
+ }
+
+ @Override
+ public boolean preResubscribe()
+ {
+ return true;
+ }
+
+ @Override
+ public void failoverComplete()
+ {
+ _failoverComplete.countDown();
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java b/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java
index 39689f5096..884e89fb65 100644
--- a/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java
@@ -20,54 +20,55 @@
*/
package org.apache.qpid.client.ssl;
-import org.apache.qpid.client.AMQConnection;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.client.AMQTestConnection_0_10;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.transport.Connection;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import javax.jms.Connection;
+import javax.jms.JMSException;
import javax.jms.Session;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
public class SSLTest extends QpidBrokerTestCase
{
- private static final String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks";
- private static final String KEYSTORE_PASSWORD = "password";
- private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
- private static final String TRUSTSTORE_PASSWORD = "password";
private static final String CERT_ALIAS_APP1 = "app1";
private static final String CERT_ALIAS_APP2 = "app2";
@Override
protected void setUp() throws Exception
{
- if(isJavaBroker())
- {
- setTestClientSystemProperty("profile.use_ssl", "true");
- setConfigurationProperty("connector.ssl.enabled", "true");
- setConfigurationProperty("connector.ssl.sslOnly", "true");
- setConfigurationProperty("connector.ssl.wantClientAuth", "true");
- }
-
- // set the ssl system properties
- setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
- setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
- setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
- setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
setSystemProperty("javax.net.debug", "ssl");
- super.setUp();
+
+ setSslStoreSystemProperties();
+
+ //We dont call super.setUp, the tests start the broker after deciding
+ //whether to run and then configuring it appropriately
}
public void testCreateSSLConnectionUsingConnectionURLParams() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
- // Clear the ssl system properties
- setSystemProperty("javax.net.ssl.keyStore", null);
- setSystemProperty("javax.net.ssl.keyStorePassword", null);
- setSystemProperty("javax.net.ssl.trustStore", null);
- setSystemProperty("javax.net.ssl.trustStorePassword", null);
+ clearSslStoreSystemProperties();
+ //Start the broker (NEEDing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, true, false);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" +
"?ssl='true'&ssl_verify_hostname='true'" +
"&key_store='%s'&key_store_password='%s'" +
@@ -76,24 +77,75 @@ public class SSLTest extends QpidBrokerTestCase
url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT,
KEYSTORE,KEYSTORE_PASSWORD,TRUSTSTORE,TRUSTSTORE_PASSWORD);
-
- AMQConnection con = new AMQConnection(url);
+
+ Connection con = getConnection(new AMQConnectionURL(url));
assertNotNull("connection should be successful", con);
Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE);
assertNotNull("create session should be successful", ssn);
- }
+ }
+ }
+
+ /**
+ * Create an SSL connection using the SSL system properties for the trust and key store, but using
+ * the {@link ConnectionURL} ssl='true' option to indicate use of SSL at a Connection level,
+ * without specifying anything at the {@link ConnectionURL#OPTIONS_BROKERLIST} level.
+ */
+ public void testSslConnectionOption() throws Exception
+ {
+ if (shouldPerformTest())
+ {
+ //Start the broker (NEEDing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, true, false);
+ super.setUp();
+
+ //Create URL enabling SSL at the connection rather than brokerlist level
+ String url = "amqp://guest:guest@test/?ssl='true'&brokerlist='tcp://localhost:%s'";
+ url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT);
+
+ Connection con = getConnection(new AMQConnectionURL(url));
+ assertNotNull("connection should be successful", con);
+ Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE);
+ assertNotNull("create session should be successful", ssn);
+ }
+ }
+
+ /**
+ * Create an SSL connection using the SSL system properties for the trust and key store, but using
+ * the {@link ConnectionURL} ssl='true' option to indicate use of SSL at a Connection level,
+ * overriding the false setting at the {@link ConnectionURL#OPTIONS_BROKERLIST} level.
+ */
+ public void testSslConnectionOptionOverridesBrokerlistOption() throws Exception
+ {
+ if (shouldPerformTest())
+ {
+ //Start the broker (NEEDing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, true, false);
+ super.setUp();
+
+ //Create URL enabling SSL at the connection, overriding the false at the brokerlist level
+ String url = "amqp://guest:guest@test/?ssl='true'&brokerlist='tcp://localhost:%s?ssl='false''";
+ url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT);
+
+ Connection con = getConnection(new AMQConnectionURL(url));
+ assertNotNull("connection should be successful", con);
+ Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE);
+ assertNotNull("create session should be successful", ssn);
+ }
}
public void testCreateSSLConnectionUsingSystemProperties() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
+ //Start the broker (NEEDing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, true, false);
+ super.setUp();
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s?ssl='true''";
url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT);
- AMQConnection con = new AMQConnection(url);
+ Connection con = getConnection(new AMQConnectionURL(url));
assertNotNull("connection should be successful", con);
Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE);
assertNotNull("create session should be successful", ssn);
@@ -102,14 +154,18 @@ public class SSLTest extends QpidBrokerTestCase
public void testMultipleCertsInSingleStore() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
+ //Start the broker (NEEDing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, true, false);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" +
QpidBrokerTestCase.DEFAULT_SSL_PORT +
"?ssl='true'&ssl_cert_alias='" + CERT_ALIAS_APP1 + "''";
AMQTestConnection_0_10 con = new AMQTestConnection_0_10(url);
- Connection transportCon = con.getConnection();
+ org.apache.qpid.transport.Connection transportCon = con.getConnection();
String userID = transportCon.getSecurityLayer().getUserID();
assertEquals("The correct certificate was not choosen","app1@acme.org",userID);
con.close();
@@ -126,65 +182,82 @@ public class SSLTest extends QpidBrokerTestCase
}
}
- public void testVerifyHostNameWithIncorrectHostname()
+ public void testVerifyHostNameWithIncorrectHostname() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
+ //Start the broker (WANTing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, false, true);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://127.0.0.1:" +
QpidBrokerTestCase.DEFAULT_SSL_PORT +
"?ssl='true'&ssl_verify_hostname='true''";
try
{
- AMQConnection con = new AMQConnection(url);
+ getConnection(new AMQConnectionURL(url));
fail("Hostname verification failed. No exception was thrown");
}
catch (Exception e)
{
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- e.printStackTrace(new PrintStream(bout));
- String strace = bout.toString();
- assertTrue("Correct exception not thrown",strace.contains("SSL hostname verification failed"));
+ verifyExceptionCausesContains(e, "SSL hostname verification failed");
}
-
}
}
+
+ private void verifyExceptionCausesContains(Exception e, String expectedString)
+ {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ e.printStackTrace(new PrintStream(bout));
+ String strace = bout.toString();
+ assertTrue("Correct exception not thrown", strace.contains(expectedString));
+ }
public void testVerifyLocalHost() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
+ //Start the broker (WANTing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, false, true);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" +
QpidBrokerTestCase.DEFAULT_SSL_PORT +
"?ssl='true'&ssl_verify_hostname='true''";
- AMQConnection con = new AMQConnection(url);
- assertNotNull("connection should have been created", con);
+ Connection con = getConnection(new AMQConnectionURL(url));
+ assertNotNull("connection should have been created", con);
}
}
public void testVerifyLocalHostLocalDomain() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
+ //Start the broker (WANTing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, false, true);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost.localdomain:" +
QpidBrokerTestCase.DEFAULT_SSL_PORT +
"?ssl='true'&ssl_verify_hostname='true''";
- AMQConnection con = new AMQConnection(url);
+ Connection con = getConnection(new AMQConnectionURL(url));
assertNotNull("connection should have been created", con);
}
}
public void testCreateSSLConnectionUsingConnectionURLParamsTrustStoreOnly() throws Exception
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (shouldPerformTest())
{
- // Clear the ssl system properties
- setSystemProperty("javax.net.ssl.keyStore", null);
- setSystemProperty("javax.net.ssl.keyStorePassword", null);
- setSystemProperty("javax.net.ssl.trustStore", null);
- setSystemProperty("javax.net.ssl.trustStorePassword", null);
+ clearSslStoreSystemProperties();
+
+ //Start the broker (WANTing client certificate authentication)
+ configureJavaBrokerIfNecessary(true, true, false, true);
+ super.setUp();
+
String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" +
"?ssl='true'&ssl_verify_hostname='true'" +
@@ -193,10 +266,122 @@ public class SSLTest extends QpidBrokerTestCase
url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT, TRUSTSTORE,TRUSTSTORE_PASSWORD);
- AMQConnection con = new AMQConnection(url);
+ Connection con = getConnection(new AMQConnectionURL(url));
assertNotNull("connection should be successful", con);
Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE);
assertNotNull("create session should be successful", ssn);
}
}
+
+ /**
+ * Verifies that when the broker is configured to NEED client certificates,
+ * a client which doesn't supply one fails to connect.
+ */
+ public void testClientCertMissingWhilstNeeding() throws Exception
+ {
+ missingClientCertWhileNeedingOrWantingTestImpl(true, false, false);
+ }
+
+ /**
+ * Verifies that when the broker is configured to WANT client certificates,
+ * a client which doesn't supply one succeeds in connecting.
+ */
+ public void testClientCertMissingWhilstWanting() throws Exception
+ {
+ missingClientCertWhileNeedingOrWantingTestImpl(false, true, true);
+ }
+
+ /**
+ * Verifies that when the broker is configured to WANT and NEED client certificates
+ * that a client which doesn't supply one fails to connect.
+ */
+ public void testClientCertMissingWhilstWantingAndNeeding() throws Exception
+ {
+ missingClientCertWhileNeedingOrWantingTestImpl(true, true, false);
+ }
+
+ private void missingClientCertWhileNeedingOrWantingTestImpl(boolean needClientCerts,
+ boolean wantClientCerts, boolean shouldSucceed) throws Exception
+ {
+ if (shouldPerformTest())
+ {
+ clearSslStoreSystemProperties();
+
+ //Start the broker
+ configureJavaBrokerIfNecessary(true, true, needClientCerts, wantClientCerts);
+ super.setUp();
+
+ String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" +
+ "?ssl='true'&trust_store='%s'&trust_store_password='%s''";
+
+ url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT,TRUSTSTORE,TRUSTSTORE_PASSWORD);
+ try
+ {
+ Connection con = getConnection(new AMQConnectionURL(url));
+ if(!shouldSucceed)
+ {
+ fail("Connection succeeded, expected exception was not thrown");
+ }
+ else
+ {
+ //Use the connection to verify it works
+ con.createSession(true, Session.SESSION_TRANSACTED);
+ }
+ }
+ catch(JMSException e)
+ {
+ if(shouldSucceed)
+ {
+ _logger.error("Caught unexpected exception",e);
+ fail("Connection failed, unexpected exception thrown");
+ }
+ else
+ {
+ //expected
+ verifyExceptionCausesContains(e, "Caused by: javax.net.ssl.SSLException:");
+ }
+ }
+ }
+ }
+
+ private boolean shouldPerformTest()
+ {
+ // We run the SSL tests on all the Java broker profiles
+ if(isJavaBroker())
+ {
+ setTestClientSystemProperty(PROFILE_USE_SSL, "true");
+ }
+
+ return Boolean.getBoolean(PROFILE_USE_SSL);
+ }
+
+ private void configureJavaBrokerIfNecessary(boolean sslEnabled, boolean sslOnly, boolean needClientAuth, boolean wantClientAuth) throws ConfigurationException
+ {
+ if(isJavaBroker())
+ {
+ Map<String, Object> sslPortAttributes = new HashMap<String, Object>();
+ sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ sslPortAttributes.put(Port.NEED_CLIENT_AUTH, needClientAuth);
+ sslPortAttributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth);
+ sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+ getBrokerConfiguration().addPortConfiguration(sslPortAttributes);
+ }
+ }
+
+ private void setSslStoreSystemProperties()
+ {
+ setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
+ setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
+ setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+ setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+ }
+
+ private void clearSslStoreSystemProperties()
+ {
+ setSystemProperty("javax.net.ssl.keyStore", null);
+ setSystemProperty("javax.net.ssl.keyStorePassword", null);
+ setSystemProperty("javax.net.ssl.trustStore", null);
+ setSystemProperty("javax.net.ssl.trustStorePassword", null);
+ }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java
new file mode 100644
index 0000000000..80001099a8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.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.ra.admin;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.naming.NamingException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.spi.ObjectFactory;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class QpidConnectionFactoryProxyTest extends QpidBrokerTestCase
+{
+ private static final String BROKER_PORT = "15672";
+
+ private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN''";
+
+ public void testQueueConnectionFactory() throws Exception
+ {
+ QueueConnectionFactory cf = null;
+ QueueConnection c = null;
+
+ try
+ {
+ cf = new QpidConnectionFactoryProxy();
+ ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL);
+ c = cf.createQueueConnection();
+ assertTrue(c instanceof QueueConnection);
+
+ }
+ finally
+ {
+ if(c != null)
+ {
+ c.close();
+ }
+ }
+ }
+
+ public void testTopicConnectionFactory() throws Exception
+ {
+ TopicConnectionFactory cf = null;
+ TopicConnection c = null;
+
+ try
+ {
+ cf = new QpidConnectionFactoryProxy();
+ ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL);
+ c = cf.createTopicConnection();
+ assertTrue(c instanceof TopicConnection);
+
+ }
+ finally
+ {
+ if(c != null)
+ {
+ c.close();
+ }
+ }
+ try
+ {
+
+ }
+ finally
+ {
+
+ }
+ }
+
+ public void testConnectionFactory() throws Exception
+ {
+ ConnectionFactory cf = null;
+ Connection c = null;
+
+ try
+ {
+ cf = new QpidConnectionFactoryProxy();
+ ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL);
+ c = cf.createConnection();
+ assertTrue(c instanceof Connection);
+
+ }
+ finally
+ {
+ if(c != null)
+ {
+ c.close();
+ }
+
+ }
+ }
+}
+
diff --git a/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java b/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
index 9f3994fc91..eba2a638c0 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
@@ -30,6 +30,7 @@ import org.apache.qpid.util.LogMonitor;
import javax.jms.Connection;
import javax.jms.Queue;
import javax.jms.Session;
+import java.io.File;
import java.util.List;
/**
@@ -72,10 +73,7 @@ public class BrokerStartupTest extends AbstractTestLogging
if (isJavaBroker() && isExternalBroker() && !isInternalBroker())
{
//Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
-
- // Add an invalid value
- _brokerCommand += " -l invalid";
+ setBrokerCommandLog4JFile(new File("invalid file"));
// The broker has a built in default log4j configuration set up
// so if the the broker cannot load the -l value it will use default
@@ -145,4 +143,4 @@ public class BrokerStartupTest extends AbstractTestLogging
}
}
-} \ No newline at end of file
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java b/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java
index e8d72c13bd..23a00431d1 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java
@@ -23,13 +23,17 @@ package org.apache.qpid.server;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.adapter.PortFactoryTest;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
/**
* Tests to validate it is possible to disable support for particular protocol
* versions entirely, rather than selectively excluding them on particular ports,
* and it is possible to configure the reply to an unsupported protocol initiation.
+ *<p>
+ * Protocol exclusion/inclusion are unit tested as part of {@link PortFactoryTest}
*/
public class SupportedProtocolVersionsTest extends QpidBrokerTestCase
{
@@ -41,8 +45,8 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase
private void clearProtocolSupportManipulations()
{
//Remove the QBTC provided protocol manipulations, giving only the protocols which default to enabled
- setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_EXCLUDES, null);
- setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_INCLUDES, null);
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, null);
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, null);
}
/**
@@ -87,8 +91,8 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase
clearProtocolSupportManipulations();
//disable 0-10 and 1-0 support
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false");
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES,
+ Protocol.AMQP_1_0 + "," + Protocol.AMQP_0_10);
super.setUp();
@@ -100,52 +104,14 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase
connection.close();
}
- public void testDisabling091and010and10() throws Exception
- {
- clearProtocolSupportManipulations();
-
- //disable 0-91 and 0-10 and 1-0 support
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false");
-
- super.setUp();
-
- //Verify initially requesting a 0-10 connection now negotiates a 0-9
- //connection as the broker should reply with its highest supported protocol
- setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10");
- AMQConnection connection = (AMQConnection) getConnection();
- assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_9, connection.getProtocolVersion());
- connection.close();
- }
-
- public void testDisabling09and091and010and10() throws Exception
- {
- clearProtocolSupportManipulations();
-
- //disable 0-9, 0-91, 0-10 and 1-0 support
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP09ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false");
-
- super.setUp();
-
- //Verify initially requesting a 0-10 connection now negotiates a 0-8
- //connection as the broker should reply with its highest supported protocol
- setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10");
- AMQConnection connection = (AMQConnection) getConnection();
- assertEquals("Unexpected protocol version in use", ProtocolVersion.v8_0, connection.getProtocolVersion());
- connection.close();
- }
-
public void testConfiguringReplyingToUnsupported010ProtocolInitiationWith09insteadOf091() throws Exception
{
clearProtocolSupportManipulations();
//disable 0-10 support, and set the default unsupported protocol initiation reply to 0-9
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP_SUPPORTED_REPLY, "v0_9");
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES,
+ Protocol.AMQP_1_0 + "," + Protocol.AMQP_0_10);
+ setSystemProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY, "v0_9");
super.setUp();
@@ -164,71 +130,5 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase
connection.close();
}
- public void testProtocolInclusionThroughQBTCSystemPropertiesOverridesProtocolExclusion() throws Exception
- {
- testProtocolInclusionOverridesProtocolExclusion(false);
- }
-
- public void testProtocolInclusionThroughConfigOverridesProtocolExclusion() throws Exception
- {
- testProtocolInclusionOverridesProtocolExclusion(true);
- }
-
- private void testProtocolInclusionOverridesProtocolExclusion(boolean useConfig) throws Exception
- {
- clearProtocolSupportManipulations();
-
- //selectively exclude 0-10 and 1-0 on the test port
- setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_EXCLUDES,"--exclude-0-10 @PORT --exclude-1-0 @PORT");
-
- super.setUp();
-
- //Verify initially requesting a 0-10 connection negotiates a 0-9-1 connection
- setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10");
- AMQConnection connection = (AMQConnection) getConnection();
- assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_91, connection.getProtocolVersion());
- connection.close();
-
- stopBroker();
-
- if(useConfig)
- {
- //selectively include 0-10 support again on the test port through config
- setConfigurationProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, String.valueOf(getPort()));
- }
- else
- {
- //selectively include 0-10 support again on the test port through QBTC sys props
- setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_INCLUDES,"--include-0-10 @PORT");
- }
-
- startBroker();
-
- //Verify requesting a 0-10 connection now returns one
- setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10");
- connection = (AMQConnection) getConnection();
- assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_10, connection.getProtocolVersion());
- connection.close();
- }
-
- public void testProtocolInclusionOverridesProtocolDisabling() throws Exception
- {
- clearProtocolSupportManipulations();
-
- //disable 0-10 and 1-0
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false");
- setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false");
-
- //selectively include 0-10 support again on the test port
- setConfigurationProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, String.valueOf(getPort()));
-
- super.setUp();
-
- //Verify initially requesting a 0-10 connection still works
- setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10");
- AMQConnection connection = (AMQConnection) getConnection();
- assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_10, connection.getProtocolVersion());
- connection.close();
- }
} \ No newline at end of file
diff --git a/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java b/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
deleted file mode 100644
index 6f54a56e93..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
+++ /dev/null
@@ -1,75 +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;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-/**
- * This system test ensures that when loading our default system-test
- * configuration file the configuration is correctly loaded.
- *
- * All configuration values should be set in the systest config file so that
- * the ability to load them can be validated.
- */
-public class ServerConfigurationFileTest extends QpidBrokerTestCase
-{
- private ServerConfiguration _serverConfig;
-
- public void setUp() throws ConfigurationException
- {
- if (!_configFile.exists())
- {
- fail("Unable to test without config file:" + _configFile);
- }
-
- saveTestConfiguration();
- saveTestVirtualhosts();
-
- _serverConfig = new ServerConfiguration(_configFile);
- }
-
- /**
- * This helper method ensures that when we attempt to read a value that is
- * set in the configuration file we do actualy read a value and not
- * simply get a defaulted value from the ServerConfiguration.get*() methods.
- *
- * @param property the propert to test
- */
- private void validatePropertyDefinedInFile(String property)
- {
- //Verify that we are not just picking up the the default value from the getBoolean
- assertNotNull("The value set in the configuration file is not being read for property:" + property,
- _serverConfig.getConfig().getProperty(property));
- }
-
- public void testStatusUpdates() throws ConfigurationException
- {
- validatePropertyDefinedInFile(ServerConfiguration.STATUS_UPDATES);
- }
-
- public void testLocale() throws ConfigurationException
- {
- validatePropertyDefinedInFile(ServerConfiguration.ADVANCED_LOCALE);
- }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java b/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java
deleted file mode 100644
index 87a53a0765..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java
+++ /dev/null
@@ -1,237 +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.failure;
-
-import junit.framework.TestCase;
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.failover.FailoverException;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidClientConnectionHelper;
-
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-import java.io.IOException;
-
-
-/** Test Case provided by client Non-functional Test NF101: heap exhaustion behaviour */
-public class HeapExhaustion extends TestCase
-{
- private static final Logger _logger = Logger.getLogger(HeapExhaustion.class);
-
- protected QpidClientConnectionHelper conn;
- protected final String BROKER = "localhost";
- protected final String vhost = "/test";
- protected final String queue = "direct://amq.direct//queue";
-
- protected String hundredK;
- protected String megabyte;
-
- protected String generatePayloadOfSize(Integer numBytes)
- {
- return new String(new byte[numBytes]);
- }
-
- protected void setUp() throws Exception
- {
- conn = new QpidClientConnectionHelper(BROKER);
- conn.setVirtualHost(vhost);
-
- try
- {
- conn.connect();
- } catch (JMSException e)
- {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- // clear queue
- _logger.debug("setup: clearing test queue");
- conn.consume(queue, 2000);
-
- hundredK = generatePayloadOfSize(1024 * 100);
- megabyte = generatePayloadOfSize(1024 * 1024);
- }
-
- protected void tearDown() throws Exception
- {
- conn.disconnect();
- }
-
-
- /**
- * PUT at maximum rate (although we commit after each PUT) until failure
- *
- * @throws Exception on error
- */
- public void testUntilFailureTransient() throws Exception
- {
- int copies = 0;
- int total = 0;
- String payload = hundredK;
- int size = payload.getBytes().length;
- while (true)
- {
- conn.put(queue, payload, 1, DeliveryMode.NON_PERSISTENT);
- copies++;
- total += size;
- System.out.println("put copy " + copies + " OK for total bytes: " + total);
- }
- }
-
- /**
- * PUT at lower rate (5 per second) until failure
- *
- * @throws Exception on error
- */
- public void testUntilFailureWithDelaysTransient() throws Exception
- {
- int copies = 0;
- int total = 0;
- String payload = hundredK;
- int size = payload.getBytes().length;
- while (true)
- {
- conn.put(queue, payload, 1, DeliveryMode.NON_PERSISTENT);
- copies++;
- total += size;
- System.out.println("put copy " + copies + " OK for total bytes: " + total);
- Thread.sleep(200);
- }
- }
-
- public static void noDelay()
- {
- HeapExhaustion he = new HeapExhaustion();
-
- try
- {
- he.setUp();
- }
- catch (Exception e)
- {
- _logger.info("Unable to connect");
- System.exit(0);
- }
-
- try
- {
- _logger.info("Running testUntilFailure");
- try
- {
- he.testUntilFailureTransient();
- }
- catch (FailoverException fe)
- {
- _logger.error("Caught failover:" + fe);
- }
- _logger.info("Finishing Connection ");
-
- try
- {
- he.tearDown();
- }
- catch (JMSException jmse)
- {
- if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT)
- {
- _logger.info("Successful test of testUntilFailure");
- }
- else
- {
- _logger.error("Test Failed due to:" + jmse);
- }
- }
- }
- catch (Exception e)
- {
- _logger.error("Test Failed due to:" + e);
- }
- }
-
- public static void withDelay()
- {
- HeapExhaustion he = new HeapExhaustion();
-
- try
- {
- he.setUp();
- }
- catch (Exception e)
- {
- _logger.info("Unable to connect");
- System.exit(0);
- }
-
- try
- {
- _logger.info("Running testUntilFailure");
- try
- {
- he.testUntilFailureWithDelaysTransient();
- }
- catch (FailoverException fe)
- {
- _logger.error("Caught failover:" + fe);
- }
- _logger.info("Finishing Connection ");
-
- try
- {
- he.tearDown();
- }
- catch (JMSException jmse)
- {
- if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT)
- {
- _logger.info("Successful test of testUntilFailure");
- }
- else
- {
- _logger.error("Test Failed due to:" + jmse);
- }
- }
- }
- catch (Exception e)
- {
- _logger.error("Test Failed due to:" + e);
- }
- }
-
- public static void main(String args[])
- {
- noDelay();
-
-
- try
- {
- System.out.println("Restart failed broker now to retest broker with delays in send.");
- System.in.read();
- }
- catch (IOException e)
- {
- _logger.info("Continuing");
- }
-
- withDelay();
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
index b666b1f424..84017b6850 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java
@@ -20,12 +20,7 @@
*/
package org.apache.qpid.server.logging;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.logging.subjects.AbstractTestLogSubject;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.util.LogMonitor;
@@ -47,8 +42,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase
public static final String TEST_LOG_PREFIX = "MESSAGE";
protected LogMonitor _monitor;
- private InternalBrokerBaseCase _configLoader;
-
@Override
public void setUp() throws Exception
{
@@ -58,32 +51,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase
_monitor = new LogMonitor(_outputFile);
}
- protected ServerConfiguration getServerConfig() throws ConfigurationException
- {
- ServerConfiguration _serverConfiguration;
- if (isExternalBroker())
- {
- _serverConfiguration = new ServerConfiguration(_configFile)
- {
- @Override
- public void initialise() throws ConfigurationException
- {
- //Overriding initialise to only setup the vhosts and not
- //perform the ConfigurationPlugin setup, removing need for
- //an ApplicationRegistry to be loaded.
- setupVirtualHosts(getConfig());
- }
- };
- _serverConfiguration.initialise();
- }
- else
- {
- _serverConfiguration = ApplicationRegistry.getInstance().getConfiguration();
- }
-
- return _serverConfiguration;
- }
-
protected void setLogMessagePrefix()
{
//set the message prefix to facilitate scraping from the munged test output.
@@ -94,10 +61,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase
public void tearDown() throws Exception
{
_monitor.close();
- if (isExternalBroker() && _configLoader != null)
- {
- _configLoader.tearDown();
- }
super.tearDown();
}
@@ -159,7 +122,7 @@ public class AbstractTestLogging extends QpidBrokerTestCase
}
protected String fromMessage(String log)
- {
+ {;
int startSubject = log.indexOf("]") + 1;
int start = log.indexOf("]", startSubject) + 1;
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
index 4b7b3f0cf0..37f960a65a 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
@@ -31,10 +31,10 @@ import java.util.List;
/**
* ACL version 2/3 file testing to verify that ACL actor logging works correctly.
- *
+ *
* This suite of tests validate that the AccessControl messages occur correctly
* and according to the following format:
- *
+ *
* <pre>
* ACL-1001 : Allowed Operation Object {PROPERTIES}
* ACL-1002 : Denied Operation Object {PROPERTIES}
@@ -83,12 +83,12 @@ public class AccessControlLoggingTest extends AbstractTestLogging
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn.start();
((AMQSession<?, ?>) sess).createQueue(new AMQShortString("allow"), false, false, false);
-
+
List<String> matches = findMatches(ACL_LOG_PREFIX);
-
+
assertTrue("Should be no ACL log messages", matches.isEmpty());
}
-
+
/**
* Test that {@code allow-log} ACL entries log correctly.
*/
@@ -98,25 +98,25 @@ public class AccessControlLoggingTest extends AbstractTestLogging
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn.start();
((AMQSession<?, ?>) sess).createQueue(new AMQShortString("allow-log"), false, false, false);
-
+
List<String> matches = findMatches(ACL_LOG_PREFIX);
-
+
assertEquals("Should only be one ACL log message", 1, matches.size());
-
+
String log = getLogMessage(matches, 0);
String actor = fromActor(log);
String subject = fromSubject(log);
String message = getMessageString(fromMessage(log));
-
+
validateMessageID(ACL_LOG_PREFIX + 1001, log);
-
- assertTrue("Actor should contain the user identity", actor.contains(USER));
+
+ assertTrue("Actor " + actor + " should contain the user identity: " + USER, actor.contains(USER));
assertTrue("Subject should be empty", subject.length() == 0);
assertTrue("Message should start with 'Allowed'", message.startsWith("Allowed"));
assertTrue("Message should contain 'Create Queue'", message.contains("Create Queue"));
assertTrue("Message should have contained the queue name", message.contains("allow-log"));
}
-
+
/**
* Test that {@code deny-log} ACL entries log correctly.
*/
@@ -134,25 +134,25 @@ public class AccessControlLoggingTest extends AbstractTestLogging
// Denied, so exception thrown
assertEquals("Expected ACCESS_REFUSED error code", AMQConstant.ACCESS_REFUSED, amqe.getErrorCode());
}
-
+
List<String> matches = findMatches(ACL_LOG_PREFIX);
-
+
assertEquals("Should only be one ACL log message", 1, matches.size());
-
+
String log = getLogMessage(matches, 0);
String actor = fromActor(log);
String subject = fromSubject(log);
String message = getMessageString(fromMessage(log));
-
+
validateMessageID(ACL_LOG_PREFIX + 1002, log);
-
- assertTrue("Actor should contain the user identity", actor.contains(USER));
+
+ assertTrue("Actor " + actor + " should contain the user identity: " + USER, actor.contains(USER));
assertTrue("Subject should be empty", subject.length() == 0);
assertTrue("Message should start with 'Denied'", message.startsWith("Denied"));
assertTrue("Message should contain 'Create Queue'", message.contains("Create Queue"));
assertTrue("Message should have contained the queue name", message.contains("deny-log"));
}
-
+
/**
* Test that {@code deny} ACL entries do not log anything.
*/
@@ -170,9 +170,9 @@ public class AccessControlLoggingTest extends AbstractTestLogging
// Denied, so exception thrown
assertEquals("Expected ACCESS_REFUSED error code", AMQConstant.ACCESS_REFUSED, amqe.getErrorCode());
}
-
+
List<String> matches = findMatches(ACL_LOG_PREFIX);
-
+
assertTrue("Should be no ACL log messages", matches.isEmpty());
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
index 02c41e14c0..68ec101245 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
@@ -22,10 +22,6 @@ package org.apache.qpid.server.logging;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.util.FileUtils;
import javax.jms.Connection;
import javax.jms.Queue;
@@ -44,29 +40,19 @@ public class AlertingTest extends AbstractTestLogging
public void setUp() throws Exception
{
- // Update the configuration to make our virtualhost Persistent.
- makeVirtualHostPersistent(VIRTUALHOST);
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "5000");
-
_numMessages = 50;
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", String.valueOf(ALERT_LOG_WAIT_PERIOD));
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", String.valueOf(_numMessages));
+
// Then we do the normal setup stuff like starting the broker, getting a connection etc.
super.setUp();
setupConnection();
}
- @Override
- public void tearDown() throws Exception
- {
- // Ensure queue is clean for next run.
- drainQueue(_destination);
- super.tearDown();
- }
-
-
/**
- * Create a new connection and ensure taht our destination queue is created
+ * Create a new connection and ensure that our destination queue is created
* and bound.
*
* Note that the tests here that restart the broker rely on persistence.
@@ -102,20 +88,6 @@ public class AlertingTest extends AbstractTestLogging
if (!waitForMessage(MESSAGE_COUNT_ALERT, ALERT_LOG_WAIT_PERIOD))
{
StringBuffer message = new StringBuffer("Could not find 'MESSAGE_COUNT_ALERT' in log file: " + _monitor.getMonitoredFile().getAbsolutePath());
- message.append("\n");
-
- // Add the current contents of the log file to test output
- message.append(_monitor.readFile());
-
- // Write the test config file to test output
- message.append("Server configuration overrides in use:\n");
- message.append(FileUtils.readFileAsString(getTestConfigFile()));
-
- message.append("\nVirtualhost maxMessageCount:\n");
- ServerConfiguration config = new ServerConfiguration(_configFile);
- config.initialise();
- message.append(config.getVirtualHostConfig(VIRTUALHOST).getMaximumMessageCount());
-
fail(message.toString());
}
}
@@ -148,9 +120,6 @@ public class AlertingTest extends AbstractTestLogging
* Test sends two messages to the broker then restarts the broker with new
* configuration.
*
- * If the test is running inVM the test validates that the new configuration
- * has been applied.
- *
* Validates that we only have two messages on the queue and then sends
* enough messages to trigger the alert.
*
@@ -172,31 +141,24 @@ public class AlertingTest extends AbstractTestLogging
_monitor.markDiscardPoint();
// Change max message count to 5, start broker and make sure that that's triggered at the right time
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", "5");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", "5");
startBroker();
- if (isInternalBroker())
- {
- assertEquals("Alert Max Msg Count is not correct", 5, ApplicationRegistry.getInstance().getVirtualHostRegistry().
- getVirtualHost(VIRTUALHOST).getQueueRegistry().getQueue(new AMQShortString(_destination.getQueueName())).
- getMaximumMessageCount());
- }
-
setupConnection();
// Validate the queue depth is as expected
long messageCount = ((AMQSession<?, ?>) _session).getQueueDepth((AMQDestination) _destination);
assertEquals("Broker has invalid message count for test", 2, messageCount);
- // Ensure the alert has not occured yet
+ // Ensure the alert has not occurred yet
assertLoggingNotYetOccured(MESSAGE_COUNT_ALERT);
// Trigger the new value
sendMessage(_session, _destination, 3);
_session.commit();
- // Validate that the alert occured.
+ // Validate that the alert occurred.
wasAlertFired();
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
index dee593b12b..c5f5e06ae1 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
@@ -23,12 +23,20 @@ package org.apache.qpid.server.logging;
import junit.framework.AssertionFailedError;
import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.util.LogMonitor;
import java.io.IOException;
import java.net.Socket;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Broker Test Suite
@@ -47,6 +55,8 @@ import java.util.List;
*/
public class BrokerLoggingTest extends AbstractTestLogging
{
+ private static final String BROKER_MESSAGE_LOG_REG_EXP = ".*\\[\\w*\\] (BRK\\-\\d*) .*";
+ private static final Pattern BROKER_MESSAGE_LOG_PATTERN = Pattern.compile(BROKER_MESSAGE_LOG_REG_EXP);
private static final String BRK_LOG_PREFIX = "BRK-";
public void setUp() throws Exception
@@ -95,7 +105,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
_monitor = new LogMonitor(_outputFile);
- String configFilePath = _configFile.toString();
+ String configFilePath = getConfigPath();
// Ensure we wait for TESTID to be logged
waitAndFindMatches(TESTID);
@@ -118,8 +128,9 @@ public class BrokerLoggingTest extends AbstractTestLogging
1, results.size());
//3
- assertTrue("Config file details not correctly logged",
- log.endsWith(configFilePath));
+ assertTrue("Config file details not correctly logged, got "
+ + log + " but expected it to end with " + configFilePath,
+ log.endsWith(configFilePath));
}
catch (AssertionFailedError afe)
{
@@ -130,6 +141,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
}
}
+ private String getConfigPath()
+ {
+ return getPathRelativeToWorkingDirectory(getTestConfigFile(DEFAULT_PORT));
+ }
+
/**
* Description:
* On startup the broker must report correctly report the log4j file in use. This is important as it can help diagnose why logging messages are not being reported.
@@ -155,8 +171,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
{
String TESTID = "BRK-1007";
- //Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+ _brokerCommandHelper.removeBrokerCommandLog4JFile();
startBroker();
@@ -243,8 +258,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
// This logging startup code only occurs when you run a Java broker
if (isJavaBroker() && isExternalBroker())
{
- // Get custom -l value used during testing for the broker startup
- String customLog4j = _brokerCommand.substring(_brokerCommand.indexOf("-l") + 2).trim();
+ String customLog4j = getBrokerCommandLog4JFile().getAbsolutePath();
String TESTID = "BRK-1007";
@@ -293,8 +307,10 @@ public class BrokerLoggingTest extends AbstractTestLogging
1, findMatches(TESTID).size());
//3
- assertTrue("Log4j file details not correctly logged:" + getMessageString(log),
- getMessageString(log).endsWith(customLog4j));
+ String messageString = getMessageString(log);
+ assertTrue("Log4j file details not correctly logged. Message '"
+ + messageString + "' should contain '" +customLog4j + "'",
+ messageString.endsWith(customLog4j));
validation = true;
}
@@ -442,10 +458,13 @@ public class BrokerLoggingTest extends AbstractTestLogging
{
String log = getLog(rawLog);
+ // using custom method to get id as getMessageId() fails to correctly identify id
+ // because of using brackets for protocols
+ String id = getBrokerLogId(log);
// Ensure we do not have a BRK-1002 message
- if (!getMessageID(log).equals(TESTID))
+ if (!id.equals(TESTID))
{
- if (getMessageID(log).equals("BRK-1001"))
+ if (id.equals("BRK-1001"))
{
foundBRK1001 = true;
}
@@ -455,7 +474,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
assertTrue("BRK-1001 not logged before this message", foundBRK1001);
//1
- validateMessageID(TESTID, log);
+ assertEquals("Incorrect message", TESTID, id);
//2
//There will be 2 copies of the startup message (one via SystemOut, and one via Log4J)
@@ -465,7 +484,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
//3
String message = getMessageString(log);
assertTrue("Expected Listen log not correct" + message,
- message.endsWith("Listening on TCP port " + getPort()));
+ message.endsWith("Listening on [TCP] port " + getPort()));
validation = true;
}
@@ -481,6 +500,16 @@ public class BrokerLoggingTest extends AbstractTestLogging
}
}
+ private String getBrokerLogId(String log)
+ {
+ Matcher m = BROKER_MESSAGE_LOG_PATTERN.matcher(log);
+ if (m.matches())
+ {
+ return m.group(1);
+ }
+ return getMessageID(log);
+ }
+
/**
* Description:
* On startup the broker may listen on a number of ports and protocols. Each of these must be reported as they are made available.
@@ -498,8 +527,8 @@ public class BrokerLoggingTest extends AbstractTestLogging
* 1. The BRK ID is correct
* 2. This occurs after the BRK-1001 startup message
* 3. With SSL enabled in the configuration two BRK-1002 will be printed (order is not specified)
- * 1. One showing values TCP / 5672
- * 2. One showing values TCP/SSL / 5672
+ * 1. One showing values [TCP] 5672
+ * 2. One showing values [SSL] 5671
*
* @throws Exception caused by broker startup
*/
@@ -512,12 +541,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
String TESTID = "BRK-1002";
// Enable SSL on the connection
- setConfigurationProperty("connector.ssl.enabled", "true");
- setConfigurationProperty("connector.ssl.sslOnly", "false");
- setConfigurationProperty("connector.ssl.keyStorePath", getConfigurationStringProperty("management.ssl.keyStorePath"));
- setConfigurationProperty("connector.ssl.keyStorePassword", getConfigurationStringProperty("management.ssl.keyStorePassword"));
-
- Integer sslPort = Integer.parseInt(getConfigurationStringProperty("connector.ssl.port"));
+ Map<String, Object> sslPortAttributes = new HashMap<String, Object>();
+ sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+ getBrokerConfiguration().addPortConfiguration(sslPortAttributes);
startBroker();
@@ -545,10 +573,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
{
String log = getLog(rawLog);
+ String id = getBrokerLogId(log);
// Ensure we do not have a BRK-1002 message
- if (!getMessageID(log).equals(TESTID))
+ if (!id.equals(TESTID))
{
- if (getMessageID(log).equals("BRK-1001"))
+ if (id.equals("BRK-1001"))
{
foundBRK1001 = true;
}
@@ -558,7 +587,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
assertTrue("BRK-1001 not logged before this message", foundBRK1001);
//1
- validateMessageID(TESTID, log);
+ assertEquals("Incorrect message", TESTID, id);
//2
//There will be 4 copies of the startup message (two via SystemOut, and two via Log4J)
@@ -570,16 +599,16 @@ public class BrokerLoggingTest extends AbstractTestLogging
//Check the first
String message = getMessageString(getLog(listenMessages .get(0)));
assertTrue("Expected Listen log not correct" + message,
- message.endsWith("Listening on TCP port " + getPort()));
+ message.endsWith("Listening on [TCP] port " + getPort()));
// Check the third, ssl listen.
message = getMessageString(getLog(listenMessages .get(2)));
assertTrue("Expected Listen log not correct" + message,
- message.endsWith("Listening on TCP/SSL port " + sslPort));
+ message.endsWith("Listening on [SSL] port " + DEFAULT_SSL_PORT));
//4 Test ports open
testSocketOpen(getPort());
- testSocketOpen(sslPort);
+ testSocketOpen(DEFAULT_SSL_PORT);
validation = true;
}
@@ -803,11 +832,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
String TESTID = "BRK-1003";
// Enable SSL on the connection
- setConfigurationProperty("connector.ssl.enabled", "true");
- setConfigurationProperty("connector.ssl.keyStorePath", getConfigurationStringProperty("management.ssl.keyStorePath"));
- setConfigurationProperty("connector.ssl.keyStorePassword", getConfigurationStringProperty("management.ssl.keyStorePassword"));
-
- Integer sslPort = Integer.parseInt(getConfigurationStringProperty("connector.ssl.port"));
+ Map<String, Object> sslPortAttributes = new HashMap<String, Object>();
+ sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+ getBrokerConfiguration().addPortConfiguration(sslPortAttributes);
startBroker();
@@ -848,13 +877,13 @@ public class BrokerLoggingTest extends AbstractTestLogging
// Check second, ssl, listen.
message = getMessageString(getLog(listenMessages.get(1)));
assertTrue("Expected shutdown log not correct" + message,
- message.endsWith("TCP/SSL port " + sslPort));
+ message.endsWith("TCP/SSL port " + DEFAULT_SSL_PORT));
//4
//Test Port closed
checkSocketClosed(getPort());
//Test SSL Port closed
- checkSocketClosed(sslPort);
+ checkSocketClosed(DEFAULT_SSL_PORT);
}
catch (AssertionFailedError afe)
{
@@ -999,4 +1028,5 @@ public class BrokerLoggingTest extends AbstractTestLogging
+ ". Due to:" + e.getMessage());
}
}
+
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
index 236202f323..9f532ec5f7 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
@@ -66,8 +66,8 @@ public class SubscriptionLoggingTest extends AbstractTestLogging
_session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- _queue = (Queue) getInitialContext().lookup(QUEUE);
- _topic = (Topic) getInitialContext().lookup(TOPIC);
+ _queue = _session.createQueue(getTestQueueName() + "Queue");
+ _topic = _session.createTopic(getTestQueueName() + "Topic");
}
/**
@@ -434,10 +434,6 @@ public class SubscriptionLoggingTest extends AbstractTestLogging
throw afe;
}
_connection.close();
-
- //Ensure the queue is drained before the test ends
- drainQueue(_queue);
-
}
/**
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
index 5f96215269..1ea105ae1a 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.logging;
import junit.framework.AssertionFailedError;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import java.util.Arrays;
import java.util.List;
@@ -68,7 +67,7 @@ public class VirtualHostLoggingTest extends AbstractTestLogging
try
{
- List<String> vhosts = Arrays.asList(getServerConfig().getVirtualHosts());
+ List<String> vhosts = Arrays.asList("test");
assertEquals("Each vhost did not create a store.", vhosts.size(), results.size());
@@ -110,23 +109,17 @@ public class VirtualHostLoggingTest extends AbstractTestLogging
// Wait for the correct VHT message to arrive.
waitForMessage(VHT_PREFIX + "1002");
-
+
// Validate each vhost logs a closure
List<String> results = findMatches(VHT_PREFIX + "1002");
-
+
try
{
- // Load VirtualHost list from file.
- ServerConfiguration configuration = new ServerConfiguration(_configFile);
- configuration.initialise();
- List<String> vhosts = Arrays.asList(configuration.getVirtualHosts());
-
- assertEquals("Each vhost did not close their store.", vhosts.size(), results.size());
+ assertEquals("Each vhost did not close their store.", 1, results.size());
}
catch (AssertionFailedError afe)
{
dumpLogs(results, _monitor);
-
throw afe;
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java b/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
index bcad59a1fa..82b421a531 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
@@ -39,7 +39,7 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
*/
public class NoLocalAfterRecoveryTest extends QpidBrokerTestCase
{
- protected final String MY_TOPIC_SUBSCRIPTION_NAME = this.getName();
+ protected final String MY_TOPIC_SUBSCRIPTION_NAME = getTestQueueName();
protected static final int SEND_COUNT = 10;
public void testNoLocalNotQueued() throws Exception
diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java b/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
index 8536651ffb..cbf4e032db 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
@@ -30,6 +30,7 @@ import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
+
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -54,7 +55,9 @@ public class MultipleTransactedBatchProducerTest extends QpidBrokerTestCase
//debug level logging often makes this test pass artificially, turn the level down to info.
setSystemProperty("amqj.server.logging.level", "INFO");
_receivedLatch = new CountDownLatch(MESSAGE_COUNT * NUM_PRODUCERS);
- setConfigurationProperty("management.enabled", "true");
+
+ getBrokerConfiguration().addJmxManagementConfiguration();
+
super.setUp();
_queueName = getTestQueueName();
_failMsg = null;
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
index 8ccf74a22b..814936f342 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
@@ -26,6 +26,7 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.url.URLSyntaxException;
@@ -45,7 +46,7 @@ import java.util.concurrent.TimeUnit;
/**
* Abstract test case for ACLs.
*
- * This base class contains convenience methods to mange ACL files and implements a mechanism that allows each
+ * This base class contains convenience methods to manage ACL files and implements a mechanism that allows each
* test method to run its own setup code before the broker starts.
*
* TODO move the pre broker-startup setup method invocation code to {@link QpidBrokerTestCase}
@@ -58,25 +59,11 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
{
/** Used to synchronise {@link #tearDown()} when exceptions are thrown */
protected CountDownLatch _exceptionReceived;
-
- /** Override this to return the name of the configuration XML file. */
- public String getConfig()
- {
- return "config-systests.xml";
- }
- /**
- * This setup method checks {@link #getConfig()} and {@link #getHostList()} to initialise the broker with specific
- * ACL configurations and then runs an optional per-test setup method, which is simply a method with the same name
- * as the test, but starting with {@code setUp} rather than {@code test}.
- *
- * @see org.apache.qpid.test.utils.QpidBrokerTestCase#setUp()
- */
@Override
public void setUp() throws Exception
{
- // Initialise ACLs.
- _configFile = new File("build" + File.separator + "etc" + File.separator + getConfig());
+ getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, System.getProperty(QPID_HOME) + "/etc/groups-systests");
// run test specific setup
String testSetup = StringUtils.replace(getName(), "test", "setUp");
@@ -123,11 +110,11 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
if (vhost == null)
{
- testcase.setConfigurationProperty("security.acl", aclFile.getAbsolutePath());
+ testcase.getBrokerConfiguration().setBrokerAttribute(Broker.ACL_FILE, aclFile.getAbsolutePath());
}
else
{
- testcase.setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.acl", aclFile.getAbsolutePath());
+ testcase.setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.acl", aclFile.getAbsolutePath());
}
PrintWriter out = new PrintWriter(new FileWriter(aclFile));
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
index ceff2b998a..1830040007 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
@@ -33,14 +33,19 @@ import java.lang.management.RuntimeMXBean;
*/
public class ExternalACLJMXTest extends AbstractACLTestCase
{
+
private JMXTestUtils _jmx;
private static final String TEST_QUEUE_OWNER = "admin";
private static final String TEST_VHOST = "test";
+ private static final String TEST2_VHOST = "test2";
@Override
public void setUp() throws Exception
{
+ createTestVirtualHost(0, TEST_VHOST);
+ createTestVirtualHost(0, TEST2_VHOST);
+
_jmx = new JMXTestUtils(this);
_jmx.setUp();
super.setUp();
@@ -54,15 +59,14 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
super.tearDown();
}
- /**
- * Ensure an empty ACL defaults to DENY ALL.
- */
- public void setUpDenyAllIsDefault() throws Exception
+ public void setUpDenyAllIsCatchAllRule() throws Exception
{
- writeACLFile(null, "#Empty ACL file");
+ writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
+ "#No more rules, default catch all (deny all) should apply");
}
- public void testDenyAllIsDefault() throws Exception
+ public void testDenyAllIsCatchAllRule() throws Exception
{
//try a broker-level method
ServerInformation info = _jmx.getServerInformation();
@@ -115,6 +119,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpVhostAllowOverridesGlobalDeny() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
writeACLFile(TEST_VHOST,
"ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
@@ -128,7 +133,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
//try a vhost-level method on a different vhost
try
{
- _jmx.createQueue("development", getTestQueueName(), TEST_QUEUE_OWNER, true);
+ _jmx.createQueue(TEST2_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
fail("Exception not thrown");
}
catch (SecurityException e)
@@ -144,6 +149,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpUpdateComponentOnlyAllow() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager'");
}
@@ -162,6 +168,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpUpdateMethodOnlyAllow() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL ALLOW admin UPDATE METHOD");
}
@@ -179,8 +186,8 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
*/
public void setUpCreateQueueSuccess() throws Exception
{
- writeACLFile(TEST_VHOST,
- "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
+ writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
+ writeACLFile(TEST_VHOST, "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
}
public void testCreateQueueSuccess() throws Exception
@@ -194,6 +201,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
*/
public void setUpCreateQueueSuccessNoAMQPRights() throws Exception
{
+ writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
writeACLFile(TEST_VHOST,
"ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'",
"ACL DENY admin CREATE QUEUE");
@@ -210,6 +218,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
*/
public void setUpCreateQueueDenied() throws Exception
{
+ writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
writeACLFile(TEST_VHOST,
"ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
}
@@ -234,6 +243,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpServerInformationUpdateDenied() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL DENY admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
}
@@ -258,6 +268,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpServerInformationAccessGranted() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL ALLOW-LOG admin ACCESS METHOD component='ServerInformation' name='getManagementApiMajorVersion'");
}
@@ -284,6 +295,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
public void setUpServerInformationUpdateMethodPermission() throws Exception
{
writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
"ACL ALLOW admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
}
@@ -300,7 +312,9 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
*/
public void setUpServerInformationAllMethodPermissions() throws Exception
{
- writeACLFile(null, "ACL ALLOW admin ALL METHOD component='ServerInformation'");
+ writeACLFile(null,
+ "ACL ALLOW admin ACCESS MANAGEMENT",
+ "ACL ALLOW admin ALL METHOD component='ServerInformation'");
}
public void testServerInformationAllMethodPermissions() throws Exception
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index 0e45ca9493..8324ac74a5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -319,8 +319,12 @@ public class ExternalACLTest extends AbstractACLTestCase
public void setUpRequestResponseSuccess() throws Exception
{
- writeACLFile("test", "GROUP messaging-users client server",
- "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST",
+ // The group "messaging-users", referenced in the ACL below, is currently defined
+ // in broker/etc/groups-systests.
+ // We tolerate a dependency from this test to that file because its
+ // contents are expected to change rarely.
+
+ writeACLFile("test", "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST",
"# Server side",
"ACL ALLOW-LOG server CREATE QUEUE name=\"example.RequestQueue\"" ,
"ACL ALLOW-LOG server BIND EXCHANGE",
@@ -389,14 +393,44 @@ public class ExternalACLTest extends AbstractACLTestCase
conn.start();
// create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+ String topicName = "kipper";
+ Topic topic = sess.createTopic(topicName);
+ TopicSubscriber subscriber = sess.createDurableSubscriber(topic, topicName);
subscriber.close();
- sess.unsubscribe("kipper");
+ sess.unsubscribe(topicName);
//Do something to show connection is active.
sess.rollback();
conn.close();
}
+
+ public void setUpFirewallAllow() throws Exception
+ {
+ writeACLFile("test", "ACL ALLOW client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+ }
+
+ public void testFirewallAllow() throws Exception
+ {
+ getConnection("test", "client", "guest");
+ // test pass because we successfully connected
+ }
+
+ public void setUpFirewallDeny() throws Exception
+ {
+ writeACLFile("test", "ACL DENY client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+ }
+
+ public void testFirewallDeny() throws Exception
+ {
+ try
+ {
+ getConnection("test", "client", "guest");
+ fail("We expected the connection to fail");
+ }
+ catch(JMSException e)
+ {
+ // pass
+ }
+ }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
new file mode 100644
index 0000000000..c7a43a292b
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class ExternalAuthenticationTest extends QpidBrokerTestCase
+{
+ @Override
+ protected void setUp() throws Exception
+ {
+ // not calling super.setUp() to avoid broker start-up
+ }
+
+ /**
+ * Tests that when EXTERNAL authentication is used on the SSL port, clients presenting certificates are able to connect.
+ * Also, checks that default authentication manager PrincipalDatabaseAuthenticationManager is used on non SSL port.
+ */
+ public void testExternalAuthenticationManagerOnSSLPort() throws Exception
+ {
+ setCommonBrokerSSLProperties(true);
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, Port.AUTHENTICATION_MANAGER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+ super.setUp();
+
+ setClientKeystoreProperties();
+ setClientTrustoreProperties();
+
+ try
+ {
+ getExternalSSLConnection(false);
+ }
+ catch (JMSException e)
+ {
+ fail("Should be able to create a connection to the SSL port: " + e.getMessage());
+ }
+
+ try
+ {
+ getConnection();
+ }
+ catch (JMSException e)
+ {
+ fail("Should be able to create a connection with credentials to the standard port: " + e.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests that when EXTERNAL authentication manager is set as the default, clients presenting certificates are able to connect.
+ * Also, checks a client with valid username and password but not using ssl is unable to connect to the non SSL port.
+ */
+ public void testExternalAuthenticationManagerAsDefault() throws Exception
+ {
+ setCommonBrokerSSLProperties(true);
+ getBrokerConfiguration().setBrokerAttribute(Broker.DEFAULT_AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+ super.setUp();
+
+ setClientKeystoreProperties();
+ setClientTrustoreProperties();
+
+ try
+ {
+ getConnection();
+ fail("Connection should not succeed");
+ }
+ catch (JMSException e)
+ {
+ // pass
+ }
+
+ try
+ {
+ getExternalSSLConnection(false);
+ }
+ catch (JMSException e)
+ {
+ fail("Should be able to create a connection to the SSL port. " + e.getMessage());
+ }
+ }
+
+ /**
+ * Tests that when EXTERNAL authentication manager is set as the default, clients without certificates are unable to connect to the SSL port
+ * even with valid username and password.
+ */
+ public void testExternalAuthenticationManagerWithoutClientKeyStore() throws Exception
+ {
+ setCommonBrokerSSLProperties(false);
+ getBrokerConfiguration().setBrokerAttribute(Broker.DEFAULT_AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+ super.setUp();
+
+ setClientTrustoreProperties();
+
+ try
+ {
+ getExternalSSLConnection(true);
+ fail("Connection should not succeed");
+ }
+ catch (JMSException e)
+ {
+ // pass
+ }
+ }
+
+ private Connection getExternalSSLConnection(boolean includeUserNameAndPassword) throws Exception
+ {
+ String url = "amqp://%s@test/?brokerlist='tcp://localhost:%s?ssl='true'&sasl_mechs='EXTERNAL''";
+ if (includeUserNameAndPassword)
+ {
+ url = String.format(url, "guest:guest", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
+ }
+ else
+ {
+ url = String.format(url, ":", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
+ }
+ return getConnection(new AMQConnectionURL(url));
+ }
+
+ private void setCommonBrokerSSLProperties(boolean needClientAuth) throws ConfigurationException
+ {
+ TestBrokerConfiguration config = getBrokerConfiguration();
+ Map<String, Object> sslPortAttributes = new HashMap<String, Object>();
+ sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ sslPortAttributes.put(Port.NEED_CLIENT_AUTH, String.valueOf(needClientAuth));
+ sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+ config.addPortConfiguration(sslPortAttributes);
+
+ Map<String, Object> externalAuthProviderAttributes = new HashMap<String, Object>();
+ externalAuthProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManagerFactory.PROVIDER_TYPE);
+ externalAuthProviderAttributes.put(AuthenticationProvider.NAME, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+ config.addAuthenticationProviderConfiguration(externalAuthProviderAttributes);
+ }
+
+ private void setClientKeystoreProperties()
+ {
+ setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
+ setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
+ }
+
+ private void setClientTrustoreProperties()
+ {
+ setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+ setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+ setSystemProperty("javax.net.debug", "ssl");
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
index 858b32c24c..f41f1159ab 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
@@ -20,28 +20,44 @@
*/
package org.apache.qpid.server.security.auth.manager;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.jms.Connection;
import javax.jms.JMSException;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class MultipleAuthenticationManagersTest extends QpidBrokerTestCase
{
- private static final String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks";
- private static final String KEYSTORE_PASSWORD = "password";
- private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
- private static final String TRUSTSTORE_PASSWORD = "password";
-
@Override
protected void setUp() throws Exception
{
- setConfigurationProperty("connector.ssl.enabled", "true");
- setConfigurationProperty("connector.ssl.sslOnly", "false");
- setConfigurationProperty("security.anonymous-auth-manager", "");
- setConfigurationProperty("security.default-auth-manager", "PrincipalDatabaseAuthenticationManager");
- setConfigurationProperty("security.port-mappings.port-mapping.port", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
- setConfigurationProperty("security.port-mappings.port-mapping.auth-manager", "AnonymousAuthenticationManager");
+ TestBrokerConfiguration config = getBrokerConfiguration();
+
+ Map<String, Object> externalAuthProviderAttributes = new HashMap<String, Object>();
+ externalAuthProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE);
+ externalAuthProviderAttributes.put(AuthenticationProvider.NAME, TestBrokerConfiguration.ENTRY_NAME_ANONYMOUS_PROVIDER);
+ config.addAuthenticationProviderConfiguration(externalAuthProviderAttributes);
+
+ Map<String, Object> sslPortAttributes = new HashMap<String, Object>();
+ sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+ sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+ sslPortAttributes.put(Port.AUTHENTICATION_MANAGER, TestBrokerConfiguration.ENTRY_NAME_ANONYMOUS_PROVIDER);
+ config.addPortConfiguration(sslPortAttributes);
// set the ssl system properties
setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
deleted file mode 100644
index f5adf815aa..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
+++ /dev/null
@@ -1,283 +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.firewall;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class FirewallConfigTest extends QpidBrokerTestCase
-{
- private File _tmpConfig, _tmpVirtualhosts;
- private String _ipAddressOfBrokerHost;
-
- @Override
- protected void setUp() throws Exception
- {
- // Setup initial config file.
- _configFile = new File("build/etc/config-systests-firewall.xml");
-
- // Setup temporary config file
- _tmpConfig = File.createTempFile("config-systests-firewall", ".xml");
- setSystemProperty("QPID_FIREWALL_CONFIG_SETTINGS", _tmpConfig.getAbsolutePath());
- _tmpConfig.deleteOnExit();
-
- // Setup temporary virtualhosts file
- _tmpVirtualhosts = File.createTempFile("virtualhosts-systests-firewall", ".xml");
- setSystemProperty("QPID_FIREWALL_VIRTUALHOSTS_SETTINGS", _tmpVirtualhosts.getAbsolutePath());
- _tmpVirtualhosts.deleteOnExit();
-
- _ipAddressOfBrokerHost = getIpAddressOfBrokerHost();
- }
-
- private void writeFirewallFile(boolean allow, boolean inVhost) throws IOException
- {
- FileWriter out = new FileWriter(inVhost ? _tmpVirtualhosts : _tmpConfig);
- if (inVhost)
- {
- out.write("<virtualhosts><virtualhost><test>");
- }
- else
- {
- out.write("<broker>");
- }
- out.write("<security><firewall>");
- out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\"" + _ipAddressOfBrokerHost + "\"/>");
- out.write("</firewall></security>");
- if (inVhost)
- {
- out.write("</test></virtualhost></virtualhosts>");
- }
- else
- {
- out.write("</broker>");
- }
- out.close();
- }
-
- public void testVhostAllowBrokerDeny() throws Exception
- {
-
- _configFile = new File("build/etc/config-systests-firewall-2.xml");
-
- super.setUp();
- try
- {
- //Try to get a connection to the 'test2' vhost
- //This is expected to succeed as it is allowed at the vhost level
- getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
- }
- catch (JMSException e)
- {
- e.getLinkedException().printStackTrace();
- fail("The connection was expected to succeed: " + e.getMessage());
- }
-
- try
- {
- //Try to get a connection to the 'test' vhost
- //This is expected to fail as it is denied at the broker level
- getConnection();
- fail("We expected the connection to fail");
- }
- catch (JMSException e)
- {
- //ignore
- }
- }
-
- public void testVhostDenyBrokerAllow() throws Exception
- {
- _configFile = new File("build/etc/config-systests-firewall-3.xml");
-
- super.setUp();
- try
- {
- //Try to get a connection to the 'test2' vhost
- //This is expected to fail as it is denied at the vhost level
- getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
- fail("The connection was expected to fail");
- }
- catch (JMSException e)
- {
- //ignore
- }
-
- try
- {
- //Try to get a connection to the 'test' vhost
- //This is expected to succeed as it is allowed at the broker level
- getConnection();
- }
- catch (JMSException e)
- {
- e.getLinkedException().printStackTrace();
- fail("The connection was expected to succeed: " + e.getMessage());
- }
- }
-
- public void testDenyOnRestart() throws Exception
- {
- testDeny(false, new Runnable() {
-
- public void run()
- {
- try
- {
- restartBroker();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testDenyOnRestartInVhost() throws Exception
- {
- testDeny(true, new Runnable() {
-
- public void run()
- {
- try
- {
- restartBroker();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testAllowOnReloadInVhost() throws Exception
- {
- testFirewall(false, true, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testDenyOnReload() throws Exception
- {
- testDeny(false, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- }
- );
- }
-
- public void testDenyOnReloadInVhost() throws Exception
- {
- testDeny(true, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- }
- );
-
- }
-
- private void testDeny(boolean inVhost, Runnable restartOrReload) throws Exception
- {
- testFirewall(true, inVhost, restartOrReload);
- }
-
- /*
- * Check we can get a connection
- */
- private boolean checkConnection() throws Exception
- {
- Exception exception = null;
- Connection conn = null;
- try
- {
- conn = getConnection();
- }
- catch (JMSException e)
- {
- exception = e;
- }
-
- return conn != null;
- }
-
- private void testFirewall(boolean initial, boolean inVhost, Runnable restartOrReload) throws Exception
- {
-
- writeFirewallFile(initial, inVhost);
- setConfigurationProperty("management.enabled", String.valueOf(true));
- super.setUp();
-
- assertEquals("Initial connection check failed", initial, checkConnection());
-
- // Reload changed firewall file after restart or reload
- writeFirewallFile(!initial, inVhost);
- restartOrReload.run();
-
- assertEquals("Second connection check failed", !initial, checkConnection());
- }
-
- private String getIpAddressOfBrokerHost()
- {
- String brokerHost = getBroker().getHost();
- try
- {
- return InetAddress.getByName(brokerHost).getHostAddress();
- }
- catch (UnknownHostException e)
- {
- throw new RuntimeException("Could not determine IP address of host : " + brokerHost, e);
- }
-
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java b/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
index c38fcd9199..6d53896371 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
@@ -27,10 +27,13 @@ import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.model.Broker;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
import org.apache.qpid.util.LogMonitor;
import java.util.List;
+import java.util.Map;
import javax.jms.Connection;
import javax.jms.Destination;
@@ -45,46 +48,55 @@ import javax.jms.TextMessage;
*/
public class StatisticsReportingTest extends QpidBrokerTestCase
{
+ private static final String VHOST_NAME1 = "vhost1";
+ private static final String VHOST_NAME2 = "vhost2";
+ private static final String VHOST_NAME3 = "vhost3";
+ private static long STATISTICS_REPORTING_PERIOD_IN_SECONDS = 10l;
+
protected LogMonitor _monitor;
protected static final String USER = "admin";
- protected Connection _test, _dev, _local;
+ protected Connection _conToVhost1, _conToVhost2, _conToVhost3;
protected String _queueName = "statistics";
protected Destination _queue;
protected String _brokerUrl;
+ private long _startTestTime;
@Override
public void setUp() throws Exception
{
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
+ createTestVirtualHost(0, VHOST_NAME1);
+ createTestVirtualHost(0, VHOST_NAME2);
+ createTestVirtualHost(0, VHOST_NAME3);
if (getName().equals("testEnabledStatisticsReporting"))
{
- setConfigurationProperty("statistics.reporting.period", "10");
+ TestBrokerConfiguration config = getBrokerConfiguration();
+ config.removeObjectConfiguration(TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST);
+ config.setBrokerAttribute(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SECONDS);
}
_monitor = new LogMonitor(_outputFile);
+ _startTestTime = System.currentTimeMillis();
super.setUp();
_brokerUrl = getBroker().toString();
- _test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- _dev = new AMQConnection(_brokerUrl, USER, USER, "clientid", "development");
- _local = new AMQConnection(_brokerUrl, USER, USER, "clientid", "localhost");
-
- _test.start();
- _dev.start();
- _local.start();
+ _conToVhost1 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME1);
+ _conToVhost2 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME2);
+ _conToVhost3 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME3);
+ _conToVhost1.start();
+ _conToVhost2.start();
+ _conToVhost3.start();
}
@Override
public void tearDown() throws Exception
{
- _test.close();
- _dev.close();
- _local.close();
+ _conToVhost1.close();
+ _conToVhost2.close();
+ _conToVhost3.close();
super.tearDown();
}
@@ -94,21 +106,30 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
*/
public void testEnabledStatisticsReporting() throws Exception
{
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 15, 100);
-
- Thread.sleep(10 * 1000); // 15s
-
- List<String> brokerStatsData = _monitor.findMatches("BRK-1008");
- List<String> brokerStatsMessages = _monitor.findMatches("BRK-1009");
- List<String> vhostStatsData = _monitor.findMatches("VHT-1003");
- List<String> vhostStatsMessages = _monitor.findMatches("VHT-1004");
-
- assertEquals("Incorrect number of broker data stats log messages", 2, brokerStatsData.size());
- assertEquals("Incorrect number of broker message stats log messages", 2, brokerStatsMessages.size());
- assertEquals("Incorrect number of virtualhost data stats log messages", 6, vhostStatsData.size());
- assertEquals("Incorrect number of virtualhost message stats log messages", 6, vhostStatsMessages.size());
+ sendUsing(_conToVhost1, 10, 100);
+ sendUsing(_conToVhost2, 20, 100);
+ sendUsing(_conToVhost3, 15, 100);
+
+ Thread.sleep(STATISTICS_REPORTING_PERIOD_IN_SECONDS * 1000);
+
+ Map<String, List<String>> brokerStatsData = _monitor.findMatches("BRK-1008", "BRK-1009", "VHT-1003", "VHT-1004");
+ long endTestTime = System.currentTimeMillis();
+
+ int maxNumberOfReports = (int)((endTestTime - _startTestTime)/STATISTICS_REPORTING_PERIOD_IN_SECONDS);
+
+ int brk1008LinesNumber = brokerStatsData.get("BRK-1008").size();
+ int brk1009LinesNumber = brokerStatsData.get("BRK-1009").size();
+ int vht1003LinesNumber = brokerStatsData.get("VHT-1003").size();
+ int vht1004LinesNumber = brokerStatsData.get("VHT-1004").size();
+
+ assertTrue("Incorrect number of broker data stats log messages:" + brk1008LinesNumber, 2 <= brk1008LinesNumber
+ && brk1008LinesNumber <= maxNumberOfReports * 2);
+ assertTrue("Incorrect number of broker message stats log messages:" + brk1009LinesNumber, 2 <= brk1009LinesNumber
+ && brk1009LinesNumber <= maxNumberOfReports * 2);
+ assertTrue("Incorrect number of virtualhost data stats log messages:" + vht1003LinesNumber, 6 <= vht1003LinesNumber
+ && vht1003LinesNumber <= maxNumberOfReports * 6);
+ assertTrue("Incorrect number of virtualhost message stats log messages: " + vht1004LinesNumber, 6 <= vht1004LinesNumber
+ && vht1004LinesNumber <= maxNumberOfReports * 6);
}
/**
@@ -116,9 +137,9 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
*/
public void testNotEnabledStatisticsReporting() throws Exception
{
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 15, 100);
+ sendUsing(_conToVhost1, 10, 100);
+ sendUsing(_conToVhost2, 20, 100);
+ sendUsing(_conToVhost3, 15, 100);
Thread.sleep(10 * 1000); // 15s
@@ -135,7 +156,7 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
private void sendUsing(Connection con, int number, int size) throws Exception
{
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session session = con.createSession(true, Session.SESSION_TRANSACTED);
createQueue(session);
MessageProducer producer = session.createProducer(_queue);
String content = new String(new byte[size]);
@@ -144,6 +165,8 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
{
producer.send(msg);
}
+ session.commit();
+ session.close();
}
private void createQueue(Session session) throws AMQException, JMSException
diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java b/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
index 9db04b64b3..6d38004451 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
@@ -27,8 +27,6 @@ import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-import org.apache.qpid.server.federation.BrokerLink;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.AMQQueue;
@@ -322,35 +320,6 @@ public class SlowMessageStore implements MessageStore
doPostDelay("updateQueue");
}
-
- public void createBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- doPreDelay("createBrokerLink");
- _durableConfigurationStore.createBrokerLink(link);
- doPostDelay("createBrokerLink");
- }
-
- public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
- {
- doPreDelay("deleteBrokerLink");
- _durableConfigurationStore.deleteBrokerLink(link);
- doPostDelay("deleteBrokerLink");
- }
-
- public void createBridge(final Bridge bridge) throws AMQStoreException
- {
- doPreDelay("createBridge");
- _durableConfigurationStore.createBridge(bridge);
- doPostDelay("createBridge");
- }
-
- public void deleteBridge(final Bridge bridge) throws AMQStoreException
- {
- doPreDelay("deleteBridge");
- _durableConfigurationStore.deleteBridge(bridge);
- doPostDelay("deleteBridge");
- }
-
@Override
public void activate() throws Exception
{
diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java b/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
index 9fb1db3a4f..61ca6d9c28 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
@@ -60,9 +60,9 @@ public class StoreOverfullTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
- setConfigurationProperty("virtualhosts.virtualhost.test.store.class", QuotaMessageStore.class.getName());
- setConfigurationProperty("virtualhosts.virtualhost.test.store.overfull-size", String.valueOf(OVERFULL_SIZE));
- setConfigurationProperty("virtualhosts.virtualhost.test.store.underfull-size", String.valueOf(UNDERFULL_SIZE));
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.class", QuotaMessageStore.class.getName());
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.overfull-size", String.valueOf(OVERFULL_SIZE));
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.underfull-size", String.valueOf(UNDERFULL_SIZE));
super.setUp();
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java b/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java
deleted file mode 100644
index 9ff143daf3..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java
+++ /dev/null
@@ -1,223 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * QPID-1447 : Add slow consumer detection and disconnection.
- *
- * Slow consumers should on a topic should expect to receive a
- * 506 : Resource Error if the hit a predefined threshold.
- */
-public class GlobalQueuesTest extends TestingBaseCase
-{
-
- protected String CONFIG_SECTION = ".queues";
-
- /**
- * Queue Configuration
-
- <slow-consumer-detection>
- <!-- The depth before which the policy will be applied-->
- <depth>4235264</depth>
-
- <!-- The message age before which the policy will be applied-->
- <messageAge>600000</messageAge>
-
- <!-- The number of message before which the policy will be applied-->
- <messageCount>50</messageCount>
-
- <!-- Policies configuration -->
- <policy>
- <name>TopicDelete</name>
- <topicDelete>
- <delete-persistent/>
- </topicDelete>
- </policy>
- </slow-consumer-detection>
-
- */
-
-
- /**
- * VirtualHost Plugin Configuration
-
- <slow-consumer-detection>
- <delay>1</delay>
- <timeunit>MINUTES</timeunit>
- </slow-consumer-detection>
-
- */
-
- public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
- {
- setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
- "policy.name", "TopicDelete");
-
- setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
- property, value);
-
- if (deleteDurable)
- {
- setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
- "policy.topicdelete.delete-persistent", "");
- }
- }
-
- /**
- * Test that setting messageCount takes affect on topics
- *
- * We send 10 messages and disconnect at 9
- *
- * @throws Exception
- */
- public void testTopicConsumerMessageCount() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), false);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
- }
-
- /**
- * Test that setting depth has an effect on topics
- *
- * Sets the message size for the test
- * Sets the depth to be 9 * the depth
- * Ensure that sending 10 messages causes the disconnection
- *
- * @throws Exception
- */
- public void testTopicConsumerMessageSize() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), false);
-
- //Start the broker
- startBroker();
-
- setMessageSize(MESSAGE_SIZE);
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
- }
-
- /**
- * Test that setting messageAge has an effect on topics
- *
- * Sets the messageAge to be half the disconnection wait timeout
- * Send 10 messages and then ensure that we get disconnected as we will
- * wait for the full timeout.
- *
- * @throws Exception
- */
- public void testTopicConsumerMessageAge() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 2), false);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
- }
-
- /**
- * Test that setting messageCount takes affect on a durable Consumer
- *
- * Ensure we set the delete-persistent option
- *
- * We send 10 messages and disconnect at 9
- *
- * @throws Exception
- */
-
- public void testTopicDurableConsumerMessageCount() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), true);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
- /**
- * Test that setting depth has an effect on durable consumer topics
- *
- * Ensure we set the delete-persistent option
- *
- * Sets the message size for the test
- * Sets the depth to be 9 * the depth
- * Ensure that sending 10 messages causes the disconnection
- *
- * @throws Exception
- */
- public void testTopicDurableConsumerMessageSize() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), true);
-
- //Start the broker
- startBroker();
-
- setMessageSize(MESSAGE_SIZE);
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
- /**
- * Test that setting messageAge has an effect on topics
- *
- * Ensure we set the delete-persistent option
- *
- * Sets the messageAge to be 1/5 the disconnection wait timeout (or 1sec)
- * Send 10 messages and then ensure that we get disconnected as we will
- * wait for the full timeout.
- *
- * @throws Exception
- */
- public void testTopicDurableConsumerMessageAge() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 5), true);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java b/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java
deleted file mode 100644
index 993d71ea34..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java
+++ /dev/null
@@ -1,109 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-public class MergeConfigurationTest extends TestingBaseCase
-{
-
- protected int topicCount = 0;
-
-
- public void configureTopic(String topic, int msgCount) throws NamingException, IOException, ConfigurationException
- {
-
- setProperty(".topics.topic("+topicCount+").name", topic);
- setProperty(".topics.topic("+topicCount+").slow-consumer-detection.messageCount", String.valueOf(msgCount));
- setProperty(".topics.topic("+topicCount+").slow-consumer-detection.policy.name", "TopicDelete");
- topicCount++;
- }
-
-
- /**
- * Test that setting messageCount takes affect on topics
- *
- * We send 10 messages and disconnect at 9
- *
- * @throws Exception
- */
- public void testTopicConsumerMessageCount() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- configureTopic(getName(), (MAX_QUEUE_MESSAGE_COUNT * 4) - 1);
-
- //Configure topic as a subscription
- setProperty(".topics.topic("+topicCount+").subscriptionName", "clientid:"+getTestQueueName());
- configureTopic(getName(), (MAX_QUEUE_MESSAGE_COUNT - 1));
-
-
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
-
-//
-// public void testMerge() throws ConfigurationException, AMQException
-// {
-//
-// AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(getName()+":stockSubscription"), false, new AMQShortString("testowner"),
-// false, false, _virtualHost, null);
-//
-// _virtualHost.getQueueRegistry().registerQueue(queue);
-// Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
-// _virtualHost.getBindingFactory().addBinding(getName(), queue, defaultExchange, null);
-//
-//
-// Exchange topicExchange = _virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME);
-// _virtualHost.getBindingFactory().addBinding("stocks.nyse.orcl", queue, topicExchange, null);
-//
-// TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName());
-//
-// assertNotNull("Queue should have topic configuration bound to it.", config);
-// assertEquals("Configuration name not correct", getName() + ":stockSubscription", config.getSubscriptionName());
-//
-// ConfigurationPlugin scdConfig = queue.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName());
-// if (scdConfig instanceof org.apache.qpid.server.configuration.plugin.SlowConsumerDetectionQueueConfiguration)
-// {
-// System.err.println("********************** scd is a SlowConsumerDetectionQueueConfiguration.");
-// }
-// else
-// {
-// System.err.println("********************** Test SCD "+SlowConsumerDetectionQueueConfiguration.class.getClassLoader());
-// System.err.println("********************** Broker SCD "+scdConfig.getClass().getClassLoader());
-// System.err.println("********************** Broker SCD "+scdConfig.getClass().isAssignableFrom(SlowConsumerDetectionQueueConfiguration.class));
-// System.err.println("********************** is a "+scdConfig.getClass());
-// }
-//
-// assertNotNull("Queue should have scd configuration bound to it.", scdConfig);
-// assertEquals("MessageCount is not correct", 10 , ((SlowConsumerDetectionQueueConfiguration)scdConfig).getMessageCount());
-// assertEquals("Policy is not correct", TopicDeletePolicy.class.getName() , ((SlowConsumerDetectionQueueConfiguration)scdConfig).getPolicy().getClass().getName());
-// }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java b/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java
deleted file mode 100644
index 9e9375fd44..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * Test SCD when configured with Subscription details.
- *
- * We run the subscription based tests here to validate that the
- * subscriptionname value is correctly associated with the subscription.
- *
- *
- */
-public class SubscriptionTest extends TestingBaseCase
-{
- private int _count=0;
- protected String CONFIG_SECTION = ".topics.topic";
-
- /**
- * Add configuration for the queue that relates just to this test.
- * We use the getTestQueueName() as our subscription. To ensure the
- * config sections do not overlap we identify each section with a _count
- * value.
- *
- * This would allow each test to configure more than one section.
- *
- * @param property to set
- * @param value the value to set
- * @param deleteDurable should deleteDurable be set.
- * @throws NamingException
- * @throws IOException
- * @throws ConfigurationException
- */
- public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
- {
- setProperty(CONFIG_SECTION + "("+_count+").subscriptionName", "clientid:"+getTestQueueName());
-
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- "policy.name", "TopicDelete");
-
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- property, value);
-
- if (deleteDurable)
- {
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- "policy.topicdelete.delete-persistent", "");
- }
- _count++;
- }
-
-
- /**
- * Test that setting messageCount takes affect on a durable Consumer
- *
- * Ensure we set the delete-persistent option
- *
- * We send 10 messages and disconnect at 9
- *
- * @throws Exception
- */
-
- public void testTopicDurableConsumerMessageCount() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), true);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
- /**
- * Test that setting depth has an effect on durable consumer topics
- *
- * Ensure we set the delete-persistent option
- *
- * Sets the message size for the test
- * Sets the depth to be 9 * the depth
- * Ensure that sending 10 messages causes the disconnection
- *
- * @throws Exception
- */
- public void testTopicDurableConsumerMessageSize() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), true);
-
- //Start the broker
- startBroker();
-
- setMessageSize(MESSAGE_SIZE);
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
- /**
- * Test that setting messageAge has an effect on topics
- *
- * Ensure we set the delete-persistent option
- *
- * Sets the messageAge to be 1/5 the disconnection wait timeout (or 1sec)
- * Send 10 messages and then ensure that we get disconnected as we will
- * wait for the full timeout.
- *
- * @throws Exception
- */
- public void testTopicDurableConsumerMessageAge() throws Exception
- {
- MAX_QUEUE_MESSAGE_COUNT = 10;
-
- setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 5), true);
-
- //Start the broker
- startBroker();
-
- topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
- }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java b/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java
deleted file mode 100644
index 86c9462fc9..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java
+++ /dev/null
@@ -1,240 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.jms.ConnectionListener;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.naming.NamingException;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class TestingBaseCase extends QpidBrokerTestCase implements ExceptionListener, ConnectionListener
-{
-
- private Topic _destination;
- protected CountDownLatch _disconnectionLatch = new CountDownLatch(1);
- protected int MAX_QUEUE_MESSAGE_COUNT;
- protected int MESSAGE_SIZE = DEFAULT_MESSAGE_SIZE;
-
- private Thread _publisher;
- protected static final long DISCONNECTION_WAIT = 5;
- protected Exception _publisherError = null;
- protected JMSException _connectionException = null;
- private static final long JOIN_WAIT = 5000;
-
- @Override
- public void setUp() throws Exception
- {
-
- setConfigurationProperty("virtualhosts.virtualhost."
- + getConnectionURL().getVirtualHost().substring(1) +
- ".slow-consumer-detection.delay", "1");
-
- setConfigurationProperty("virtualhosts.virtualhost."
- + getConnectionURL().getVirtualHost().substring(1) +
- ".slow-consumer-detection.timeunit", "SECONDS");
-
- }
-
-
- protected void setProperty(String property, String value) throws NamingException, IOException, ConfigurationException
- {
- setConfigurationProperty("virtualhosts.virtualhost." +
- getConnectionURL().getVirtualHost().substring(1) +
- property, value);
- }
-
-
- /**
- * Create and start an asynchrounous publisher that will send MAX_QUEUE_MESSAGE_COUNT
- * messages to the provided destination. Messages are sent in a new connection
- * on a transaction. Any error is captured and the test is signalled to exit.
- *
- * @param destination
- */
- private void startPublisher(final Destination destination)
- {
- _publisher = new Thread(new Runnable()
- {
-
- public void run()
- {
- try
- {
- Connection connection = getConnection();
- Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
-
- MessageProducer publisher = session.createProducer(destination);
-
- for (int count = 0; count < MAX_QUEUE_MESSAGE_COUNT; count++)
- {
- publisher.send(createNextMessage(session, count));
- session.commit();
- }
- }
- catch (Exception e)
- {
- _publisherError = e;
- _disconnectionLatch.countDown();
- }
- }
- });
-
- _publisher.start();
- }
-
-
-
- /**
- * Perform the Main test of a topic Consumer with the given AckMode.
- *
- * Test creates a new connection and sets up the connection to prevent
- * failover
- *
- * A new consumer is connected and started so that it will prefetch msgs.
- *
- * An asynchrounous publisher is started to fill the broker with messages.
- *
- * We then wait to be notified of the disconnection via the ExceptionListener
- *
- * 0-10 does not have the same notification paths but sync() apparently should
- * give us the exception, currently it doesn't, so the test is excluded from 0-10
- *
- * We should ensure that this test has the same path for all protocol versions.
- *
- * Clients should not have to modify their code based on the protocol in use.
- *
- * @param ackMode @see javax.jms.Session
- *
- * @throws Exception
- */
- protected void topicConsumer(int ackMode, boolean durable) throws Exception
- {
- Connection connection = getConnection();
-
- connection.setExceptionListener(this);
-
- Session session = connection.createSession(ackMode == Session.SESSION_TRANSACTED, ackMode);
-
- _destination = session.createTopic(getName());
-
- MessageConsumer consumer;
-
- if (durable)
- {
- consumer = session.createDurableSubscriber(_destination, getTestQueueName());
- }
- else
- {
- consumer = session.createConsumer(_destination);
- }
-
- connection.start();
-
- // Start the consumer pre-fetching
- // Don't care about response as we will fill the broker up with messages
- // after this point and ensure that the client is disconnected at the
- // right point.
- consumer.receiveNoWait();
- startPublisher(_destination);
-
- boolean disconnected = _disconnectionLatch.await(DISCONNECTION_WAIT, TimeUnit.SECONDS);
-
- assertTrue("Client was not disconnected", disconnected);
- assertTrue("Client was not disconnected.", _connectionException != null);
-
- Exception linked = _connectionException.getLinkedException();
-
- _publisher.join(JOIN_WAIT);
-
- assertFalse("Publisher still running", _publisher.isAlive());
-
- //Validate publishing occurred ok
- if (_publisherError != null)
- {
- throw _publisherError;
- }
-
- // NOTE these exceptions will need to be modeled so that they are not
- // 0-8 specific. e.g. JMSSessionClosedException
-
- assertNotNull("No error received onException listener.", _connectionException);
-
- assertNotNull("No linked exception set on:" + _connectionException.getMessage(), linked);
-
- assertTrue("Incorrect linked exception received.", linked instanceof AMQException);
-
- AMQException amqException = (AMQException) linked;
-
- assertEquals("Channel was not closed with correct code.", AMQConstant.RESOURCE_ERROR, amqException.getErrorCode());
- }
-
-
- // Exception Listener
-
- public void onException(JMSException e)
- {
- _connectionException = e;
-
- e.printStackTrace();
-
- _disconnectionLatch.countDown();
- }
-
- /// Connection Listener
-
- public void bytesSent(long count)
- {
- }
-
- public void bytesReceived(long count)
- {
- }
-
- public boolean preFailover(boolean redirect)
- {
- // Prevent Failover
- return false;
- }
-
- public boolean preResubscribe()
- {
- return false;
- }
-
- public void failoverComplete()
- {
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java b/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java
deleted file mode 100644
index 09c849cfde..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * This Topic test extends the Global queue test so it will run all the topic
- * and subscription tests.
- *
- * We redefine the CONFIG_SECTION here so that the configuration is written
- * against a topic element.
- *
- * To complete the migration to testing 'topic' elements we also override
- * the setConfig to use the test name as the topic name.
- *
- */
-public class TopicTest extends GlobalQueuesTest
-{
- private int _count=0;
-
- @Override
- public void setUp() throws Exception
- {
- CONFIG_SECTION = ".topics.topic";
- super.setUp();
- }
-
- /**
- * Add configuration for the queue that relates just to this test.
- * We use the getTestQueueName() as our subscription. To ensure the
- * config sections do not overlap we identify each section with a _count
- * value.
- *
- * This would allow each test to configure more than one section.
- *
- * @param property to set
- * @param value the value to set
- * @param deleteDurable should deleteDurable be set.
- * @throws NamingException
- * @throws IOException
- * @throws ConfigurationException
- */
- @Override
- public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
- {
- setProperty(CONFIG_SECTION + "("+_count+").name", getName());
-
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- "policy.name", "TopicDelete");
-
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- property, value);
-
- if (deleteDurable)
- {
- setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
- "policy.topicdelete.delete-persistent", "");
- }
- _count++;
- }
-
-
-}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
index 7473a4d3e7..954208e78e 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
@@ -107,6 +107,8 @@ public class BrokerManagementTest extends QpidBrokerTestCase
{
String defaultExchangeName = ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString();
+ ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
+ assertNotNull("Exchange should exist", defaultExchange);
try
{
_managedBroker.unregisterExchange(defaultExchangeName);
@@ -117,7 +119,7 @@ public class BrokerManagementTest extends QpidBrokerTestCase
// PASS
assertEquals("'<<default>>' is a reserved exchange and can't be deleted", e.getMessage());
}
- final ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
+ defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
assertNotNull("Exchange should exist", defaultExchange);
}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
index 28d7bf4aed..28d7bf4aed 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
index ac6730638e..3c3bbdca41 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
@@ -25,8 +25,7 @@ import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
-import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBeanTest;
-import org.apache.qpid.server.logging.log4j.LoggingFacadeTest;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacadeTest;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.util.FileUtils;
@@ -37,7 +36,7 @@ import org.apache.qpid.util.LogMonitor;
* test-profiles/log4j-test.xml</b>.
*
* @see LoggingManagementMBeanTest
- * @see LoggingFacadeTest
+ * @see LoggingManagementFacadeTest
*
*/
public class LoggingManagementTest extends QpidBrokerTestCase
@@ -56,9 +55,8 @@ public class LoggingManagementTest extends QpidBrokerTestCase
File tmpLogFile = File.createTempFile("log4j" + "." + getName(), ".xml");
tmpLogFile.deleteOnExit();
- FileUtils.copy(_logConfigFile, tmpLogFile);
-
- _logConfigFile = tmpLogFile;
+ FileUtils.copy(getBrokerCommandLog4JFile(), tmpLogFile);
+ setBrokerCommandLog4JFile(tmpLogFile);
super.setUp();
_jmxUtils.open();
@@ -106,7 +104,7 @@ public class LoggingManagementTest extends QpidBrokerTestCase
_monitor.markDiscardPoint();
_loggingManagement.setRuntimeLoggerLevel(logger, "OFF");
- List<String> matches = _monitor.findMatches("Setting level to OFF for logger 'org.apache.qpid'");
+ List<String> matches = _monitor.waitAndFindMatches("Setting level to OFF for logger 'org.apache.qpid'", 5000);
assertEquals(1, matches.size());
TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
@@ -122,7 +120,7 @@ public class LoggingManagementTest extends QpidBrokerTestCase
_monitor.markDiscardPoint();
_loggingManagement.setConfigFileLoggerLevel(operationalLoggingLogger, "OFF");
- List<String> matches = _monitor.findMatches("Setting level to OFF for logger 'qpid.message'");
+ List<String> matches = _monitor.waitAndFindMatches("Setting level to OFF for logger 'qpid.message'", 5000);
assertEquals(1, matches.size());
assertEffectiveLoggingLevel(operationalLoggingLogger, "INFO");
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
index 47b38381c5..47b38381c5 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
index 6100d5a23e..950b002b87 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
@@ -21,12 +21,16 @@
package org.apache.qpid.systest.management.jmx;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.BrokerProperties;
import org.apache.qpid.server.logging.AbstractTestLogging;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.test.utils.TestSSLConstants;
import org.apache.qpid.util.LogMonitor;
-import java.io.File;
+import java.util.Collections;
import java.util.List;
/**
@@ -36,11 +40,11 @@ import java.util.List;
*
* This suite of tests validate that the management console messages occur correctly and according to the following format:
*
- * MNG-1001 : Startup
+ * MNG-1001 : <type> Management Startup
* MNG-1002 : Starting : <service> : Listening on port <Port>
* MNG-1003 : Shutting down : <service> : port <Port>
- * MNG-1004 : Ready
- * MNG-1005 : Stopped
+ * MNG-1004 : <type> Management Ready
+ * MNG-1005 : <type> Management Stopped
* MNG-1006 : Using SSL Keystore : <path>
* MNG-1007 : Open : User <username>
* MNG-1008 : Close : User <username>
@@ -105,7 +109,7 @@ public class ManagementLoggingTest extends AbstractTestLogging
2, results.size());
//3
- assertEquals("Startup log message is not 'Startup'.", "Startup",
+ assertEquals("Startup log message is not 'Startup'.", "JMX Management Startup",
getMessageString(log));
}
}
@@ -202,7 +206,7 @@ public class ManagementLoggingTest extends AbstractTestLogging
// We expect the RMI Registry port (the defined 'management port') to be
// 100 lower than the JMX RMIConnector Server Port (the actual JMX server)
- int jmxPort = mPort + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET;
+ int jmxPort = mPort + JMXPORT_CONNECTORSERVER_OFFSET;
assertTrue("JMX RMIConnectorServer port not as expected(" + jmxPort + ").:" + getMessageString(log),
getMessageString(log).endsWith(String.valueOf(jmxPort)));
}
@@ -226,6 +230,7 @@ public class ManagementLoggingTest extends AbstractTestLogging
{
if (isJavaBroker())
{
+ setSystemProperty("javax.net.debug", "ssl");
startBrokerAndCreateMonitor(true, true);
List<String> results = waitAndFindMatches("MNG-1006");
@@ -244,7 +249,7 @@ public class ManagementLoggingTest extends AbstractTestLogging
// Validate the keystore path is as expected
assertTrue("SSL Keystore entry expected.:" + getMessageString(log),
- getMessageString(log).endsWith(new File(getConfigurationStringProperty("management.ssl.keyStorePath")).getName()));
+ getMessageString(log).endsWith(TestSSLConstants.BROKER_KEYSTORE));
}
}
@@ -265,6 +270,7 @@ public class ManagementLoggingTest extends AbstractTestLogging
{
if (isJavaBroker())
{
+ setSystemProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, "false");
startBrokerAndCreateMonitor(true, false);
final JMXTestUtils jmxUtils = new JMXTestUtils(this);
@@ -300,13 +306,20 @@ public class ManagementLoggingTest extends AbstractTestLogging
private void startBrokerAndCreateMonitor(boolean managementEnabled, boolean useManagementSSL) throws Exception
{
- //Ensure management is on
- setConfigurationProperty("management.enabled", String.valueOf(managementEnabled));
+ TestBrokerConfiguration config = getBrokerConfiguration();
+
+ if (managementEnabled)
+ {
+ config.addJmxManagementConfiguration();
+ }
if(useManagementSSL)
{
// This test requires we have an ssl connection
- setConfigurationProperty("management.ssl.enabled", "true");
+ config.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_JMX_PORT, Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+
+ setSystemProperty("javax.net.ssl.keyStore", "test-profiles/test_resources/ssl/java_broker_keystore.jks");
+ setSystemProperty("javax.net.ssl.keyStorePassword", "password");
}
startBroker();
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
index 79d04b239e..0d3289d1bd 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
@@ -206,13 +206,41 @@ public class QueueManagementTest extends QpidBrokerTestCase
managedBroker.createNewQueue(queueName, null, true, arguments);
// Ensure the queue exists
- assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName("test", queueName));
+ assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
assertEquals("Unexpected maximum delivery count", deliveryCount, managedQueue.getMaximumDeliveryCount());
}
+ public void testCreateQueueWithAlertingThresholdsSet() throws Exception
+ {
+ final String queueName = getName();
+ final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
+
+ final Long maximumMessageCount = 100l;
+ final Long maximumMessageSize = 200l;
+ final Long maximumQueueDepth = 300l;
+ final Long maximumMessageAge = 400l;
+ final Map<String, Object> arguments = new HashMap<String, Object>();
+ arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_COUNT, maximumMessageCount);
+ arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_SIZE, maximumMessageSize);
+ arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_QUEUE_DEPTH, maximumQueueDepth);
+ arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_AGE, maximumMessageAge);
+
+ managedBroker.createNewQueue(queueName, null, true, arguments);
+
+ // Ensure the queue exists
+ assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
+ assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
+
+ ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+ assertEquals("Unexpected maximum message count", maximumMessageCount, managedQueue.getMaximumMessageCount());
+ assertEquals("Unexpected maximum message size", maximumMessageSize, managedQueue.getMaximumMessageSize());
+ assertEquals("Unexpected maximum queue depth", maximumQueueDepth, managedQueue.getMaximumQueueDepth());
+ assertEquals("Unexpected maximum message age", maximumMessageAge, managedQueue.getMaximumMessageAge());
+ }
+
/**
* Requires 0-10 as relies on ADDR addresses.
* @see AddressBasedDestinationTest for the testing of message routing to the alternate exchange
@@ -552,6 +580,60 @@ public class QueueManagementTest extends QpidBrokerTestCase
assertMessageIndicesOn(_destinationQueue, 0);
}
+ /**
+ * Tests {@link ManagedQueue#deleteMessages(long, long)} interface.
+ */
+ public void testDeleteMessages() throws Exception
+ {
+ final int numberOfMessagesToSend = 15;
+
+ sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+ syncSession(_session);
+ assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+ List<Long> amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+ // Current expected queue state, in terms of message header indices: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
+
+ // Delete the first message (Remember the amqMessagesIds list, and the message indices added as a property when sending, are both 0-based index)
+ long fromMessageId = amqMessagesIds.get(0);
+ long toMessageId = fromMessageId;
+ _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+ assertEquals("Unexpected message count after first deletion", numberOfMessagesToSend - 1, _managedSourceQueue.getMessageCount().intValue());
+ // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
+
+ // Delete the 9th-10th messages, in the middle of the queue
+ fromMessageId = amqMessagesIds.get(8);
+ toMessageId = amqMessagesIds.get(9);
+ _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+ assertEquals("Unexpected message count after third deletion", numberOfMessagesToSend - 3, _managedSourceQueue.getMessageCount().intValue());
+ // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,X,X,10,11,12,13,14]
+
+ // Delete the 11th and 12th messages, but still include the IDs for the 9th and 10th messages in the
+ // range to ensure their IDs are 'skipped' until the matching messages are found
+ fromMessageId = amqMessagesIds.get(8);
+ toMessageId = amqMessagesIds.get(11);
+ _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+ assertEquals("Unexpected message count after fourth deletion", numberOfMessagesToSend - 5, _managedSourceQueue.getMessageCount().intValue());
+ // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,X,X,X,X,12,13,14]
+
+ // Delete the 8th message and the 13th message, including the IDs for the 9th-12th messages in the
+ // range to ensure their IDs are 'skipped' and the other matching message is found
+ fromMessageId = amqMessagesIds.get(7);
+ toMessageId = amqMessagesIds.get(12);
+ _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+ assertEquals("Unexpected message count after fourth deletion", numberOfMessagesToSend - 7, _managedSourceQueue.getMessageCount().intValue());
+ // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,X,X,X,X,X,X,13,14]
+
+ // Delete the last message message
+ fromMessageId = amqMessagesIds.get(numberOfMessagesToSend -1);
+ toMessageId = fromMessageId;
+ _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+ assertEquals("Unexpected message count after second deletion", numberOfMessagesToSend - 8, _managedSourceQueue.getMessageCount().intValue());
+ // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,X,X,X,X,X,X,13,X]
+
+ // Verify the message indices with a consumer
+ assertMessageIndicesOn(_sourceQueue, 1,2,3,4,5,6,13);
+ }
+
@Override
public Message createNextMessage(Session session, int messageNumber) throws JMSException
{
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
index c3fff94923..72fbd65acc 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
@@ -36,42 +36,48 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
public class StatisticsTest extends QpidBrokerTestCase
{
+ private static final String TEST_VIRTUALHOST1 = "test1";
+ private static final String TEST_VIRTUALHOST2 = "test2";
+
private static final String TEST_USER = "admin";
private static final String TEST_PASSWORD = "admin";
private static final int MESSAGE_COUNT_TEST = 5;
private static final int MESSAGE_COUNT_DEV = 9;
private JMXTestUtils _jmxUtils;
- private Connection _test1, _dev;
- private Session _testSession, _developmentSession;
- private Queue _developmentQueue, _testQueue;
+ private Connection _vhost1Connection, _vhost2Connection;
+ private Session _vhost1Session, _vhost2Session;
+ private Queue _vhost1Queue, _vhost2Queue;
protected String _brokerUrl;
@Override
public void setUp() throws Exception
{
+ createTestVirtualHost(0, TEST_VIRTUALHOST1);
+ createTestVirtualHost(0, TEST_VIRTUALHOST2);
+
_jmxUtils = new JMXTestUtils(this, TEST_USER, TEST_PASSWORD);
_jmxUtils.setUp();
super.setUp();
_brokerUrl = getBroker().toString();
- _test1 = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", "test");
- _dev = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", "development");
- _test1.start();
- _dev.start();
+ _vhost1Connection = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", TEST_VIRTUALHOST1);
+ _vhost2Connection = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", TEST_VIRTUALHOST2);
+ _vhost1Connection.start();
+ _vhost2Connection.start();
- _testSession = _test1.createSession(true, Session.SESSION_TRANSACTED);
- _developmentSession = _dev.createSession(true, Session.SESSION_TRANSACTED);
+ _vhost1Session = _vhost1Connection.createSession(true, Session.SESSION_TRANSACTED);
+ _vhost2Session = _vhost2Connection.createSession(true, Session.SESSION_TRANSACTED);
- _developmentQueue = _developmentSession.createQueue(getTestQueueName());
- _testQueue = _testSession.createQueue(getTestQueueName());
+ _vhost1Queue = _vhost2Session.createQueue(getTestQueueName());
+ _vhost2Queue = _vhost1Session.createQueue(getTestQueueName());
//Create queues by opening and closing consumers
- final MessageConsumer testConsumer = _testSession.createConsumer(_testQueue);
- testConsumer.close();
- final MessageConsumer developmentConsumer = _developmentSession.createConsumer(_developmentQueue);
- developmentConsumer.close();
+ final MessageConsumer vhost1Consumer = _vhost1Session.createConsumer(_vhost2Queue);
+ vhost1Consumer.close();
+ final MessageConsumer vhost2Consumer = _vhost2Session.createConsumer(_vhost1Queue);
+ vhost2Consumer.close();
_jmxUtils.open();
}
@@ -87,63 +93,63 @@ public class StatisticsTest extends QpidBrokerTestCase
public void testInitialStatisticValues() throws Exception
{
//Check initial values
- checkSingleConnectionOnVHostStatistics("test", 0, 0, 0, 0);
- checkVHostStatistics("test", 0, 0, 0, 0);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, 0, 0, 0, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST1, 0, 0, 0, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
checkBrokerStatistics(0, 0, 0, 0);
}
public void testSendOnSingleVHost() throws Exception
{
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
+ sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
//Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
checkBrokerStatistics(MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
}
public void testSendOnTwoVHosts() throws Exception
{
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- sendMessagesAndSync(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
+ sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+ sendMessagesAndSync(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
//Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
- checkSingleConnectionOnVHostStatistics("development", MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
- checkVHostStatistics("development", MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST2, MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, 0, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, 0);
}
public void testSendAndConsumeOnSingleVHost() throws Exception
{
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- consumeMessages(_testSession, _testQueue, MESSAGE_COUNT_TEST);
+ sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+ consumeMessages(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
//Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkSingleConnectionOnVHostStatistics("development", 0, 0, 0, 0);
- checkVHostStatistics("development", 0, 0, 0, 0);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+ checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+ checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
checkBrokerStatistics(MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
}
public void testSendAndConsumeOnTwoVHosts() throws Exception
{
- sendMessagesAndSync(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- sendMessagesAndSync(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
- consumeMessages(_testSession, _testQueue, MESSAGE_COUNT_TEST);
- consumeMessages(_developmentSession, _developmentQueue, MESSAGE_COUNT_DEV);
+ sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+ sendMessagesAndSync(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
+ consumeMessages(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+ consumeMessages(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
//Check values
- checkSingleConnectionOnVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("test", MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
- checkSingleConnectionOnVHostStatistics("development", MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
- checkVHostStatistics("development", MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+ checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+ checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
+ checkVHostStatistics(TEST_VIRTUALHOST2, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE);
}
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
index 62b1b554a9..7eff1c89ee 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
@@ -23,15 +23,23 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import javax.jms.Connection;
import javax.jms.JMSException;
import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory;
import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
import org.apache.qpid.tools.security.Passwd;
/**
@@ -53,9 +61,10 @@ public class UserManagementTest extends QpidBrokerTestCase
_passwd = createPasswordEncodingUtility();
_passwordFile = createTemporaryPasswordFileWithJmxAdminUser();
- setConfigurationProperty("security.pd-auth-manager.principal-database.class", getPrincipalDatabaseImplClass().getName());
- setConfigurationProperty("security.pd-auth-manager.principal-database.attributes.attribute.name", "passwordFile");
- setConfigurationProperty("security.pd-auth-manager.principal-database.attributes.attribute.value", _passwordFile.getAbsolutePath());
+ Map<String, Object> newAttributes = new HashMap<String, Object>();
+ newAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, getAuthenticationManagerType());
+ newAttributes.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _passwordFile.getAbsolutePath());
+ getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER, newAttributes);
_jmxUtils = new JMXTestUtils(this);
_jmxUtils.setUp();
@@ -163,9 +172,9 @@ public class UserManagementTest extends QpidBrokerTestCase
};
}
- protected Class<? extends PrincipalDatabase> getPrincipalDatabaseImplClass()
+ protected String getAuthenticationManagerType()
{
- return PlainPasswordFilePrincipalDatabase.class;
+ return PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE;
}
private File createTemporaryPasswordFileWithJmxAdminUser() throws Exception
diff --git a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
index 84a66232ce..1423bc557e 100644
--- a/java/broker-plugins/management-jmx/src/test/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
@@ -18,8 +18,7 @@
*/
package org.apache.qpid.systest.management.jmx;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory;
import org.apache.qpid.tools.security.Passwd;
public class UserManagementWithBase64MD5PasswordsTest extends UserManagementTest
@@ -31,9 +30,8 @@ public class UserManagementWithBase64MD5PasswordsTest extends UserManagementTest
}
@Override
- protected Class<? extends PrincipalDatabase> getPrincipalDatabaseImplClass()
+ protected String getAuthenticationManagerType()
{
- return Base64MD5PasswordFilePrincipalDatabase.class;
+ return Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE;
}
-
}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
index 2595007574..16253139ce 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/Asserts.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -37,6 +37,7 @@ 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.Protocol;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.VirtualHost;
@@ -49,7 +50,7 @@ public class Asserts
{
assertNotNull("Virtualhost " + virtualHostName + " data are not found", virtualHost);
assertAttributesPresent(virtualHost, VirtualHost.AVAILABLE_ATTRIBUTES, VirtualHost.TIME_TO_LIVE,
- VirtualHost.CREATED, VirtualHost.UPDATED, VirtualHost.SUPPORTED_QUEUE_TYPES, VirtualHost.STORE_CONFIGURATION);
+ VirtualHost.CREATED, VirtualHost.UPDATED, VirtualHost.SUPPORTED_QUEUE_TYPES, VirtualHost.STORE_PATH, VirtualHost.CONFIG_PATH);
assertEquals("Unexpected value of attribute " + VirtualHost.NAME, virtualHostName, virtualHost.get(VirtualHost.NAME));
assertNotNull("Unexpected value of attribute " + VirtualHost.ID, virtualHost.get(VirtualHost.ID));
@@ -65,7 +66,7 @@ public class Asserts
@SuppressWarnings("unchecked")
Collection<String> exchangeTypes = (Collection<String>) virtualHost.get(VirtualHost.SUPPORTED_EXCHANGE_TYPES);
assertEquals("Unexpected value of attribute " + VirtualHost.SUPPORTED_EXCHANGE_TYPES,
- new HashSet<String>(Arrays.asList("headers", "topic", "direct", "fanout", "management")),
+ new HashSet<String>(Arrays.asList("headers", "topic", "direct", "fanout")),
new HashSet<String>(exchangeTypes));
@SuppressWarnings("unchecked")
@@ -180,7 +181,6 @@ public class Asserts
public static void assertPortAttributes(Map<String, Object> port)
{
- assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED);
assertNotNull("Unexpected value of attribute " + Port.ID, port.get(Port.ID));
assertEquals("Unexpected value of attribute " + Port.DURABLE, Boolean.FALSE, port.get(Port.DURABLE));
@@ -188,9 +188,30 @@ public class Asserts
port.get(Broker.LIFETIME_POLICY));
assertEquals("Unexpected value of attribute " + Port.STATE, State.ACTIVE.name(), port.get(Port.STATE));
assertEquals("Unexpected value of attribute " + Port.TIME_TO_LIVE, 0, port.get(Port.TIME_TO_LIVE));
- assertNotNull("Unexpected value of attribute " + Port.BINDING_ADDRESS, port.get(Port.BINDING_ADDRESS));
- assertNotNull("Unexpected value of attribute " + Port.PROTOCOLS, port.get(Port.PROTOCOLS));
- assertNotNull("Unexpected value of attribute " + Port.NAME, port.get(Port.NAME));
+
+ @SuppressWarnings("unchecked")
+ Collection<String> protocols = (Collection<String>) port.get(Port.PROTOCOLS);
+ assertNotNull("Unexpected value of attribute " + Port.PROTOCOLS, protocols);
+ boolean isAMQPPort = false;
+ for (String protocolName : protocols)
+ {
+ if (Protocol.valueOf(protocolName).isAMQP())
+ {
+ isAMQPPort = true;
+ break;
+ }
+ }
+ if (isAMQPPort)
+ {
+ assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED, Port.AUTHENTICATION_MANAGER);
+ assertNotNull("Unexpected value of attribute " + Port.BINDING_ADDRESS, port.get(Port.BINDING_ADDRESS));
+ }
+ else
+ {
+ assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED, Port.AUTHENTICATION_MANAGER,
+ Port.BINDING_ADDRESS, Port.TCP_NO_DELAY, Port.SEND_BUFFER_SIZE, Port.RECEIVE_BUFFER_SIZE,
+ Port.NEED_CLIENT_AUTH, Port.WANT_CLIENT_AUTH);
+ }
@SuppressWarnings("unchecked")
Collection<String> transports = (Collection<String>) port.get(Port.TRANSPORTS);
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
index 5e6d9a998a..a171b4459b 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/AuthenticationProviderRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.util.List;
import java.util.Map;
@@ -33,13 +33,13 @@ public class AuthenticationProviderRestTest extends QpidRestTestCase
public void testGet() throws Exception
{
- List<Map<String, Object>> providerDetails = getJsonAsList("/rest/authenticationprovider");
+ List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider");
assertNotNull("Providers details cannot be null", providerDetails);
assertEquals("Unexpected number of providers", 1, providerDetails.size());
for (Map<String, Object> provider : providerDetails)
{
assertProvider("PrincipalDatabaseAuthenticationManager", provider);
- Map<String, Object> data = getJsonAsSingletonList("/rest/authenticationprovider/"
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/"
+ provider.get(AuthenticationProvider.NAME));
assertNotNull("Cannot load data for " + provider.get(AuthenticationProvider.NAME), data);
assertProvider("PrincipalDatabaseAuthenticationManager", data);
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java
new file mode 100644
index 0000000000..0574b6cc24
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java
@@ -0,0 +1,121 @@
+/*
+ *
+ * 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.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.Collections;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class BasicAuthRestTest extends QpidRestTestCase
+{
+ private static final String USERNAME = "admin";
+
+ @Override
+ public void setUp() throws Exception
+ {
+ setSystemProperty("javax.net.debug", "ssl");
+
+ //don't call super method, we will configure the broker in the test before doing so
+ }
+
+ @Override
+ protected void customizeConfiguration() throws ConfigurationException, IOException
+ {
+ //do nothing, we will configure this locally
+ }
+
+ private void configure(boolean useSsl) throws ConfigurationException, IOException
+ {
+ getRestTestHelper().setUseSsl(useSsl);
+ if (useSsl)
+ {
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.PROTOCOLS, Collections.singleton(Protocol.HTTPS));
+ }
+ super.customizeConfiguration();
+ }
+
+ private void verifyGetBrokerAttempt(int responseCode) throws IOException
+ {
+ HttpURLConnection conn = getRestTestHelper().openManagementConnection("/rest/broker", "GET");
+ assertEquals(responseCode, conn.getResponseCode());
+ }
+
+ public void testDefaultEnabledWithHttps() throws Exception
+ {
+ configure(true);
+ super.setUp();
+ setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+ setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+
+ // Try the attempt with authentication, it should succeed because
+ // BASIC auth is enabled by default on secure connections.
+ getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+ verifyGetBrokerAttempt(HttpServletResponse.SC_OK);
+ }
+
+ public void testDefaultDisabledWithHttp() throws Exception
+ {
+ configure(false);
+ super.setUp();
+
+ // Try the attempt with authentication, it should fail because
+ // BASIC auth is disabled by default on non-secure connections.
+ getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+ verifyGetBrokerAttempt(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+
+ public void testEnablingForHttp() throws Exception
+ {
+ configure(false);
+
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+ super.setUp();
+
+ // Try the attempt with authentication, it should succeed because
+ // BASIC auth is now enabled on non-secure connections.
+ getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+ verifyGetBrokerAttempt(HttpServletResponse.SC_OK);
+ }
+
+ public void testDisablingForHttps() throws Exception
+ {
+ configure(true);
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpsBasicAuthenticationEnabled", false);
+ super.setUp();
+ setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+ setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+
+ // Try the attempt with authentication, it should fail because
+ // BASIC auth is now disabled on secure connections.
+ getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+ verifyGetBrokerAttempt(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java
index 1ed0d97185..372db8f560 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BindingRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.net.HttpURLConnection;
import java.util.HashMap;
@@ -32,9 +32,10 @@ public class BindingRestTest extends QpidRestTestCase
public void testGetAllBindings() throws Exception
{
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding");
assertNotNull("Bindings cannot be null", bindings);
- assertTrue("Unexpected number of bindings", bindings.size() >= EXPECTED_HOSTS.length * EXPECTED_QUEUES.length);
+ assertTrue("Unexpected number of bindings: " + bindings.size(),
+ bindings.size() >= EXPECTED_VIRTUALHOSTS.length * EXPECTED_QUEUES.length);
for (Map<String, Object> binding : bindings)
{
Asserts.assertBinding((String) binding.get(Binding.NAME), (String) binding.get(Binding.EXCHANGE), binding);
@@ -43,7 +44,7 @@ public class BindingRestTest extends QpidRestTestCase
public void testGetVirtualHostBindings() throws Exception
{
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test");
assertNotNull("Bindings cannot be null", bindings);
assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length * 2, bindings.size());
for (String queueName : EXPECTED_QUEUES)
@@ -52,31 +53,31 @@ public class BindingRestTest extends QpidRestTestCase
searchAttributes.put(Binding.NAME, queueName);
searchAttributes.put(Binding.EXCHANGE, "amq.direct");
- Map<String, Object> binding = find(searchAttributes, bindings);
+ Map<String, Object> binding = getRestTestHelper().find(searchAttributes, bindings);
Asserts.assertBinding(queueName, "amq.direct", binding);
searchAttributes.put(Binding.EXCHANGE, "<<default>>");
- binding = find(searchAttributes, bindings);
+ binding = getRestTestHelper().find(searchAttributes, bindings);
Asserts.assertBinding(queueName, "<<default>>", binding);
}
}
public void testGetVirtualHostExchangeBindings() throws Exception
{
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct");
assertNotNull("Bindings cannot be null", bindings);
assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length, bindings.size());
for (String queueName : EXPECTED_QUEUES)
{
- Map<String, Object> binding = find(Binding.NAME, queueName, bindings);
+ Map<String, Object> binding = getRestTestHelper().find(Binding.NAME, queueName, bindings);
Asserts.assertBinding(queueName, "amq.direct", binding);
}
}
public void testGetVirtualHostExchangeQueueBindings() throws Exception
{
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue");
assertNotNull("Bindings cannot be null", bindings);
assertEquals("Unexpected number of bindings", 1, bindings.size());
Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
@@ -85,25 +86,25 @@ public class BindingRestTest extends QpidRestTestCase
public void testDeleteBinding() throws Exception
{
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
assertEquals("Unexpected number of bindings", 1, bindings.size());
Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
- HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct/queue/queue", "DELETE");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct/queue/queue", "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- bindings = getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+ bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
assertEquals("Binding should be deleted", 0, bindings.size());
}
public void testDeleteBindingById() throws Exception
{
- Map<String, Object> binding = getJsonAsSingletonList("/rest/binding/test/amq.direct/queue");
- HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct?id=" + binding.get(Binding.ID), "DELETE");
+ Map<String, Object> binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct?id=" + binding.get(Binding.ID), "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> bindings = getJsonAsList("/rest/binding/test/amq.direct/queue");
+ List<Map<String, Object>> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue");
assertEquals("Binding should be deleted", 0, bindings.size());
}
@@ -115,13 +116,13 @@ public class BindingRestTest extends QpidRestTestCase
bindingData.put(Binding.QUEUE, "queue");
bindingData.put(Binding.EXCHANGE, "amq.direct");
- HttpURLConnection connection = openManagementConection("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT");
connection.connect();
- writeJsonRequest(connection, bindingData);
+ getRestTestHelper().writeJsonRequest(connection, bindingData);
int responseCode = connection.getResponseCode();
connection.disconnect();
assertEquals("Unexpected response code", 201, responseCode);
- Map<String, Object> binding = getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName);
+ Map<String, Object> binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName);
Asserts.assertBinding(bindingName, "queue", "amq.direct", binding);
}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java
index 4bbe9155cd..13e0c1e819 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestHttpsTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java
@@ -18,24 +18,25 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class BrokerRestHttpsTest extends QpidRestTestCase
{
- private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
- private static final String TRUSTSTORE_PASSWORD = "password";
-
@Override
public void setUp() throws Exception
{
@@ -48,39 +49,21 @@ public class BrokerRestHttpsTest extends QpidRestTestCase
@Override
protected void customizeConfiguration() throws ConfigurationException, IOException
{
- setConfigurationProperty("management.enabled", "true");
- setConfigurationProperty("management.http.enabled", "false");
- setConfigurationProperty("management.https.enabled", "true");
- setConfigurationProperty("management.https.port", Integer.toString(getHttpPort()));
- }
-
- @Override
- protected String getHostName()
- {
- return "localhost";
- }
-
- @Override
- protected String getProtocol()
- {
- return "https";
- }
-
- @Override
- protected HttpURLConnection openManagementConection(String path) throws IOException
- {
- URL url = getManagementURL(path);
- HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
- ((HttpsURLConnection) httpCon).setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
- httpCon.setDoOutput(true);
- return httpCon;
+ super.customizeConfiguration();
+ getRestTestHelper().setUseSsl(true);
+ Map<String, Object> newAttributes = new HashMap<String, Object>();
+ newAttributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTPS));
+ newAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+ getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT,newAttributes);
}
public void testGetWithHttps() throws Exception
{
- Map<String, Object> brokerDetails = getJsonAsSingletonList("/rest/broker");
+ Map<String, Object> brokerDetails = getRestTestHelper().getJsonAsSingletonList("/rest/broker");
Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES, Broker.BYTES_RETAINED,
- Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES, Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED);
+ Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES, Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED,
+ Broker.ACL_FILE, Broker.KEY_STORE_CERT_ALIAS, Broker.TRUST_STORE_PATH, Broker.TRUST_STORE_PASSWORD,
+ Broker.GROUP_FILE);
}
}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java
index f2970e2ba9..d479d39287 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/BrokerRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.util.Arrays;
import java.util.Collection;
@@ -32,6 +32,7 @@ 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.VirtualHost;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class BrokerRestTest extends QpidRestTestCase
{
@@ -43,7 +44,7 @@ public class BrokerRestTest extends QpidRestTestCase
public void testGet() throws Exception
{
- Map<String, Object> brokerDetails = getJsonAsSingletonList("/rest/broker");
+ Map<String, Object> brokerDetails = getRestTestHelper().getJsonAsSingletonList("/rest/broker");
assertBrokerAttributes(brokerDetails);
@@ -55,24 +56,23 @@ public class BrokerRestTest extends QpidRestTestCase
List<Map<String, Object>> virtualhosts = (List<Map<String, Object>>) brokerDetails.get(BROKER_VIRTUALHOSTS_ATTRIBUTE);
assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size());
- Asserts.assertVirtualHost("development", find(VirtualHost.NAME, "development", virtualhosts));
- Asserts.assertVirtualHost("localhost", find(VirtualHost.NAME, "localhost", virtualhosts));
- Asserts.assertVirtualHost("test", find(VirtualHost.NAME, "test", virtualhosts));
+ Asserts.assertVirtualHost(TEST3_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST3_VIRTUALHOST, virtualhosts));
+ Asserts.assertVirtualHost(TEST2_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST2_VIRTUALHOST, virtualhosts));
+ Asserts.assertVirtualHost(TEST1_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST1_VIRTUALHOST, virtualhosts));
@SuppressWarnings("unchecked")
List<Map<String, Object>> ports = (List<Map<String, Object>>) brokerDetails.get(BROKER_PORTS_ATTRIBUTE);
- assertEquals("Unexpected number of ports", 2, ports.size());
+ assertEquals("Unexpected number of ports", 4, ports.size());
for (Map<String, Object> port : ports)
{
Asserts.assertPortAttributes(port);
}
- String bindingAddress = (String)ports.get(0).get(Port.BINDING_ADDRESS);
-
- Map<String, Object> amqpPort = find(Port.NAME, bindingAddress + ":" + getPort(), ports);
- Map<String, Object> httpPort = find(Port.NAME, bindingAddress + ":" + getHttpPort(), ports);
+ Map<String, Object> amqpPort = getRestTestHelper().find(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT, ports);
+ Map<String, Object> httpPort = getRestTestHelper().find(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, ports);
+ assertEquals("Unexpected binding address", "*", amqpPort.get(Port.BINDING_ADDRESS));
assertNotNull("Cannot find AMQP port", amqpPort);
assertNotNull("Cannot find HTTP port", httpPort);
@@ -90,7 +90,9 @@ public class BrokerRestTest extends QpidRestTestCase
{
Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES,
Broker.BYTES_RETAINED, Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES,
- Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED);
+ Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED, Broker.ACL_FILE,
+ Broker.KEY_STORE_PATH, Broker.KEY_STORE_PASSWORD, Broker.KEY_STORE_CERT_ALIAS,
+ Broker.TRUST_STORE_PATH, Broker.TRUST_STORE_PASSWORD, Broker.GROUP_FILE);
assertEquals("Unexpected value of attribute " + Broker.BUILD_VERSION, QpidProperties.getBuildVersion(),
brokerDetails.get(Broker.BUILD_VERSION));
@@ -105,7 +107,7 @@ public class BrokerRestTest extends QpidRestTestCase
assertEquals("Unexpected value of attribute " + Broker.DURABLE, Boolean.TRUE, brokerDetails.get(Broker.DURABLE));
assertEquals("Unexpected value of attribute " + Broker.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
brokerDetails.get(Broker.LIFETIME_POLICY));
- assertEquals("Unexpected value of attribute " + Broker.NAME, "Broker", brokerDetails.get(Broker.NAME));
+ assertEquals("Unexpected value of attribute " + Broker.NAME, "QpidBroker", brokerDetails.get(Broker.NAME));
assertEquals("Unexpected value of attribute " + Broker.STATE, State.ACTIVE.name(), brokerDetails.get(Broker.STATE));
assertNotNull("Unexpected value of attribute " + Broker.ID, brokerDetails.get(Broker.ID));
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java
index 3661b94a7c..05c8e362a1 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConnectionRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.io.IOException;
import java.net.URLDecoder;
@@ -90,14 +90,14 @@ public class ConnectionRestTest extends QpidRestTestCase
public void testGetAllConnections() throws Exception
{
- List<Map<String, Object>> connections = getJsonAsList("/rest/connection");
+ List<Map<String, Object>> connections = getRestTestHelper().getJsonAsList("/rest/connection");
assertEquals("Unexpected number of connections", 1, connections.size());
Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
}
public void testGetVirtualHostConnections() throws Exception
{
- List<Map<String, Object>> connections = getJsonAsList("/rest/connection/test");
+ List<Map<String, Object>> connections = getRestTestHelper().getJsonAsList("/rest/connection/test");
assertEquals("Unexpected number of connections", 1, connections.size());
Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
}
@@ -107,21 +107,21 @@ public class ConnectionRestTest extends QpidRestTestCase
// get connection name
String connectionName = getConnectionName();
- Map<String, Object> connectionDetails = getJsonAsSingletonList("/rest/connection/test/"
+ Map<String, Object> connectionDetails = getRestTestHelper().getJsonAsSingletonList("/rest/connection/test/"
+ URLDecoder.decode(connectionName, "UTF-8"));
assertConnection(connectionDetails);
}
public void testGetAllSessions() throws Exception
{
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session");
+ List<Map<String, Object>> sessions = getRestTestHelper().getJsonAsList("/rest/session");
assertEquals("Unexpected number of sessions", 1, sessions.size());
assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
}
public void testGetVirtualHostSessions() throws Exception
{
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test");
+ List<Map<String, Object>> sessions = getRestTestHelper().getJsonAsList("/rest/session/test");
assertEquals("Unexpected number of sessions", 1, sessions.size());
assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
}
@@ -131,7 +131,7 @@ public class ConnectionRestTest extends QpidRestTestCase
// get connection name
String connectionName = getConnectionName();
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test/"
+ List<Map<String, Object>> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/"
+ URLDecoder.decode(connectionName, "UTF-8"));
assertEquals("Unexpected number of sessions", 1, sessions.size());
assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
@@ -142,7 +142,7 @@ public class ConnectionRestTest extends QpidRestTestCase
// get connection name
String connectionName = getConnectionName();
- List<Map<String, Object>> sessions = getJsonAsList("/rest/session/test/"
+ List<Map<String, Object>> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/"
+ URLDecoder.decode(connectionName, "UTF-8") + "/" + ((AMQSession<?, ?>) _session).getChannelId());
assertEquals("Unexpected number of sessions", 1, sessions.size());
assertSession(sessions.get(0), (AMQSession<?, ?>) _session);
@@ -201,7 +201,7 @@ public class ConnectionRestTest extends QpidRestTestCase
private String getConnectionName() throws IOException
{
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> connections = (List<Map<String, Object>>) hostDetails
.get(VirtualHostRestTest.VIRTUALHOST_CONNECTIONS_ATTRIBUTE);
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java
index 4904d2adf3..ec9791db13 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ExchangeRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.net.URLDecoder;
import java.util.List;
@@ -31,9 +31,9 @@ public class ExchangeRestTest extends QpidRestTestCase
{
public void testGet() throws Exception
{
- List<Map<String, Object>> exchanges = getJsonAsList("/rest/exchange");
+ List<Map<String, Object>> exchanges = getRestTestHelper().getJsonAsList("/rest/exchange");
assertNotNull("Exchanges cannot be null", exchanges);
- assertTrue("Unexpected number of exchanges", exchanges.size() >= EXPECTED_HOSTS.length * EXPECTED_EXCHANGES.length);
+ assertTrue("Unexpected number of exchanges", exchanges.size() >= EXPECTED_VIRTUALHOSTS.length * EXPECTED_EXCHANGES.length);
for (Map<String, Object> exchange : exchanges)
{
Asserts.assertExchange((String) exchange.get(Exchange.NAME), (String) exchange.get(Exchange.TYPE), exchange);
@@ -42,12 +42,12 @@ public class ExchangeRestTest extends QpidRestTestCase
public void testGetHostExchanges() throws Exception
{
- List<Map<String, Object>> exchanges = getJsonAsList("/rest/exchange/test");
+ List<Map<String, Object>> exchanges = getRestTestHelper().getJsonAsList("/rest/exchange/test");
assertNotNull("Users cannot be null", exchanges);
- assertEquals("Unexpected number of exchanges", 6, EXPECTED_EXCHANGES.length);
+ assertEquals("Unexpected number of exchanges", exchanges.size(), EXPECTED_EXCHANGES.length);
for (String exchangeName : EXPECTED_EXCHANGES)
{
- Map<String, Object> exchange = find(Exchange.NAME, exchangeName, exchanges);
+ Map<String, Object> exchange = getRestTestHelper().find(Exchange.NAME, exchangeName, exchanges);
assertExchange(exchangeName, exchange);
}
}
@@ -56,7 +56,7 @@ public class ExchangeRestTest extends QpidRestTestCase
{
for (String exchangeName : EXPECTED_EXCHANGES)
{
- Map<String, Object> exchange = getJsonAsSingletonList("/rest/exchange/test/"
+ Map<String, Object> exchange = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/"
+ URLDecoder.decode(exchangeName, "UTF-8"));
assertExchange(exchangeName, exchange);
}
@@ -79,7 +79,7 @@ public class ExchangeRestTest extends QpidRestTestCase
List<Map<String, Object>> bindings = (List<Map<String, Object>>) exchange.get("bindings");
for (String queueName : EXPECTED_QUEUES)
{
- Map<String, Object> binding = find(Binding.NAME, queueName, bindings);
+ Map<String, Object> binding = getRestTestHelper().find(Binding.NAME, queueName, bindings);
Asserts.assertBinding(queueName, (String) exchange.get(Exchange.NAME), binding);
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
new file mode 100644
index 0000000000..861bf8cb71
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
@@ -0,0 +1,160 @@
+/*
+ *
+ * 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.systest.rest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Group;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.UUIDGenerator;
+
+public class GroupProviderRestTest extends QpidRestTestCase
+{
+ private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+ private File _groupFile;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _groupFile = createTemporaryGroupFile();
+
+ getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_groupFile != null)
+ {
+ if (_groupFile.exists())
+ {
+ _groupFile.delete();
+ }
+ }
+ }
+
+ public void testGet() throws Exception
+ {
+ List<Map<String, Object>> providerDetails = getRestTestHelper().getJsonAsList("/rest/groupprovider");
+ assertNotNull("Providers details cannot be null", providerDetails);
+ assertEquals("Unexpected number of providers", 1, providerDetails.size());
+ for (Map<String, Object> provider : providerDetails)
+ {
+ assertProvider(FILE_GROUP_MANAGER, provider);
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/"
+ + provider.get(GroupProvider.NAME));
+ assertNotNull("Cannot load data for " + provider.get(GroupProvider.NAME), data);
+ assertProvider(FILE_GROUP_MANAGER, data);
+ }
+ }
+
+ public void testCreateNewGroup() throws Exception
+ {
+ String groupName = "newGroup";
+
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ assertNotNull("Cannot load data for provider", data);
+
+ getRestTestHelper().assertNumberOfGroups(data, 1);
+
+ getRestTestHelper().createGroup(groupName, FILE_GROUP_MANAGER);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ assertNotNull("Cannot load data for provider", data);
+
+ getRestTestHelper().assertNumberOfGroups(data, 2);
+ }
+
+ public void testRemoveGroup() throws Exception
+ {
+ String groupName = "myGroup";
+
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ assertNotNull("Cannot load data for provider", data);
+
+ getRestTestHelper().assertNumberOfGroups(data, 1);
+
+ getRestTestHelper().removeGroup(groupName, FILE_GROUP_MANAGER);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ assertNotNull("Cannot load data for provider", data);
+
+ getRestTestHelper().assertNumberOfGroups(data, 0);
+ }
+
+
+ private void assertProvider(String type, Map<String, Object> provider)
+ {
+ Asserts.assertAttributesPresent(provider, GroupProvider.AVAILABLE_ATTRIBUTES,
+ GroupProvider.CREATED, GroupProvider.UPDATED, GroupProvider.DESCRIPTION,
+ GroupProvider.TIME_TO_LIVE);
+ assertEquals("Unexpected value of provider attribute " + GroupProvider.STATE, State.ACTIVE.name(),
+ provider.get(GroupProvider.STATE));
+ assertEquals("Unexpected value of provider attribute " + GroupProvider.LIFETIME_POLICY,
+ LifetimePolicy.PERMANENT.name(), provider.get(GroupProvider.LIFETIME_POLICY));
+ assertEquals("Unexpected value of provider attribute " + GroupProvider.DURABLE, Boolean.TRUE,
+ provider.get(GroupProvider.DURABLE));
+ assertEquals("Unexpected value of provider attribute " + GroupProvider.TYPE, type,
+ provider.get(GroupProvider.TYPE));
+
+ final String name = (String) provider.get(GroupProvider.NAME);
+ assertEquals("Unexpected value of provider attribute " + GroupProvider.NAME, type,
+ name);
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> groups = (List<Map<String, Object>>) provider.get("groups");
+ assertNotNull("Groups were not found", groups);
+ assertEquals("Unexpected number of groups", 1, groups.size());
+ for (Map<String, Object> group : groups)
+ {
+
+ final String groupName = (String) group.get(Group.NAME);
+ assertNotNull("Attribute " + Group.NAME, groupName);
+
+ assertNotNull("Attribute " + Group.ID, group.get(Group.ID));
+ assertEquals("Attribute " + Group.ID, UUIDGenerator.generateGroupUUID(name, groupName).toString(), group.get(Group.ID));
+ }
+ }
+
+ private File createTemporaryGroupFile() throws Exception
+ {
+ File groupFile = File.createTempFile("group", "grp");
+ groupFile.deleteOnExit();
+
+ Properties props = new Properties();
+ props.put("myGroup.users", "guest");
+
+ props.store(new FileOutputStream(groupFile), "test group file");
+
+ return groupFile;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java
new file mode 100644
index 0000000000..d3f93cc0fe
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.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.systest.rest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupMember;
+
+public class GroupRestTest extends QpidRestTestCase
+{
+ private static final String GROUP_NAME = "myGroup";
+ private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+ private static final String EXISTING_MEMBER = "user1";
+ private static final String NEW_MEMBER = "user2";
+
+ private File _groupFile;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _groupFile = createTemporaryGroupFile();
+
+ getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+ super.setUp();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_groupFile != null)
+ {
+ if (_groupFile.exists())
+ {
+ _groupFile.delete();
+ }
+ }
+ }
+
+ public void testGet() throws Exception
+ {
+ Map<String, Object> group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+ List<Map<String, Object>> groupmembers = (List<Map<String, Object>>) group.get("groupmembers");
+ assertEquals(1, groupmembers.size());
+
+ Map<String, Object> member1 = groupmembers.get(0);
+ assertEquals(EXISTING_MEMBER, (String)member1.get(GroupMember.NAME));
+ }
+
+ public void testCreateNewMemberOfGroup() throws Exception
+ {
+ Map<String, Object> group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+ getRestTestHelper().assertNumberOfGroupMembers(group, 1);
+
+ getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, GROUP_NAME, NEW_MEMBER);
+
+ group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+ getRestTestHelper().assertNumberOfGroupMembers(group, 2);
+ }
+
+ public void testRemoveMemberFromGroup() throws Exception
+ {
+ Map<String, Object> group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+ getRestTestHelper().assertNumberOfGroupMembers(group, 1);
+
+ getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, GROUP_NAME, EXISTING_MEMBER);
+
+ group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+ getRestTestHelper().assertNumberOfGroupMembers(group, 0);
+ }
+
+ private File createTemporaryGroupFile() throws Exception
+ {
+ File groupFile = File.createTempFile("group", "grp");
+ groupFile.deleteOnExit();
+
+ Properties props = new Properties();
+ props.put(GROUP_NAME + ".users", EXISTING_MEMBER);
+
+ props.store(new FileOutputStream(groupFile), "test group file");
+
+ return groupFile;
+ }
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java
index c64fd6e1da..a2f9d3189c 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/LogRecordsRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.util.List;
import java.util.Map;
@@ -27,10 +27,10 @@ public class LogRecordsRestTest extends QpidRestTestCase
{
public void testGet() throws Exception
{
- List<Map<String, Object>> logs = getJsonAsList("/rest/logrecords");
+ List<Map<String, Object>> logs = getRestTestHelper().getJsonAsList("/rest/logrecords");
assertNotNull("Logs data cannot be null", logs);
assertTrue("Logs are not found", logs.size() > 0);
- Map<String, Object> record = find("message", "[Broker] BRK-1004 : Qpid Broker Ready", logs);
+ Map<String, Object> record = getRestTestHelper().find("message", "[Broker] BRK-1004 : Qpid Broker Ready", logs);
assertNotNull("BRK-1004 message is not found", record);
assertNotNull("Message id cannot be null", record.get("id"));
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java
index 492df43957..fb6bfca1d8 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/MessagesRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -85,7 +85,7 @@ public class MessagesRestTest extends QpidRestTestCase
public void testGet() throws Exception
{
String queueName = getTestQueueName();
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
+ List<Map<String, Object>> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
int position = 0;
@@ -111,7 +111,7 @@ public class MessagesRestTest extends QpidRestTestCase
// get message IDs
List<Long> ids = getMesssageIds(queueName);
- Map<String, Object> message = getJsonAsMap("/rest/message/test/" + queueName + "/" + ids.get(0));
+ Map<String, Object> message = getRestTestHelper().getJsonAsMap("/rest/message/test/" + queueName + "/" + ids.get(0));
assertMessageAttributes(message);
assertMessageAttributeValues(message, true);
@@ -121,7 +121,7 @@ public class MessagesRestTest extends QpidRestTestCase
assertEquals("Unexpected message header", 0, headers.get("index"));
Long lastMessageId = ids.get(ids.size() - 1);
- message = getJsonAsMap("/rest/message/test/" + queueName + "/" + lastMessageId);
+ message = getRestTestHelper().getJsonAsMap("/rest/message/test/" + queueName + "/" + lastMessageId);
assertMessageAttributes(message);
assertEquals("Unexpected message attribute mimeType", "application/octet-stream", message.get("mimeType"));
assertEquals("Unexpected message attribute size", 4, message.get("size"));
@@ -132,10 +132,10 @@ public class MessagesRestTest extends QpidRestTestCase
assertEquals("Unexpected message header", "value", bytesMessageHeader.get("test"));
// get content
- HttpURLConnection connection = openManagementConection("/rest/message-content/test/" + queueName + "/"
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message-content/test/" + queueName + "/"
+ lastMessageId, "GET");
connection.connect();
- byte[] data = readConnectionInputStream(connection);
+ byte[] data = getRestTestHelper().readConnectionInputStream(connection);
assertTrue("Unexpected message", Arrays.equals(messageBytes, data));
}
@@ -159,38 +159,38 @@ public class MessagesRestTest extends QpidRestTestCase
}
// move messages
- HttpURLConnection connection = openManagementConection("/rest/message/test/" + queueName, "POST");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message/test/" + queueName, "POST");
Map<String, Object> messagesData = new HashMap<String, Object>();
messagesData.put("messages", movedMessageIds);
messagesData.put("destinationQueue", queueName2);
messagesData.put("move", Boolean.TRUE);
- writeJsonRequest(connection, messagesData);
+ getRestTestHelper().writeJsonRequest(connection, messagesData);
assertEquals("Unexpected response code", 200, connection.getResponseCode());
// check messages on target queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName2);
+ List<Map<String, Object>> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName2);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", movedMessageIds.size(), messages.size());
for (Long id : movedMessageIds)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
// check messages on original queue
- messages = getJsonAsList("/rest/message/test/" + queueName);
+ messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", ids.size(), messages.size());
for (Long id : ids)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
for (Long id : movedMessageIds)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertNull("Moved message " + id + " is found on original queue", message);
}
}
@@ -214,37 +214,37 @@ public class MessagesRestTest extends QpidRestTestCase
}
// copy messages
- HttpURLConnection connection = openManagementConection("/rest/message/test/" + queueName, "POST");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message/test/" + queueName, "POST");
Map<String, Object> messagesData = new HashMap<String, Object>();
messagesData.put("messages", copyMessageIds);
messagesData.put("destinationQueue", queueName2);
- writeJsonRequest(connection, messagesData);
+ getRestTestHelper().writeJsonRequest(connection, messagesData);
assertEquals("Unexpected response code", 200, connection.getResponseCode());
// check messages on target queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName2);
+ List<Map<String, Object>> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName2);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", copyMessageIds.size(), messages.size());
for (Long id : copyMessageIds)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
// check messages on original queue
- messages = getJsonAsList("/rest/message/test/" + queueName);
+ messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
for (Long id : ids)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
for (Long id : copyMessageIds)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
}
@@ -272,30 +272,30 @@ public class MessagesRestTest extends QpidRestTestCase
}
// delete messages
- HttpURLConnection connection = openManagementConection(
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection(
"/rest/message/test/" + queueName + "?" + queryString.toString(), "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
// check messages on queue
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
+ List<Map<String, Object>> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
assertNotNull("Messages are not found", messages);
assertEquals("Unexpected number of messages", ids.size(), messages.size());
for (Long id : ids)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertMessageAttributes(message);
}
for (Long id : deleteMessageIds)
{
- Map<String, Object> message = find("id", id.intValue(), messages);
+ Map<String, Object> message = getRestTestHelper().find("id", id.intValue(), messages);
assertNull("Message with id " + id + " was not deleted", message);
}
}
private List<Long> getMesssageIds(String queueName) throws IOException, JsonParseException, JsonMappingException
{
- List<Map<String, Object>> messages = getJsonAsList("/rest/message/test/" + queueName);
+ List<Map<String, Object>> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
List<Long> ids = new ArrayList<Long>();
for (Map<String, Object> message : messages)
{
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
index 739ef5c737..578565be05 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/PortRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
@@ -18,41 +18,44 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class PortRestTest extends QpidRestTestCase
{
public void testGet() throws Exception
{
- List<Map<String, Object>> ports = getJsonAsList("/rest/port/");
+ List<Map<String, Object>> ports = getRestTestHelper().getJsonAsList("/rest/port/");
assertNotNull("Port data cannot be null", ports);
- assertEquals("Unexpected number of ports", 2, ports.size());
- int[] expectedPorts = { getPort(), getHttpPort() };
- for (int port : expectedPorts)
- {
- String portName = "0.0.0.0:" + port;
- Map<String, Object> portData = find(Port.NAME, portName, ports);
- assertNotNull("Port " + portName + " is not found", portData);
- Asserts.assertPortAttributes(portData);
- }
+ assertEquals("Unexpected number of ports", 4, ports.size());
+
+ String httpPortName = TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT;
+ Map<String, Object> portData = getRestTestHelper().find(Port.NAME, httpPortName, ports);
+ assertNotNull("Http port " + httpPortName + " is not found", portData);
+ Asserts.assertPortAttributes(portData);
+
+ String amqpPortName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> amqpPortData = getRestTestHelper().find(Port.NAME, amqpPortName, ports);
+ assertNotNull("Amqp port " + amqpPortName + " is not found", amqpPortData);
+ Asserts.assertPortAttributes(amqpPortData);
}
public void testGetPort() throws Exception
{
- List<Map<String, Object>> ports = getJsonAsList("/rest/port/");
+ List<Map<String, Object>> ports = getRestTestHelper().getJsonAsList("/rest/port/");
assertNotNull("Ports data cannot be null", ports);
- assertEquals("Unexpected number of ports", 2, ports.size());
+ assertEquals("Unexpected number of ports", 4, ports.size());
for (Map<String, Object> portMap : ports)
{
String portName = (String) portMap.get(Port.NAME);
assertNotNull("Port name attribute is not found", portName);
- Map<String, Object> portData = getJsonAsSingletonList("/rest/port/" + URLDecoder.decode(portName, "UTF-8"));
+ Map<String, Object> portData = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + URLDecoder.decode(portName, "UTF-8"));
assertNotNull("Port " + portName + " is not found", portData);
Asserts.assertPortAttributes(portData);
}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
new file mode 100644
index 0000000000..671bdd7eb8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.systest.rest;
+
+import java.io.IOException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class QpidRestTestCase extends QpidBrokerTestCase
+{
+ public static final String TEST1_VIRTUALHOST = "test";
+ public static final String TEST2_VIRTUALHOST = "test2";
+ public static final String TEST3_VIRTUALHOST = "test3";
+
+ public static final String[] EXPECTED_VIRTUALHOSTS = { TEST1_VIRTUALHOST, TEST2_VIRTUALHOST, TEST3_VIRTUALHOST};
+ public static final String[] EXPECTED_QUEUES = { "queue", "ping" };
+ public static final String[] EXPECTED_EXCHANGES = { "amq.fanout", "amq.match", "amq.direct","amq.topic","<<default>>" };
+
+ private RestTestHelper _restTestHelper = new RestTestHelper(findFreePort());
+
+ @Override
+ public void setUp() throws Exception
+ {
+ // Set up virtualhost config with queues and bindings to the amq.direct
+ for (String virtualhost : EXPECTED_VIRTUALHOSTS)
+ {
+ createTestVirtualHost(0, virtualhost);
+ for (String queue : EXPECTED_QUEUES)
+ {
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".queues.exchange", "amq.direct");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".queues.queue(-1).name", queue);
+ }
+ }
+
+ customizeConfiguration();
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ getRestTestHelper().tearDown();
+ }
+ }
+
+ protected void customizeConfiguration() throws ConfigurationException, IOException
+ {
+ TestBrokerConfiguration config = getBrokerConfiguration();
+ config.addHttpManagementConfiguration();
+ config.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.PORT, _restTestHelper.getHttpPort());
+ }
+
+ public RestTestHelper getRestTestHelper()
+ {
+ return _restTestHelper;
+ }
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
index 5f11b3fb1d..1f441e7cbb 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/QueueRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.io.IOException;
import java.net.HttpURLConnection;
@@ -80,7 +80,7 @@ public class QueueRestTest extends QpidRestTestCase
public void testGetVirtualHostQueues() throws Exception
{
String queueName = getTestQueueName();
- List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test");
+ List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/queue/test");
assertEquals("Unexpected number of queues", EXPECTED_QUEUES.length + 1, queues.size());
String[] expectedQueues = new String[EXPECTED_QUEUES.length + 1];
System.arraycopy(EXPECTED_QUEUES, 0, expectedQueues, 0, EXPECTED_QUEUES.length);
@@ -88,7 +88,7 @@ public class QueueRestTest extends QpidRestTestCase
for (String name : expectedQueues)
{
- Map<String, Object> queueDetails = find(Queue.NAME, name, queues);
+ Map<String, Object> queueDetails = getRestTestHelper().find(Queue.NAME, name, queues);
Asserts.assertQueue(name, "standard", queueDetails);
@SuppressWarnings("unchecked")
@@ -96,8 +96,8 @@ public class QueueRestTest extends QpidRestTestCase
assertNotNull("Queue bindings are not found", bindings);
assertEquals("Unexpected number of bindings", 2, bindings.size());
- Map<String, Object> defaultExchangeBinding = find(Binding.EXCHANGE, "<<default>>", bindings);
- Map<String, Object> directExchangeBinding = find(Binding.EXCHANGE, "amq.direct", bindings);
+ Map<String, Object> defaultExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "<<default>>", bindings);
+ Map<String, Object> directExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "amq.direct", bindings);
Asserts.assertBinding(name, "<<default>>", defaultExchangeBinding);
Asserts.assertBinding(name, "amq.direct", directExchangeBinding);
}
@@ -106,7 +106,7 @@ public class QueueRestTest extends QpidRestTestCase
public void testGetByName() throws Exception
{
String queueName = getTestQueueName();
- Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
+ Map<String, Object> queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
Asserts.assertQueue(queueName, "standard", queueDetails);
assertStatistics(queueDetails);
@@ -115,8 +115,8 @@ public class QueueRestTest extends QpidRestTestCase
assertNotNull("Queue bindings are not found", bindings);
assertEquals("Unexpected number of bindings", 2, bindings.size());
- Map<String, Object> defaultExchangeBinding = find(Binding.EXCHANGE, "<<default>>", bindings);
- Map<String, Object> directExchangeBinding = find(Binding.EXCHANGE, "amq.direct", bindings);
+ Map<String, Object> defaultExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "<<default>>", bindings);
+ Map<String, Object> directExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "amq.direct", bindings);
Asserts.assertBinding(queueName, "<<default>>", defaultExchangeBinding);
Asserts.assertBinding(queueName, "amq.direct", directExchangeBinding);
@@ -131,14 +131,14 @@ public class QueueRestTest extends QpidRestTestCase
{
String queueName = getTestQueueName();
String bindingName = queueName + 2;
- String[] exchanges = { "amq.direct", "amq.fanout", "amq.topic", "amq.match", "qpid.management", "<<default>>" };
+ String[] exchanges = { "amq.direct", "amq.fanout", "amq.topic", "amq.match", "<<default>>" };
for (int i = 0; i < exchanges.length; i++)
{
createBinding(bindingName, exchanges[i], queueName);
}
- Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
+ Map<String, Object> queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
Asserts.assertQueue(queueName, "standard", queueDetails);
@SuppressWarnings("unchecked")
@@ -152,14 +152,14 @@ public class QueueRestTest extends QpidRestTestCase
for (int i = 0; i < exchanges.length; i++)
{
searchAttributes.put(Binding.EXCHANGE, exchanges[i]);
- Map<String, Object> binding = find(searchAttributes, bindings);
+ Map<String, Object> binding = getRestTestHelper().find(searchAttributes, bindings);
Asserts.assertBinding(bindingName, queueName, exchanges[i], binding);
}
}
private void createBinding(String bindingName, String exchangeName, String queueName) throws IOException
{
- HttpURLConnection connection = openManagementConection(
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection(
"/rest/binding/test/" + URLDecoder.decode(exchangeName, "UTF-8") + "/" + queueName + "/" + bindingName,
"PUT");
@@ -168,7 +168,7 @@ public class QueueRestTest extends QpidRestTestCase
bindingData.put(Binding.EXCHANGE, exchangeName);
bindingData.put(Binding.QUEUE, queueName);
- writeJsonRequest(connection, bindingData);
+ getRestTestHelper().writeJsonRequest(connection, bindingData);
assertEquals("Unexpected response code", 201, connection.getResponseCode());
connection.disconnect();
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
new file mode 100644
index 0000000000..0db1f7e50d
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
@@ -0,0 +1,452 @@
+/*
+ * 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.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.Assert;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+public class RestTestHelper
+{
+ private static final Logger LOGGER = Logger.getLogger(RestTestHelper.class);
+
+ private int _httpPort;
+
+ private boolean _useSsl;
+
+ private String _username;
+
+ private String _password;
+
+ private File _passwdFile;
+
+ public RestTestHelper(int httpPort)
+ {
+ _httpPort = httpPort;
+ }
+
+ public int getHttpPort()
+ {
+ return _httpPort;
+ }
+
+ private String getHostName()
+ {
+ return "localhost";
+ }
+
+ private String getProtocol()
+ {
+ return _useSsl ? "https" : "http";
+ }
+
+ public String getManagementURL()
+ {
+ return getProtocol() + "://" + getHostName() + ":" + getHttpPort();
+ }
+
+ public URL getManagementURL(String path) throws MalformedURLException
+ {
+ return new URL(getManagementURL() + path);
+ }
+
+ public HttpURLConnection openManagementConnection(String path, String method) throws IOException
+ {
+ URL url = getManagementURL(path);
+ HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
+ if(_useSsl)
+ {
+ try
+ {
+ // We have to use a SSLSocketFactory from a new SSLContext so that we don't re-use
+ // the JVM's defaults that may have been initialised in previous tests.
+
+ SSLContext sslContext = SSLContextFactory.buildClientContext(
+ TRUSTSTORE, TRUSTSTORE_PASSWORD,
+ KeyStore.getDefaultType(),
+ TrustManagerFactory.getDefaultAlgorithm(),
+ null, null, null, null, null);
+
+ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+
+ ((HttpsURLConnection) httpCon).setSSLSocketFactory(sslSocketFactory);
+ }
+ catch (GeneralSecurityException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ if(_username != null)
+ {
+ String encoded = new String(new Base64().encode((_username + ":" + _password).getBytes()));
+ httpCon.setRequestProperty("Authorization", "Basic " + encoded);
+ }
+
+ httpCon.setDoOutput(true);
+ httpCon.setRequestMethod(method);
+ return httpCon;
+ }
+
+ public List<Map<String, Object>> readJsonResponseAsList(HttpURLConnection connection) throws IOException,
+ JsonParseException, JsonMappingException
+ {
+ byte[] data = readConnectionInputStream(connection);
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ TypeReference<List<LinkedHashMap<String, Object>>> typeReference = new TypeReference<List<LinkedHashMap<String, Object>>>()
+ {
+ };
+ List<Map<String, Object>> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
+ return providedObject;
+ }
+
+ public Map<String, Object> readJsonResponseAsMap(HttpURLConnection connection) throws IOException,
+ JsonParseException, JsonMappingException
+ {
+ byte[] data = readConnectionInputStream(connection);
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ TypeReference<LinkedHashMap<String, Object>> typeReference = new TypeReference<LinkedHashMap<String, Object>>()
+ {
+ };
+ Map<String, Object> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
+ return providedObject;
+ }
+
+ public byte[] readConnectionInputStream(HttpURLConnection connection) throws IOException
+ {
+ InputStream is = connection.getInputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int len = -1;
+ while ((len = is.read(buffer)) != -1)
+ {
+ baos.write(buffer, 0, len);
+ }
+ if (LOGGER.isTraceEnabled())
+ {
+ LOGGER.trace("RESPONSE:" + new String(baos.toByteArray()));
+ }
+ return baos.toByteArray();
+ }
+
+ public void writeJsonRequest(HttpURLConnection connection, Map<String, Object> data) throws JsonGenerationException,
+ JsonMappingException, IOException
+ {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.writeValue(connection.getOutputStream(), data);
+ }
+
+ public Map<String, Object> find(String name, Object value, List<Map<String, Object>> data)
+ {
+ for (Map<String, Object> map : data)
+ {
+ Object mapValue = map.get(name);
+ if (value.equals(mapValue))
+ {
+ return map;
+ }
+ }
+ return null;
+ }
+
+ public Map<String, Object> find(Map<String, Object> searchAttributes, List<Map<String, Object>> data)
+ {
+ for (Map<String, Object> map : data)
+ {
+ boolean equals = true;
+ for (Map.Entry<String, Object> entry : searchAttributes.entrySet())
+ {
+ Object mapValue = map.get(entry.getKey());
+ if (!entry.getValue().equals(mapValue))
+ {
+ equals = false;
+ break;
+ }
+ }
+ if (equals)
+ {
+ return map;
+ }
+ }
+ return null;
+ }
+
+ public Map<String, Object> getJsonAsSingletonList(String path) throws IOException
+ {
+ List<Map<String, Object>> response = getJsonAsList(path);
+
+ Assert.assertNotNull("Response cannot be null", response);
+ Assert.assertEquals("Unexpected response", 1, response.size());
+ return response.get(0);
+ }
+
+ public List<Map<String, Object>> getJsonAsList(String path) throws IOException, JsonParseException,
+ JsonMappingException
+ {
+ HttpURLConnection connection = openManagementConnection(path, "GET");
+ connection.connect();
+ List<Map<String, Object>> response = readJsonResponseAsList(connection);
+ return response;
+ }
+
+ public Map<String, Object> getJsonAsMap(String path) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection(path, "GET");
+ connection.connect();
+ Map<String, Object> response = readJsonResponseAsMap(connection);
+ return response;
+ }
+
+ public void createNewGroupMember(String groupProviderName, String groupName, String memberName, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection(
+ "/rest/groupmember/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8") + "/" + URLDecoder.decode(memberName, "UTF-8"),
+ "PUT");
+
+ Map<String, Object> groupMemberData = new HashMap<String, Object>();
+ // TODO add type
+ writeJsonRequest(connection, groupMemberData);
+
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+ connection.disconnect();
+ }
+
+ public void createNewGroupMember(String groupProviderName, String groupName, String memberName) throws IOException
+ {
+ createNewGroupMember(groupProviderName, groupName, memberName, HttpServletResponse.SC_CREATED);
+ }
+
+ public void removeMemberFromGroup(String groupProviderName, String groupName, String memberName, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection(
+ "/rest/groupmember/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8") + "/" + URLDecoder.decode(memberName, "UTF-8"),
+ "DELETE");
+
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+ connection.disconnect();
+ }
+
+ public void removeMemberFromGroup(String groupProviderName, String groupName, String memberName) throws IOException
+ {
+ removeMemberFromGroup(groupProviderName, groupName, memberName, HttpServletResponse.SC_OK);
+ }
+
+ public void assertNumberOfGroupMembers(Map<String, Object> data, int expectedNumberOfGroupMembers)
+ {
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> groups = (List<Map<String, Object>>) data.get("groupmembers");
+ if (groups == null)
+ {
+ groups = Collections.emptyList();
+ }
+
+ Assert.assertEquals("Unexpected number of group members", expectedNumberOfGroupMembers, groups.size());
+ }
+
+ public void createGroup(String groupName, String groupProviderName) throws IOException
+ {
+ createGroup(groupName, groupProviderName, HttpServletResponse.SC_CREATED);
+ }
+
+ public void createGroup(String groupName, String groupProviderName, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection(
+ "/rest/group/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8"),
+ "PUT");
+
+ Map<String, Object> groupData = new HashMap<String, Object>();
+ writeJsonRequest(connection, groupData);
+
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+ connection.disconnect();
+ }
+
+ public void createOrUpdateUser(String username, String password) throws IOException
+ {
+ createOrUpdateUser(username, password, HttpServletResponse.SC_CREATED);
+ }
+
+ public void createOrUpdateUser(String username, String password, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username, "PUT");
+
+ Map<String, Object> data = new HashMap<String, Object>();
+ data.put("password", password);
+ writeJsonRequest(connection, data);
+
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+ connection.disconnect();
+ }
+
+ public void removeGroup(String groupName, String groupProviderName, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection(
+ "/rest/group/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8"),
+ "DELETE");
+
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+ connection.disconnect();
+ }
+
+ public void removeGroup(String groupName, String groupProviderName) throws IOException
+ {
+ removeGroup(groupName, groupProviderName, HttpServletResponse.SC_OK);
+ }
+
+ public void removeUserById(String id) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "?id=" + id, "DELETE");
+ Assert.assertEquals("Unexpected response code", HttpServletResponse.SC_OK, connection.getResponseCode());
+ connection.disconnect();
+ }
+
+ public void removeUser(String username, int responseCode) throws IOException
+ {
+ HttpURLConnection connection = openManagementConnection("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username, "DELETE");
+ Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+ connection.disconnect();
+ }
+
+ public void removeUser(String username) throws IOException
+ {
+ removeUser(username, HttpServletResponse.SC_OK);
+ }
+
+ public void assertNumberOfGroups(Map<String, Object> data, int expectedNumberOfGroups)
+ {
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> groups = (List<Map<String, Object>>) data.get("groups");
+ if (groups == null)
+ {
+ groups = Collections.emptyList();
+ }
+ Assert.assertEquals("Unexpected number of groups", expectedNumberOfGroups, groups.size());
+ }
+
+ public void setUseSsl(boolean useSsl)
+ {
+ _useSsl = useSsl;
+ }
+
+ public void setUsernameAndPassword(String username, String password)
+ {
+ _username = username;
+ _password = password;
+ }
+
+ /**
+ * Create password file that follows the convention username=password, which is deleted by {@link #tearDown()}
+ */
+ public void configureTemporaryPasswordFile(QpidBrokerTestCase testCase, String... users) throws ConfigurationException, IOException
+ {
+ _passwdFile = createTemporaryPasswdFile(users);
+
+ testCase.getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER,
+ AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _passwdFile.getAbsolutePath());
+ }
+
+ public void tearDown()
+ {
+ if (_passwdFile != null)
+ {
+ if (_passwdFile.exists())
+ {
+ _passwdFile.delete();
+ }
+ }
+ }
+
+ private File createTemporaryPasswdFile(String[] users) throws IOException
+ {
+ BufferedWriter writer = null;
+ try
+ {
+ File testFile = File.createTempFile(this.getClass().getName(),"tmp");
+ testFile.deleteOnExit();
+
+ writer = new BufferedWriter(new FileWriter(testFile));
+ for (int i = 0; i < users.length; i++)
+ {
+ String username = users[i];
+ writer.write(username + ":" + username);
+ writer.newLine();
+ }
+
+ return testFile;
+
+ }
+ finally
+ {
+ if (writer != null)
+ {
+ writer.close();
+ }
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
new file mode 100644
index 0000000000..856fda9419
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
@@ -0,0 +1,435 @@
+/*
+ *
+ * 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.systest.rest;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.tools.security.Passwd;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class SaslRestTest extends QpidRestTestCase
+{
+ @Override
+ public void startBroker()
+ {
+ // prevent broker from starting in setUp
+ }
+
+ public void startBrokerNow() throws Exception
+ {
+ super.startBroker();
+ }
+
+ public void testGetMechanismsWithBrokerPlainPasswordPrincipalDatabase() throws Exception
+ {
+ startBrokerNow();
+
+ Map<String, Object> saslData = getRestTestHelper().getJsonAsMap("/rest/sasl");
+ assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
+
+ @SuppressWarnings("unchecked")
+ List<String> mechanisms = (List<String>) saslData.get("mechanisms");
+ String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
+ for (String mechanism : expectedMechanisms)
+ {
+ assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+ }
+ assertNull("Unexpected user was returned", saslData.get("user"));
+ }
+
+ public void testGetMechanismsWithBrokerBase64MD5FilePrincipalDatabase() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ Map<String, Object> saslData = getRestTestHelper().getJsonAsMap("/rest/sasl");
+ assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
+
+ @SuppressWarnings("unchecked")
+ List<String> mechanisms = (List<String>) saslData.get("mechanisms");
+ String[] expectedMechanisms = { "CRAM-MD5-HEX", "CRAM-MD5-HASHED" };
+ for (String mechanism : expectedMechanisms)
+ {
+ assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+ }
+ assertNull("Unexpected user was returned", saslData.get("user"));
+ }
+
+ public void testPlainSaslAuthenticationForValidCredentials() throws Exception
+ {
+ startBrokerNow();
+
+ byte[] responseBytes = generatePlainClientResponse("admin", "admin");
+ String responseData = Base64.encodeBase64String(responseBytes);
+ String parameters= "mechanism=PLAIN&response=" + responseData;
+
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+ OutputStream os = connection.getOutputStream();
+ os.write(parameters.getBytes());
+ os.flush();
+
+ int code = connection.getResponseCode();
+ assertEquals("Unexpected response code", 200, code);
+
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertEquals("Unexpected user", "admin", response2.get("user"));
+ }
+
+ public void testPlainSaslAuthenticationForIncorrectPassword() throws Exception
+ {
+ startBrokerNow();
+
+ byte[] responseBytes = generatePlainClientResponse("admin", "incorrect");
+ String responseData = Base64.encodeBase64String(responseBytes);
+ String parameters= "mechanism=PLAIN&response=" + responseData;
+
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+ OutputStream os = connection.getOutputStream();
+ os.write(parameters.getBytes());
+ os.flush();
+
+ int code = connection.getResponseCode();
+ assertEquals("Unexpected response code", 403, code);
+
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ public void testPlainSaslAuthenticationForNonExistingUser() throws Exception
+ {
+ startBrokerNow();
+
+ byte[] responseBytes = generatePlainClientResponse("nonexisting", "admin");
+ String responseData = Base64.encodeBase64String(responseBytes);
+ String parameters= "mechanism=PLAIN&response=" + responseData;
+
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+ OutputStream os = connection.getOutputStream();
+ os.write(parameters.getBytes());
+ os.flush();
+
+ int code = connection.getResponseCode();
+ assertEquals("Unexpected response code", 403, code);
+
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ public void testCramMD5SaslAuthenticationForValidCredentials() throws Exception
+ {
+ startBrokerNow();
+
+ // request the challenge for CRAM-MD5
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // authenticate user with correct credentials
+ int code = authenticateUser(connection, "admin", "admin", "CRAM-MD5");
+ assertEquals("Unexpected response code", 200, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertEquals("Unexpected user", "admin", response2.get("user"));
+ }
+
+ public void testCramMD5SaslAuthenticationForIncorrectPassword() throws Exception
+ {
+ startBrokerNow();
+
+ // request the challenge for CRAM-MD5
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // authenticate user with correct credentials
+ int code = authenticateUser(connection, "admin", "incorrect", "CRAM-MD5");
+ assertEquals("Unexpected response code", 403, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ public void testCramMD5SaslAuthenticationForNonExistingUser() throws Exception
+ {
+ startBrokerNow();
+
+ // request the challenge for CRAM-MD5
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // authenticate user with correct credentials
+ int code = authenticateUser(connection, "nonexisting", "admin", "CRAM-MD5");
+ assertEquals("Unexpected response code", 403, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ public void testCramMD5HexSaslAuthenticationForValidCredentials() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ // request the challenge for CRAM-MD5-HEX
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // authenticate user with correct credentials
+ int code = authenticateUser(connection, "admin", "admin", "CRAM-MD5-HEX");
+ assertEquals("Unexpected response code", 200, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertEquals("Unexpected user", "admin", response2.get("user"));
+ }
+
+ public void testCramMD5HexSaslAuthenticationForIncorrectPassword() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // try to authenticate user with incorrect passowrd
+ int code = authenticateUser(connection, "admin", "incorrect", "CRAM-MD5-HEX");
+ assertEquals("Unexpected response code", 403, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ public void testCramMD5HexSaslAuthenticationForNonExistingUser() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // try to authenticate non-existing user
+ int code = authenticateUser(connection, "nonexisting", "admin", "CRAM-MD5-HEX");
+ assertEquals("Unexpected response code", 403, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
+ private HttpURLConnection requestSasServerChallenge(String mechanism) throws IOException
+ {
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+ OutputStream os = connection.getOutputStream();
+ os.write(("mechanism=" + mechanism).getBytes());
+ os.flush();
+ return connection;
+ }
+
+ private int authenticateUser(HttpURLConnection requestChallengeConnection, String userName, String userPassword, String mechanism)
+ throws IOException, JsonParseException, JsonMappingException, Exception
+ {
+ // get the response
+ Map<String, Object> response = getRestTestHelper().readJsonResponseAsMap(requestChallengeConnection);
+ String challenge = (String) response.get("challenge");
+ assertNotNull("Challenge is not found", challenge);
+
+ // preserve cookies to have the same server session
+ List<String> cookies = requestChallengeConnection.getHeaderFields().get("Set-Cookie");
+
+ // generate the authentication response for the challenge received
+ byte[] challengeBytes = Base64.decodeBase64(challenge);
+ byte[] responseBytes = generateClientResponse(mechanism, userName, userPassword, challengeBytes);
+ String responseData = Base64.encodeBase64String(responseBytes);
+ String requestParameters = ("id=" + response.get("id") + "&response=" + responseData);
+
+ // re-open connection
+ HttpURLConnection authenticateConnection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+
+ // set cookies to use the same server session
+ applyCookiesToConnection(cookies, authenticateConnection);
+ OutputStream os = authenticateConnection.getOutputStream();
+ os.write(requestParameters.getBytes());
+ os.flush();
+ return authenticateConnection.getResponseCode();
+ }
+
+ private byte[] generateClientResponse(String mechanism, String userName, String userPassword, byte[] challengeBytes) throws Exception
+ {
+ byte[] responseBytes = null;
+ if ("CRAM-MD5-HEX".equalsIgnoreCase(mechanism))
+ {
+ responseBytes = generateCramMD5HexClientResponse(userName, userPassword, challengeBytes);
+ }
+ else if ("CRAM-MD5".equalsIgnoreCase(mechanism))
+ {
+ responseBytes = generateCramMD5ClientResponse(userName, userPassword, challengeBytes);
+ }
+ else
+ {
+ throw new RuntimeException("Not implemented test mechanism " + mechanism);
+ }
+ return responseBytes;
+ }
+
+ private void applyCookiesToConnection(List<String> cookies, HttpURLConnection connection)
+ {
+ for (String cookie : cookies)
+ {
+ connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
+ }
+ }
+
+ private static byte SEPARATOR = 0;
+
+ private byte[] generatePlainClientResponse(String userName, String userPassword) throws Exception
+ {
+ byte[] password = userPassword.getBytes("UTF8");
+ byte user[] = userName.getBytes("UTF8");
+ byte response[] = new byte[password.length + user.length + 2 ];
+ int size = 0;
+ response[size++] = SEPARATOR;
+ System.arraycopy(user, 0, response, size, user.length);
+ size += user.length;
+ response[size++] = SEPARATOR;
+ System.arraycopy(password, 0, response, size, password.length);
+ return response;
+ }
+
+ private byte[] generateCramMD5HexClientResponse(String userName, String userPassword, byte[] challengeBytes) throws Exception
+ {
+ String macAlgorithm = "HmacMD5";
+ byte[] digestedPasswordBytes = MessageDigest.getInstance("MD5").digest(userPassword.getBytes("UTF-8"));
+ byte[] hexEncodedDigestedPasswordBytes = toHex(digestedPasswordBytes).getBytes("UTF-8");
+ Mac mac = Mac.getInstance(macAlgorithm);
+ mac.init(new SecretKeySpec(hexEncodedDigestedPasswordBytes, macAlgorithm));
+ final byte[] messageAuthenticationCode = mac.doFinal(challengeBytes);
+ String responseAsString = userName + " " + toHex(messageAuthenticationCode);
+ return responseAsString.getBytes();
+ }
+
+ private byte[] generateCramMD5ClientResponse(String userName, String userPassword, byte[] challengeBytes) throws Exception
+ {
+ String macAlgorithm = "HmacMD5";
+ Mac mac = Mac.getInstance(macAlgorithm);
+ mac.init(new SecretKeySpec(userPassword.getBytes("UTF-8"), macAlgorithm));
+ final byte[] messageAuthenticationCode = mac.doFinal(challengeBytes);
+ String responseAsString = userName + " " + toHex(messageAuthenticationCode);
+ return responseAsString.getBytes();
+ }
+
+ private String toHex(byte[] data)
+ {
+ StringBuffer hash = new StringBuffer();
+ for (int i = 0; i < data.length; i++)
+ {
+ String hex = Integer.toHexString(0xFF & data[i]);
+ if (hex.length() == 1)
+ {
+ hash.append('0');
+ }
+ hash.append(hex);
+ }
+ return hash.toString();
+ }
+
+ private void configureBase64MD5FilePrincipalDatabase() throws IOException, ConfigurationException
+ {
+ // generate user password entry
+ String passwordFileEntry;
+ try
+ {
+ passwordFileEntry = new Passwd().getOutput("admin", "admin");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new ConfigurationException(e);
+ }
+
+ // store the entry in the file
+ File passwordFile = File.createTempFile("passwd", "pwd");
+ passwordFile.deleteOnExit();
+
+ FileWriter writer = null;
+ try
+ {
+ writer = new FileWriter(passwordFile);
+ writer.write(passwordFileEntry);
+ }
+ finally
+ {
+ writer.close();
+ }
+
+ // configure broker to use Base64MD5PasswordFilePrincipalDatabase
+ Map<String, Object> newAttributes = new HashMap<String, Object>();
+ newAttributes.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, passwordFile.getAbsolutePath());
+ newAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+ getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER, newAttributes);
+ }
+}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java
index b01e1d44b8..427934fac2 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java
@@ -18,19 +18,22 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
import java.util.List;
import java.util.Map;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
public class StructureRestTest extends QpidRestTestCase
{
public void testGet() throws Exception
{
- Map<String, Object> structure = getJsonAsMap("/rest/structure");
+ Map<String, Object> structure = getRestTestHelper().getJsonAsMap("/rest/structure");
assertNotNull("Structure data cannot be null", structure);
- assertNode(structure, "Broker");
+ assertNode(structure, "QpidBroker");
@SuppressWarnings("unchecked")
List<Map<String, Object>> virtualhosts = (List<Map<String, Object>>) structure.get("virtualhosts");
@@ -38,15 +41,15 @@ public class StructureRestTest extends QpidRestTestCase
@SuppressWarnings("unchecked")
List<Map<String, Object>> ports = (List<Map<String, Object>>) structure.get("ports");
- assertEquals("Unexpected number of ports", 2, ports.size());
+ assertEquals("Unexpected number of ports", 4, ports.size());
@SuppressWarnings("unchecked")
List<Map<String, Object>> providers = (List<Map<String, Object>>) structure.get("authenticationproviders");
assertEquals("Unexpected number of authentication providers", 1, providers.size());
- for (String hostName : EXPECTED_HOSTS)
+ for (String hostName : EXPECTED_VIRTUALHOSTS)
{
- Map<String, Object> host = find("name", hostName, virtualhosts);
+ Map<String, Object> host = getRestTestHelper().find("name", hostName, virtualhosts);
assertNotNull("Host " + hostName + " is not found ", host);
assertNode(host, hostName);
@@ -55,7 +58,7 @@ public class StructureRestTest extends QpidRestTestCase
assertNotNull("Host " + hostName + " queues are not found ", queues);
for (String queueName : EXPECTED_QUEUES)
{
- Map<String, Object> queue = find("name", queueName, queues);
+ Map<String, Object> queue = getRestTestHelper().find("name", queueName, queues);
assertNotNull(hostName + " queue " + queueName + " is not found ", queue);
assertNode(queue, queueName);
@@ -73,7 +76,7 @@ public class StructureRestTest extends QpidRestTestCase
assertNotNull("Host " + hostName + " exchanges are not found ", exchanges);
for (String exchangeName : EXPECTED_EXCHANGES)
{
- Map<String, Object> exchange = find("name", exchangeName, exchanges);
+ Map<String, Object> exchange = getRestTestHelper().find("name", exchangeName, exchanges);
assertNotNull("Exchange " + exchangeName + " is not found ", exchange);
assertNode(exchange, exchangeName);
if ("amq.direct".equalsIgnoreCase(exchangeName) || "<<default>>".equalsIgnoreCase(exchangeName))
@@ -83,28 +86,24 @@ public class StructureRestTest extends QpidRestTestCase
assertNotNull(hostName + " exchange " + exchangeName + " bindings are not found ", bindings);
for (String queueName : EXPECTED_QUEUES)
{
- Map<String, Object> binding = find("name", queueName, bindings);
+ Map<String, Object> binding = getRestTestHelper().find("name", queueName, bindings);
assertNotNull(hostName + " exchange " + exchangeName + " binding " + queueName + " is not found", binding);
assertNode(binding, queueName);
}
}
}
-
- @SuppressWarnings("unchecked")
- List<Map<String, Object>> aliases = (List<Map<String, Object>>) host.get("virtualhostaliases");
- assertNotNull("Host " + hostName + " aliaces are not found ", aliases);
- assertEquals("Unexpected aliaces size", 1, aliases.size());
- assertNode(aliases.get(0), hostName);
}
- int[] expectedPorts = { getPort(), getHttpPort() };
- for (int port : expectedPorts)
- {
- String portName = "0.0.0.0:" + port;
- Map<String, Object> portData = find("name", portName, ports);
- assertNotNull("Port " + portName + " is not found ", portData);
- assertNode(portData, portName);
- }
+
+ String httpPortName = TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT;
+ Map<String, Object> portData = getRestTestHelper().find(Port.NAME, httpPortName, ports);
+ assertNotNull("Http Port " + httpPortName + " is not found", portData);
+ assertNode(portData, httpPortName);
+
+ String amqpPortName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+ Map<String, Object> amqpPortData = getRestTestHelper().find(Port.NAME, amqpPortName, ports);
+ assertNotNull("Amqp port " + amqpPortName + " is not found", amqpPortData);
+ assertNode(amqpPortData, amqpPortName);
}
private void assertNode(Map<String, Object> node, String name)
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java
index e56fa27e21..017467a8be 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/UserRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java
@@ -18,20 +18,27 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
-import java.net.HttpURLConnection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.qpid.server.model.User;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
public class UserRestTest extends QpidRestTestCase
{
+ @Override
+ public void setUp() throws Exception
+ {
+ getRestTestHelper().configureTemporaryPasswordFile(this, "user1", "user2");
+
+ super.setUp(); // do this last because it starts the broker, using the modified config
+ }
+
public void testGet() throws Exception
{
- List<Map<String, Object>> users = getJsonAsList("/rest/user");
+ List<Map<String, Object>> users = getRestTestHelper().getJsonAsList("/rest/user");
assertNotNull("Users cannot be null", users);
assertTrue("Unexpected number of users", users.size() > 1);
for (Map<String, Object> user : users)
@@ -42,7 +49,7 @@ public class UserRestTest extends QpidRestTestCase
public void testGetUserByName() throws Exception
{
- List<Map<String, Object>> users = getJsonAsList("/rest/user");
+ List<Map<String, Object>> users = getRestTestHelper().getJsonAsList("/rest/user");
assertNotNull("Users cannot be null", users);
assertTrue("Unexpected number of users", users.size() > 1);
for (Map<String, Object> user : users)
@@ -50,8 +57,8 @@ public class UserRestTest extends QpidRestTestCase
assertNotNull("Attribute " + User.ID, user.get(User.ID));
String userName = (String) user.get(User.NAME);
assertNotNull("Attribute " + User.NAME, userName);
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
+ Map<String, Object> userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
assertUser(userDetails);
assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
}
@@ -60,47 +67,27 @@ public class UserRestTest extends QpidRestTestCase
public void testPut() throws Exception
{
String userName = getTestName();
- HttpURLConnection connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName, "PUT");
-
- Map<String, Object> userData = new HashMap<String, Object>();
- userData.put(User.NAME, userName);
- userData.put(User.PASSWORD, userName);
+ getRestTestHelper().createOrUpdateUser(userName, "newPassword");
- writeJsonRequest(connection, userData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
-
- connection.disconnect();
-
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
+ Map<String, Object> userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
assertUser(userDetails);
assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
}
public void testDelete() throws Exception
{
- // add user
String userName = getTestName();
- HttpURLConnection connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName, "PUT");
-
- Map<String, Object> userData = new HashMap<String, Object>();
- userData.put(User.NAME, userName);
- userData.put(User.PASSWORD, userName);
+ getRestTestHelper().createOrUpdateUser(userName, "newPassword");
- writeJsonRequest(connection, userData);
- assertEquals("Unexpected response code", 201, connection.getResponseCode());
- connection.disconnect();
-
- Map<String, Object> userDetails = getJsonAsSingletonList("/rest/user/PrincipalDatabaseAuthenticationManager/"
- + userName);
+ Map<String, Object> userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
String id = (String) userDetails.get(User.ID);
- connection = openManagementConection("/rest/user/PrincipalDatabaseAuthenticationManager?id=" + id, "DELETE");
- connection.connect();
- assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> users = getJsonAsList("/rest/user/PrincipalDatabaseAuthenticationManager/" + userName);
+ getRestTestHelper().removeUserById(id);
+
+ List<Map<String, Object>> users = getRestTestHelper().getJsonAsList("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
assertEquals("User should be deleted", 0, users.size());
}
diff --git a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java
index 17f1aaaf7b..fb2c941203 100644
--- a/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/VirtualHostRestTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java
@@ -18,8 +18,9 @@
* under the License.
*
*/
-package org.apache.qpid.server.management.plugin.servlet.rest;
+package org.apache.qpid.systest.rest;
+import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.HashMap;
@@ -27,12 +28,17 @@ import java.util.List;
import java.util.Map;
import javax.jms.Session;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.server.model.Exchange;
import org.apache.qpid.server.model.Queue;
import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
@@ -46,12 +52,12 @@ public class VirtualHostRestTest extends QpidRestTestCase
public void testGet() throws Exception
{
- List<Map<String, Object>> hosts = getJsonAsList("/rest/virtualhost/");
+ List<Map<String, Object>> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/");
assertNotNull("Hosts data cannot be null", hosts);
- assertEquals("Unexpected number of hosts", 3, hosts.size());
- for (String hostName : EXPECTED_HOSTS)
+ assertEquals("Unexpected number of hosts", EXPECTED_VIRTUALHOSTS.length, hosts.size());
+ for (String hostName : EXPECTED_VIRTUALHOSTS)
{
- Map<String, Object> host = find("name", hostName, hosts);
+ Map<String, Object> host = getRestTestHelper().find("name", hostName, hosts);
Asserts.assertVirtualHost(hostName, host);
}
}
@@ -62,30 +68,29 @@ public class VirtualHostRestTest extends QpidRestTestCase
_connection = (AMQConnection) getConnection();
_connection.createSession(true, Session.SESSION_TRANSACTED);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
Asserts.assertVirtualHost("test", hostDetails);
@SuppressWarnings("unchecked")
Map<String, Object> statistics = (Map<String, Object>) hostDetails.get(Asserts.STATISTICS_ATTRIBUTE);
- assertEquals("Unexpected number of exchanges in statistics", 6, statistics.get(VirtualHost.EXCHANGE_COUNT));
- assertEquals("Unexpected number of queues in statistics", 2, statistics.get(VirtualHost.QUEUE_COUNT));
+ assertEquals("Unexpected number of exchanges in statistics", EXPECTED_EXCHANGES.length, statistics.get(VirtualHost.EXCHANGE_COUNT));
+ assertEquals("Unexpected number of queues in statistics", EXPECTED_QUEUES.length, statistics.get(VirtualHost.QUEUE_COUNT));
assertEquals("Unexpected number of connections in statistics", 1, statistics.get(VirtualHost.CONNECTION_COUNT));
@SuppressWarnings("unchecked")
List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- assertEquals("Unexpected number of exchanges", 6, exchanges.size());
- Asserts.assertDurableExchange("amq.fanout", "fanout", find(Exchange.NAME, "amq.fanout", exchanges));
- Asserts.assertDurableExchange("qpid.management", "management", find(Exchange.NAME, "qpid.management", exchanges));
- Asserts.assertDurableExchange("amq.topic", "topic", find(Exchange.NAME, "amq.topic", exchanges));
- Asserts.assertDurableExchange("amq.direct", "direct", find(Exchange.NAME, "amq.direct", exchanges));
- Asserts.assertDurableExchange("amq.match", "headers", find(Exchange.NAME, "amq.match", exchanges));
- Asserts.assertDurableExchange("<<default>>", "direct", find(Exchange.NAME, "<<default>>", exchanges));
+ assertEquals("Unexpected number of exchanges", EXPECTED_EXCHANGES.length, exchanges.size());
+ Asserts.assertDurableExchange("amq.fanout", "fanout", getRestTestHelper().find(Exchange.NAME, "amq.fanout", exchanges));
+ Asserts.assertDurableExchange("amq.topic", "topic", getRestTestHelper().find(Exchange.NAME, "amq.topic", exchanges));
+ Asserts.assertDurableExchange("amq.direct", "direct", getRestTestHelper().find(Exchange.NAME, "amq.direct", exchanges));
+ Asserts.assertDurableExchange("amq.match", "headers", getRestTestHelper().find(Exchange.NAME, "amq.match", exchanges));
+ Asserts.assertDurableExchange("<<default>>", "direct", getRestTestHelper().find(Exchange.NAME, "<<default>>", exchanges));
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE);
- assertEquals("Unexpected number of queues", 2, queues.size());
- Map<String, Object> queue = find(Queue.NAME, "queue", queues);
- Map<String, Object> ping = find(Queue.NAME, "ping", queues);
+ assertEquals("Unexpected number of queues", EXPECTED_QUEUES.length, queues.size());
+ Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, "queue", queues);
+ Map<String, Object> ping = getRestTestHelper().find(Queue.NAME, "ping", queues);
Asserts.assertQueue("queue", "standard", queue);
Asserts.assertQueue("ping", "standard", ping);
assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, queue.get(Queue.DURABLE));
@@ -98,6 +103,72 @@ public class VirtualHostRestTest extends QpidRestTestCase
Asserts.assertConnection(connections.get(0), _connection);
}
+ public void testPutCreateVirtualHostUsingStoreType() throws Exception
+ {
+ String hostName = getTestName();
+ String storeType = getTestProfileMessageStoreType();
+ String storeLocation = createHost(hostName, storeType, null);
+ try
+ {
+ // make sure that the host is saved in the broker store
+ restartBroker();
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostName);
+ Asserts.assertVirtualHost(hostName, hostDetails);
+ assertEquals("Unexpected store type", storeType, hostDetails.get(VirtualHost.STORE_TYPE));
+
+ assertNewVirtualHost(hostDetails);
+ }
+ finally
+ {
+ if (storeLocation != null)
+ {
+ FileUtils.delete(new File(storeLocation), true);
+ }
+ }
+ }
+
+ public void testPutCreateVirtualHostUsingConfigPath() throws Exception
+ {
+ String hostName = getTestName();
+ File configFile = TestFileUtils.createTempFile(this, hostName + "-config.xml");
+ String configPath = configFile.getAbsolutePath();
+ String storeLocation = getStoreLocation(hostName);
+ createAndSaveVirtualHostConfiguration(hostName, configFile, storeLocation);
+ createHost(hostName, null, configPath);
+ try
+ {
+ // make sure that the host is saved in the broker store
+ restartBroker();
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostName);
+ Asserts.assertVirtualHost(hostName, hostDetails);
+ assertEquals("Unexpected config path", configPath, hostDetails.get(VirtualHost.CONFIG_PATH));
+
+ assertNewVirtualHost(hostDetails);
+ }
+ finally
+ {
+ if (storeLocation != null)
+ {
+ FileUtils.delete(new File(storeLocation), true);
+ }
+ configFile.delete();
+ }
+ }
+
+ public void testDeleteHost() throws Exception
+ {
+ String hostToDelete = TEST3_VIRTUALHOST;
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostToDelete, "DELETE");
+ connection.connect();
+ assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+ // make sure that changes are saved in the broker store
+ restartBroker();
+
+ List<Map<String, Object>> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/" + hostToDelete);
+ assertEquals("Host should be deleted", 0, hosts.size());
+ }
+
public void testPutCreateQueue() throws Exception
{
String queueName = getTestQueueName();
@@ -116,14 +187,14 @@ public class VirtualHostRestTest extends QpidRestTestCase
lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
- Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
+ Map<String, Object> standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+ Map<String, Object> sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+ Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+ Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
Asserts.assertQueue(queueName + "-standard", "standard", standardQueue);
Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue);
@@ -149,14 +220,14 @@ public class VirtualHostRestTest extends QpidRestTestCase
createExchange(exchangeName + "-headers", "headers");
createExchange(exchangeName + "-fanout", "fanout");
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- Map<String, Object> directExchange = find(Queue.NAME, exchangeName + "-direct" , exchanges);
- Map<String, Object> topicExchange = find(Queue.NAME, exchangeName + "-topic" , exchanges);
- Map<String, Object> headersExchange = find(Queue.NAME, exchangeName + "-headers" , exchanges);
- Map<String, Object> fanoutExchange = find(Queue.NAME, exchangeName + "-fanout" , exchanges);
+ Map<String, Object> directExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-direct" , exchanges);
+ Map<String, Object> topicExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-topic" , exchanges);
+ Map<String, Object> headersExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-headers" , exchanges);
+ Map<String, Object> fanoutExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-fanout" , exchanges);
Asserts.assertDurableExchange(exchangeName + "-direct", "direct", directExchange);
Asserts.assertDurableExchange(exchangeName + "-topic", "topic", topicExchange);
@@ -175,11 +246,11 @@ public class VirtualHostRestTest extends QpidRestTestCase
String queueName = getTestQueueName()+ "-lvq";
createQueue(queueName, "lvq", null);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName , queues);
+ Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName , queues);
Asserts.assertQueue(queueName , "lvq", lvqQueue);
assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
@@ -190,13 +261,13 @@ public class VirtualHostRestTest extends QpidRestTestCase
{
String queueName = getTestQueueName() + "-sorted";
int responseCode = tryCreateQueue(queueName, "sorted", null);
- assertEquals("Unexpected response code", 409, responseCode);
+ assertEquals("Unexpected response code", HttpServletResponse.SC_CONFLICT, responseCode);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> testQueue = find(Queue.NAME, queueName , queues);
+ Map<String, Object> testQueue = getRestTestHelper().find(Queue.NAME, queueName , queues);
assertNull("Sorted queue without a key was created ", testQueue);
}
@@ -206,11 +277,11 @@ public class VirtualHostRestTest extends QpidRestTestCase
String queueName = getTestQueueName()+ "-priority";
createQueue(queueName, "priority", null);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName , queues);
+ Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName , queues);
Asserts.assertQueue(queueName , "priority", priorityQueue);
assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
@@ -222,11 +293,11 @@ public class VirtualHostRestTest extends QpidRestTestCase
String queueName = getTestQueueName();
createQueue(queueName, null, null);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
+ Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName , queues);
Asserts.assertQueue(queueName , "standard", queue);
}
@@ -235,13 +306,13 @@ public class VirtualHostRestTest extends QpidRestTestCase
{
String queueName = getTestQueueName();
int responseCode = tryCreateQueue(queueName, "unsupported", null);
- assertEquals("Unexpected response code", 409, responseCode);
+ assertEquals("Unexpected response code", HttpServletResponse.SC_CONFLICT, responseCode);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
+ Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName , queues);
assertNull("Queue of unsupported type was created", queue);
}
@@ -251,10 +322,10 @@ public class VirtualHostRestTest extends QpidRestTestCase
String queueName = getTestQueueName();
createQueue(queueName, null, null);
- HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "DELETE");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+ List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
assertEquals("Queue should be deleted", 0, queues.size());
}
@@ -262,12 +333,12 @@ public class VirtualHostRestTest extends QpidRestTestCase
{
String queueName = getTestQueueName();
createQueue(queueName, null, null);
- Map<String, Object> queueDetails = getJsonAsSingletonList("/rest/queue/test/" + queueName);
+ Map<String, Object> queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
- HttpURLConnection connection = openManagementConection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> queues = getJsonAsList("/rest/queue/test/" + queueName);
+ List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
assertEquals("Queue should be deleted", 0, queues.size());
}
@@ -276,10 +347,10 @@ public class VirtualHostRestTest extends QpidRestTestCase
String exchangeName = getTestName();
createExchange(exchangeName, "direct");
- HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "DELETE");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+ List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
assertEquals("Exchange should be deleted", 0, queues.size());
}
@@ -287,12 +358,12 @@ public class VirtualHostRestTest extends QpidRestTestCase
{
String exchangeName = getTestName();
createExchange(exchangeName, "direct");
- Map<String, Object> echangeDetails = getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
+ Map<String, Object> echangeDetails = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
- HttpURLConnection connection = openManagementConection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
connection.connect();
assertEquals("Unexpected response code", 200, connection.getResponseCode());
- List<Map<String, Object>> queues = getJsonAsList("/rest/exchange/test/" + exchangeName);
+ List<Map<String, Object>> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
assertEquals("Exchange should be deleted", 0, queues.size());
}
@@ -326,14 +397,14 @@ public class VirtualHostRestTest extends QpidRestTestCase
lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
@SuppressWarnings("unchecked")
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
- Map<String, Object> standardQueue = find(Queue.NAME, queueName + "-standard" , queues);
- Map<String, Object> sortedQueue = find(Queue.NAME, queueName + "-sorted" , queues);
- Map<String, Object> priorityQueue = find(Queue.NAME, queueName + "-priority" , queues);
- Map<String, Object> lvqQueue = find(Queue.NAME, queueName + "-lvq" , queues);
+ Map<String, Object> standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+ Map<String, Object> sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+ Map<String, Object> priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+ Map<String, Object> lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
attributes.put(Queue.DURABLE, Boolean.TRUE);
Asserts.assertQueue(queueName + "-standard", "standard", standardQueue, attributes);
@@ -355,25 +426,25 @@ public class VirtualHostRestTest extends QpidRestTestCase
attributes.put(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
//verify the starting state
- Map<String, Object> hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ Map<String, Object> hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
List<Map<String, Object>> queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- assertNull("queue should not have already been present", find(Queue.NAME, queueName , queues));
- assertNull("queue should not have already been present", find(Queue.NAME, queueName + "_DLQ" , queues));
- assertNull("exchange should not have already been present", find(Exchange.NAME, queueName + "_DLE" , exchanges));
+ assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName , queues));
+ assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues));
+ assertNull("exchange should not have already been present", getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges));
//create the queue
createQueue(queueName, "standard", attributes);
//verify the new queue, as well as the DLQueue and DLExchange have been created
- hostDetails = getJsonAsSingletonList("/rest/virtualhost/test");
+ hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
queues = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
exchanges = (List<Map<String, Object>>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
- Map<String, Object> queue = find(Queue.NAME, queueName , queues);
- Map<String, Object> dlqQueue = find(Queue.NAME, queueName + "_DLQ" , queues);
- Map<String, Object> dlExchange = find(Exchange.NAME, queueName + "_DLE" , exchanges);
+ Map<String, Object> queue = getRestTestHelper().find(Queue.NAME, queueName , queues);
+ Map<String, Object> dlqQueue = getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues);
+ Map<String, Object> dlExchange = getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges);
assertNotNull("queue should not have been present", queue);
assertNotNull("queue should not have been present", dlqQueue);
assertNotNull("exchange should not have been present", dlExchange);
@@ -388,14 +459,14 @@ public class VirtualHostRestTest extends QpidRestTestCase
private void createExchange(String exchangeName, String exchangeType) throws IOException
{
- HttpURLConnection connection = openManagementConection("/rest/exchange/test/" + exchangeName, "PUT");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "PUT");
Map<String, Object> queueData = new HashMap<String, Object>();
queueData.put(Exchange.NAME, exchangeName);
queueData.put(Exchange.DURABLE, Boolean.TRUE);
queueData.put(Exchange.TYPE, exchangeType);
- writeJsonRequest(connection, queueData);
+ getRestTestHelper().writeJsonRequest(connection, queueData);
assertEquals("Unexpected response code", 201, connection.getResponseCode());
connection.disconnect();
@@ -411,7 +482,7 @@ public class VirtualHostRestTest extends QpidRestTestCase
private int tryCreateQueue(String queueName, String queueType, Map<String, Object> attributes) throws IOException,
JsonGenerationException, JsonMappingException
{
- HttpURLConnection connection = openManagementConection("/rest/queue/test/" + queueName, "PUT");
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "PUT");
Map<String, Object> queueData = new HashMap<String, Object>();
queueData.put(Queue.NAME, queueName);
@@ -425,10 +496,81 @@ public class VirtualHostRestTest extends QpidRestTestCase
queueData.putAll(attributes);
}
- writeJsonRequest(connection, queueData);
+ getRestTestHelper().writeJsonRequest(connection, queueData);
+ int responseCode = connection.getResponseCode();
+ connection.disconnect();
+ return responseCode;
+ }
+
+ private String createHost(String hostName, String storeType, String configPath) throws IOException, JsonGenerationException,
+ JsonMappingException
+ {
+ String storePath = getStoreLocation(hostName);
+ int responseCode = tryCreateVirtualHost(hostName, storeType, storePath, configPath);
+ assertEquals("Unexpected response code", 201, responseCode);
+ return storePath;
+ }
+
+ private String getStoreLocation(String hostName)
+ {
+ return new File(TMP_FOLDER, "store-" + hostName + "-" + System.currentTimeMillis()).getAbsolutePath();
+ }
+
+ private int tryCreateVirtualHost(String hostName, String storeType, String storePath, String configPath) throws IOException,
+ JsonGenerationException, JsonMappingException
+ {
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostName, "PUT");
+
+ Map<String, Object> hostData = new HashMap<String, Object>();
+ hostData.put(VirtualHost.NAME, hostName);
+ if (storeType == null)
+ {
+ hostData.put(VirtualHost.CONFIG_PATH, configPath);
+ }
+ else
+ {
+ hostData.put(VirtualHost.STORE_PATH, storePath);
+ hostData.put(VirtualHost.STORE_TYPE, storeType);
+ }
+
+ getRestTestHelper().writeJsonRequest(connection, hostData);
int responseCode = connection.getResponseCode();
connection.disconnect();
return responseCode;
}
+ private XMLConfiguration createAndSaveVirtualHostConfiguration(String hostName, File configFile, String storeLocation)
+ throws ConfigurationException
+ {
+ XMLConfiguration testConfiguration = new XMLConfiguration();
+ testConfiguration.setProperty("virtualhosts.virtualhost." + hostName + ".store.class",
+ getTestProfileMessageStoreClassName());
+ testConfiguration.setProperty("virtualhosts.virtualhost." + hostName + ".store.environment-path", storeLocation);
+ testConfiguration.save(configFile);
+ return testConfiguration;
+ }
+
+ private void assertNewVirtualHost(Map<String, Object> hostDetails)
+ {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> statistics = (Map<String, Object>) hostDetails.get(Asserts.STATISTICS_ATTRIBUTE);
+ assertEquals("Unexpected number of exchanges in statistics", EXPECTED_EXCHANGES.length,
+ statistics.get(VirtualHost.EXCHANGE_COUNT));
+ assertEquals("Unexpected number of queues in statistics", 0, statistics.get(VirtualHost.QUEUE_COUNT));
+ assertEquals("Unexpected number of connections in statistics", 0, statistics.get(VirtualHost.CONNECTION_COUNT));
+
+ @SuppressWarnings("unchecked")
+ List<Map<String, Object>> exchanges = (List<Map<String, Object>>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+ assertEquals("Unexpected number of exchanges", EXPECTED_EXCHANGES.length, exchanges.size());
+ RestTestHelper restTestHelper = getRestTestHelper();
+ Asserts.assertDurableExchange("amq.fanout", "fanout", restTestHelper.find(Exchange.NAME, "amq.fanout", exchanges));
+ Asserts.assertDurableExchange("amq.topic", "topic", restTestHelper.find(Exchange.NAME, "amq.topic", exchanges));
+ Asserts.assertDurableExchange("amq.direct", "direct", restTestHelper.find(Exchange.NAME, "amq.direct", exchanges));
+ Asserts.assertDurableExchange("amq.match", "headers", restTestHelper.find(Exchange.NAME, "amq.match", exchanges));
+ Asserts.assertDurableExchange("<<default>>", "direct", restTestHelper.find(Exchange.NAME, "<<default>>", exchanges));
+
+ assertNull("Unexpected queues", hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE));
+ assertNull("Unexpected connections", hostDetails.get(VIRTUALHOST_CONNECTIONS_ATTRIBUTE));
+ }
+
}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java
new file mode 100644
index 0000000000..40ea723b1e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java
@@ -0,0 +1,197 @@
+/*
+ *
+ * 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.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+import org.apache.qpid.systest.rest.QpidRestTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class GroupRestACLTest extends QpidRestTestCase
+{
+ private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+
+ private static final String ALLOWED_GROUP = "allowedGroup";
+ private static final String DENIED_GROUP = "deniedGroup";
+ private static final String OTHER_GROUP = "otherGroup";
+
+ private static final String ALLOWED_USER = "webadmin";
+ private static final String DENIED_USER = "admin";
+ private static final String OTHER_USER = "admin";
+
+ private File _groupFile;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _groupFile = createTemporaryGroupFile();
+ getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+ //DONT call super.setUp(), the tests will start the broker after configuring it
+ }
+
+ @Override
+ protected void customizeConfiguration() throws ConfigurationException, IOException
+ {
+ super.customizeConfiguration();
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_groupFile != null)
+ {
+ if (_groupFile.exists())
+ {
+ _groupFile.delete();
+ }
+ }
+ }
+
+ private File createTemporaryGroupFile() throws Exception
+ {
+ File groupFile = File.createTempFile("group", "grp");
+ groupFile.deleteOnExit();
+
+ Properties props = new Properties();
+ props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+ props.put(DENIED_GROUP + ".users", DENIED_USER);
+ props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+ props.store(new FileOutputStream(groupFile), "test group file");
+
+ return groupFile;
+ }
+
+ public void testCreateGroup() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE GROUP",
+ "ACL DENY-LOG " + DENIED_GROUP + " CREATE GROUP");
+
+ //Start the broker with the custom config
+ super.setUp();
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 3);
+
+ getRestTestHelper().createGroup("newGroup", FILE_GROUP_MANAGER);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 4);
+
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+ getRestTestHelper().createGroup("anotherNewGroup", FILE_GROUP_MANAGER, HttpServletResponse.SC_FORBIDDEN);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 4);
+ }
+
+ public void testDeleteGroup() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE GROUP",
+ "ACL DENY-LOG " + DENIED_GROUP + " DELETE GROUP");
+
+ //Start the broker with the custom config
+ super.setUp();
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+ Map<String, Object> data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 3);
+
+ getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER, HttpServletResponse.SC_FORBIDDEN);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 3);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+ getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER);
+
+ data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+ getRestTestHelper().assertNumberOfGroups(data, 2);
+ }
+
+ public void testUpdateGroupAddMember() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+ "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+ //Start the broker with the custom config
+ super.setUp();
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+ assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+ getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember", HttpServletResponse.SC_FORBIDDEN);
+ assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+ getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember");
+ assertNumberOfGroupMembers(OTHER_GROUP, 2);
+ }
+
+ public void testUpdateGroupDeleteMember() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+ "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+ //Start the broker with the custom config
+ super.setUp();
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+ assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+ getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER, HttpServletResponse.SC_FORBIDDEN);
+ assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+ getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER);
+ assertNumberOfGroupMembers(OTHER_GROUP, 0);
+ }
+
+ private void assertNumberOfGroupMembers(String groupName, int expectedNumberOfMembers) throws IOException
+ {
+ Map<String, Object> group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/" + groupName);
+ getRestTestHelper().assertNumberOfGroupMembers(group, expectedNumberOfMembers);
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java
new file mode 100644
index 0000000000..12973113d8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+import org.apache.qpid.systest.rest.QpidRestTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class UserRestACLTest extends QpidRestTestCase
+{
+ private static final String ALLOWED_GROUP = "allowedGroup";
+ private static final String DENIED_GROUP = "deniedGroup";
+ private static final String OTHER_GROUP = "otherGroup";
+
+ private static final String ALLOWED_USER = "webadmin";
+ private static final String DENIED_USER = "admin";
+ private static final String OTHER_USER = "other";
+
+ private File _groupFile;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _groupFile = createTemporaryGroupFile();
+ getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+ getRestTestHelper().configureTemporaryPasswordFile(this, ALLOWED_USER, DENIED_USER, OTHER_USER);
+
+ //DONT call super.setUp(), the tests will start the broker after configuring it
+ }
+
+ @Override
+ protected void customizeConfiguration() throws ConfigurationException, IOException
+ {
+ super.customizeConfiguration();
+ getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (_groupFile != null)
+ {
+ if (_groupFile.exists())
+ {
+ _groupFile.delete();
+ }
+ }
+ }
+
+ private File createTemporaryGroupFile() throws Exception
+ {
+ File groupFile = File.createTempFile("group", "grp");
+ groupFile.deleteOnExit();
+
+ Properties props = new Properties();
+ props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+ props.put(DENIED_GROUP + ".users", DENIED_USER);
+ props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+ props.store(new FileOutputStream(groupFile), "test group file");
+
+ return groupFile;
+ }
+
+ public void testAddUser() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE USER",
+ "ACL DENY-LOG " + DENIED_GROUP + " CREATE USER");
+
+ //Start the broker with the custom config
+ super.setUp();
+
+ String newUser = "newUser";
+ String password = "password";
+
+ assertUserDoesNotExist(newUser);
+
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+ getRestTestHelper().createOrUpdateUser(newUser, password, HttpServletResponse.SC_FORBIDDEN);
+ assertUserDoesNotExist(newUser);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+ getRestTestHelper().createOrUpdateUser(newUser, password);
+ assertUserExists(newUser);
+ }
+
+ public void testDeleteUser() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE USER",
+ "ACL DENY-LOG " + DENIED_GROUP + " DELETE USER");
+
+ //Start the broker with the custom config
+ super.setUp();
+
+ assertUserExists(OTHER_USER);
+
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+ getRestTestHelper().removeUser(OTHER_USER, HttpServletResponse.SC_FORBIDDEN);
+ assertUserExists(OTHER_USER);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+ getRestTestHelper().removeUser(OTHER_USER);
+ assertUserDoesNotExist(OTHER_USER);
+ }
+
+ public void testUpdateUser() throws Exception
+ {
+ AbstractACLTestCase.writeACLFileUtil(this, null,
+ "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+ "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE USER",
+ "ACL DENY-LOG " + DENIED_GROUP + " UPDATE USER");
+
+ //Start the broker with the custom config
+ super.setUp();
+
+ String newPassword = "newPassword";
+
+ checkPassword(OTHER_USER, OTHER_USER, true);
+
+ getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+ getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_FORBIDDEN);
+
+ checkPassword(OTHER_USER, newPassword, false);
+
+ getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+ getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_OK); // expect SC_OK rather than the default SC_CREATED
+
+ checkPassword(OTHER_USER, newPassword, true);
+ checkPassword(OTHER_USER, OTHER_USER, false);
+ }
+
+ private void checkPassword(String username, String password, boolean passwordExpectedToBeCorrect) throws IOException
+ {
+ getRestTestHelper().setUsernameAndPassword(username, password);
+ HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/user/"
+ + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/", "GET");
+
+ boolean passwordIsCorrect = connection.getResponseCode() == HttpServletResponse.SC_OK;
+
+ connection.disconnect();
+
+ assertEquals(passwordExpectedToBeCorrect, passwordIsCorrect);
+ }
+
+ private void assertUserDoesNotExist(String newUser) throws JsonParseException, JsonMappingException, IOException
+ {
+ String path = "/rest/user/" + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + newUser;
+ List<Map<String, Object>> userDetailsList = getRestTestHelper().getJsonAsList(path);
+ assertTrue(userDetailsList.isEmpty());
+ }
+
+ private void assertUserExists(String username) throws IOException
+ {
+ String path = "/rest/user/" + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username;
+ Map<String, Object> userDetails = getRestTestHelper().getJsonAsSingletonList(path);
+
+ assertEquals(
+ "User returned by " + path + " should have name=" + username + ". The returned JSON was: " + userDetails,
+ username,
+ userDetails.get("name"));
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
index a53c3d3ee0..2ed3f356d3 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
@@ -40,19 +40,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Description:
*
* The problem that this test is exposing is that the dispatcher used to be capable
- * of holding on to a message when stopped. This ment that when the rollback was
+ * of holding on to a message when stopped. This meant that when the rollback was
* called and the dispatcher stopped it may have hold of a message. So after all
* the local queues(preDeliveryQueue, SynchronousQueue, PostDeliveryTagQueue)
* have been cleared the client still had a single message, the one the
* dispatcher was holding on to.
*
* As a result the TxRollback operation would run and then release the dispatcher.
- * Whilst the dispatcher would then proceed to reject the message it was holiding
+ * Whilst the dispatcher would then proceed to reject the message it was holding
* the Broker would already have resent that message so the rejection would silently
* fail.
*
- * And the client would receieve that single message 'early', depending on the
- * number of messages already recevied when rollback was called.
+ * And the client would receive that single message 'early', depending on the
+ * number of messages already received when rollback was called.
*
*
* Aims:
@@ -78,7 +78,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* as expected.
*
* We are testing a race condition here but we can check through the log file if
- * the race condition occured. However, performing that check will only validate
+ * the race condition occurred. However, performing that check will only validate
* the problem exists and will not be suitable as part of a system test.
*
*/
@@ -183,18 +183,8 @@ public class RollbackOrderTest extends QpidBrokerTestCase
}
}
-// _consumer.close();
_connection.close();
assertFalse("Exceptions thrown during test run, Check Std.err.", failed.get());
}
-
- @Override public void tearDown() throws Exception
- {
-
- drainQueue(_queue);
-
- super.tearDown();
- }
-
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
index e1f93b975b..22a98b6f42 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
@@ -29,8 +29,6 @@ import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQSession_0_10;
import org.apache.qpid.client.message.QpidMessageProperties;
-import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
import org.apache.qpid.messaging.Address;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
@@ -98,7 +96,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue should not be created",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest, (QueueNode)dest.getSourceNode() ,true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest,false));
// create always -------------------------------------------
@@ -107,10 +105,10 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons = jmsSession.createConsumer(dest);
assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
assertTrue("Queue not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
- dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+ dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
// create receiver -----------------------------------------
addr1 = "ADDR:testQueue2; { create: receiver }";
@@ -126,16 +124,16 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue should not be created",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
cons = jmsSession.createConsumer(dest);
assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
assertTrue("Queue not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
- dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+ dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
// create never --------------------------------------------
addr1 = "ADDR:testQueue3; { create: never }";
@@ -161,7 +159,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue should not be created",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
// create sender ------------------------------------------
addr1 = "ADDR:testQueue3; { create: sender }";
@@ -177,14 +175,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"doesn't resolve to an exchange or a queue"));
}
assertFalse("Queue should not be created",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
prod = jmsSession.createProducer(dest);
assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
assertTrue("Queue not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
- dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+ dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
}
@@ -221,7 +219,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
// Even if the consumer is closed the queue and the bindings should be intact.
assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
assertTrue("Queue not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
@@ -326,7 +324,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertTrue("Exchange not created as expected",(
- (AMQSession_0_10)jmsSession).isExchangeExist(dest, (ExchangeNode)dest.getTargetNode() , true));
+ (AMQSession_0_10)jmsSession).isExchangeExist(dest,true));
// The existence of the queue is implicitly tested here
assertTrue("Queue not bound as expected",(
@@ -367,7 +365,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
public void checkQueueForBindings(Session jmsSession, AMQDestination dest,String headersBinding) throws Exception
{
assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
assertTrue("Queue not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
@@ -506,14 +504,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
MessageConsumer cons3 = jmsSession.createConsumer(dest3);
assertTrue("Destination1 was not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest1,(QueueNode)dest1.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest1, true));
assertTrue("Destination1 was not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
dest1.getAddressName(),dest1.getAddressName(), null));
assertTrue("Destination2 was not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest2,(QueueNode)dest2.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest2,true));
assertTrue("Destination2 was not bound as expected",(
(AMQSession_0_10)jmsSession).isQueueBound("",
@@ -602,14 +600,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons.close();
// Using the ADDR method to create a more complicated queue
- String addr = "ADDR:amq.direct/x512; {create: receiver, " +
+ String addr = "ADDR:amq.direct/x512; {" +
"link : {name : 'MY.RESP.QUEUE', " +
"x-declare : { auto-delete: true, exclusive: true, " +
"arguments : {'qpid.max_size': 1000, 'qpid.policy_type': ring} } } }";
queue = ssn.createQueue(addr);
- prod = ssn.createProducer(queue);
cons = ssn.createConsumer(queue);
+ prod = ssn.createProducer(queue);
assertTrue("MY.RESP.QUEUE was not created as expected",(
(AMQSession_0_10)ssn).isQueueBound("amq.direct",
"MY.RESP.QUEUE","x512", null));
@@ -677,8 +675,8 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
// Using the ADDR method to create a more complicated topic
topic = ssn.createTopic(addr);
- prod = ssn.createProducer(topic);
cons = ssn.createConsumer(topic);
+ prod = ssn.createProducer(topic);
assertTrue("The queue was not bound to vehicle exchange using bus as the binding key",(
(AMQSession_0_10)ssn).isQueueBound("vehicles",
@@ -778,7 +776,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
public void testSubscriptionForSameDestination() throws Exception
{
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- Destination dest = ssn.createTopic("ADDR:amq.topic/foo; {link:{durable:true}}");
+ Destination dest = ssn.createTopic("ADDR:amq.topic/foo");
MessageConsumer consumer1 = ssn.createConsumer(dest);
MessageConsumer consumer2 = ssn.createConsumer(dest);
MessageProducer prod = ssn.createProducer(dest);
@@ -840,7 +838,8 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"}";
// Using the ADDR method to create a more complicated topic
- MessageConsumer cons = ssn.createConsumer(new AMQAnyDestination(addr));
+ Topic topic = ssn.createTopic(addr);
+ MessageConsumer cons = ssn.createConsumer(topic);
assertTrue("The queue was not bound to MRKT exchange using NYSE.# as the binding key",(
(AMQSession_0_10)ssn).isQueueBound("MRKT",
@@ -854,7 +853,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
(AMQSession_0_10)ssn).isQueueBound("MRKT",
"my-topic","CNTL.#", null));
- MessageProducer prod = ssn.createProducer(ssn.createTopic(addr));
+ MessageProducer prod = ssn.createProducer(topic);
Message msg = ssn.createTextMessage("test");
msg.setStringProperty("qpid.subject", "NASDAQ.ABCD");
prod.send(msg);
@@ -909,32 +908,31 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
{
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+ String bindingStr = "x-bindings:[{key:'NYSE.#'},{key:'NASDAQ.#'},{key:'CNTL.#'}]}}";
+
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
- props.setProperty("destination.address1", "ADDR:amq.topic");
- props.setProperty("destination.address2", "ADDR:amq.direct/test");
- String addrStr = "ADDR:amq.topic/test; {link:{name: my-topic," +
- "x-bindings:[{key:'NYSE.#'},{key:'NASDAQ.#'},{key:'CNTL.#'}]}}";
- props.setProperty("destination.address3", addrStr);
- props.setProperty("topic.address4", "hello.world");
- addrStr = "ADDR:my_queue; {create:always,link: {x-subscribes:{exclusive: true, arguments: {a:b,x:y}}}}";
+ props.setProperty("destination.address1", "ADDR:amq.topic/test");
+ props.setProperty("destination.address2", "ADDR:amq.topic/test; {node:{" + bindingStr);
+ props.setProperty("destination.address3", "ADDR:amq.topic/test; {link:{" + bindingStr);
+ String addrStr = "ADDR:my_queue; {create:always,link: {x-subscribes:{exclusive: true, arguments: {a:b,x:y}}}}";
props.setProperty("destination.address5", addrStr);
Context ctx = new InitialContext(props);
- for (int i=1; i < 5; i++)
+ for (int i=1; i < 4; i++)
{
Topic topic = (Topic) ctx.lookup("address"+i);
- createDurableSubscriber(ctx,ssn,"address"+i,topic);
+ createDurableSubscriber(ctx,ssn,"address"+i,topic,"ADDR:amq.topic/test");
}
Topic topic = ssn.createTopic("ADDR:news.us");
- createDurableSubscriber(ctx,ssn,"my-dest",topic);
+ createDurableSubscriber(ctx,ssn,"my-dest",topic,"ADDR:news.us");
Topic namedQueue = (Topic) ctx.lookup("address5");
try
{
- createDurableSubscriber(ctx,ssn,"my-queue",namedQueue);
+ createDurableSubscriber(ctx,ssn,"my-queue",namedQueue,"ADDR:amq.topic/test");
fail("Exception should be thrown. Durable subscribers cannot be created for Queues");
}
catch(JMSException e)
@@ -943,16 +941,74 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
e.getMessage());
}
}
-
- private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic) throws Exception
+
+ public void testDurableSubscription() throws Exception
+ {
+ Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = session.createTopic("ADDR:amq.topic/" + getTestQueueName());
+ MessageProducer publisher = session.createProducer(topic);
+ MessageConsumer subscriber = session.createDurableSubscriber(topic, getTestQueueName());
+
+ TextMessage messageToSend = session.createTextMessage("Test0");
+ publisher.send(messageToSend);
+ ((AMQSession<?,?>)session).sync();
+
+ Message receivedMessage = subscriber.receive(1000);
+ assertNotNull("Message has not been received", receivedMessage);
+ assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+
+ subscriber.close();
+
+ messageToSend = session.createTextMessage("Test1");
+ publisher.send(messageToSend);
+ ((AMQSession<?,?>)session).sync();
+
+ subscriber = session.createDurableSubscriber(topic, getTestQueueName());
+ receivedMessage = subscriber.receive(1000);
+ assertNotNull("Message has not been received", receivedMessage);
+ assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+ }
+
+ public void testDurableSubscriptionnWithSelector() throws Exception
+ {
+ Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = session.createTopic("ADDR:amq.topic/" + getTestQueueName());
+ MessageProducer publisher = session.createProducer(topic);
+ MessageConsumer subscriber = session.createDurableSubscriber(topic, getTestQueueName(), "id=1", false);
+
+ TextMessage messageToSend = session.createTextMessage("Test0");
+ messageToSend.setIntProperty("id", 1);
+ publisher.send(messageToSend);
+ ((AMQSession<?,?>)session).sync();
+
+ Message receivedMessage = subscriber.receive(1000);
+ assertNotNull("Message has not been received", receivedMessage);
+ assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+ assertEquals("Unexpected id", 1, receivedMessage.getIntProperty("id"));
+
+ subscriber.close();
+
+ messageToSend = session.createTextMessage("Test1");
+ messageToSend.setIntProperty("id", 1);
+ publisher.send(messageToSend);
+ ((AMQSession<?,?>)session).sync();
+
+ subscriber = session.createDurableSubscriber(topic, getTestQueueName(), "id=1", false);
+ receivedMessage = subscriber.receive(1000);
+ assertNotNull("Message has not been received", receivedMessage);
+ assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+ assertEquals("Unexpected id", 1, receivedMessage.getIntProperty("id"));
+ }
+
+ private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic, String producerAddr) throws Exception
{
MessageConsumer cons = ssn.createDurableSubscriber(topic, destName);
- MessageProducer prod = ssn.createProducer(topic);
+ MessageProducer prod = ssn.createProducer(ssn.createTopic(producerAddr));
Message m = ssn.createTextMessage(destName);
prod.send(m);
Message msg = cons.receive(1000);
- assertNotNull(msg);
+ assertNotNull("Message not received as expected when using Topic : " + topic,msg);
assertEquals(destName,((TextMessage)msg).getText());
ssn.unsubscribe(destName);
}
@@ -977,7 +1033,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
String addr2 = "ADDR:testQueue2;{create: always, delete: receiver}";
@@ -993,7 +1049,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
String addr3 = "ADDR:testQueue3;{create: always, delete: sender}";
@@ -1010,9 +1066,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
+ (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
}
/**
@@ -1094,7 +1148,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
MessageConsumer cons = ssn.createConsumer(ssn.createTopic("ADDR:amq.topic/test"));
MessageProducer prod = ssn.createProducer(null);
- Queue queue = ssn.createQueue("ADDR:amq.topic/test");
+ Topic queue = ssn.createTopic("ADDR:amq.topic/test");
prod.send(queue,ssn.createTextMessage("A"));
Message msg = cons.receive(1000);
@@ -1307,4 +1361,62 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
assertNotNull("message should be re-received by consumer after rollback", receivedMessage);
jmsSession.commit();
}
+
+ /**
+ * Test Goals :
+ *
+ * 1. Verify that link bindings are created and destroyed after creating and closing a subscriber.
+ * 2. Verify that link bindings are created and destroyed after creating and closing a subscriber.
+ */
+ public void testLinkBindingBehavior() throws Exception
+ {
+ Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+ String addr = "ADDR:my-queue; {create: always, " +
+ "link: " +
+ "{" +
+ "x-bindings: [{exchange : 'amq.direct', key : test}]," +
+ "}" +
+ "}";
+
+ AMQDestination dest = (AMQDestination)jmsSession.createQueue(addr);
+ MessageConsumer cons = jmsSession.createConsumer(dest);
+ AMQSession_0_10 ssn = (AMQSession_0_10)jmsSession;
+
+ assertTrue("Queue not created as expected",ssn.isQueueExist(dest, true));
+ assertTrue("Queue not bound as expected",ssn.isQueueBound("amq.direct","my-queue","test", null));
+
+ cons.close(); // closing consumer, link binding should be removed now.
+ assertTrue("Queue should still be there",ssn.isQueueExist(dest, true));
+ assertFalse("Binding should not exist anymore",ssn.isQueueBound("amq.direct","my-queue","test", null));
+
+ MessageProducer prod = jmsSession.createProducer(dest);
+ assertTrue("Queue not bound as expected",ssn.isQueueBound("amq.direct","my-queue","test", null));
+ prod.close();
+ assertFalse("Binding should not exist anymore",ssn.isQueueBound("amq.direct","my-queue","test", null));
+ }
+
+ /**
+ * Test Goals : Verifies that the subscription queue created is as specified under link properties.
+ */
+ public void testCustomizingSubscriptionQueue() throws Exception
+ {
+ Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+ String xDeclareArgs = "x-declare: { exclusive: false, auto-delete: false," +
+ "alternate-exchange: 'amq.fanout'," +
+ "arguments: {'qpid.max_size': 1000,'qpid.max_count': 100}" +
+ "}";
+
+ String addr = "ADDR:amq.topic/test; {link: {name:my-queue, durable:true," + xDeclareArgs + "}}";
+ Destination dest = ssn.createTopic(addr);
+ MessageConsumer cons = ssn.createConsumer(dest);
+
+ String verifyAddr = "ADDR:my-queue;{ node: {durable:true, " + xDeclareArgs + "}}";
+ AMQDestination verifyDest = (AMQDestination)ssn.createQueue(verifyAddr);
+ ((AMQSession_0_10)ssn).isQueueExist(verifyDest, true);
+
+ // Verify that the producer does not delete the subscription queue.
+ MessageProducer prod = ssn.createProducer(dest);
+ prod.close();
+ ((AMQSession_0_10)ssn).isQueueExist(verifyDest, true);
+ }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
index b82c3756f2..2875e2c6b1 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
@@ -24,6 +24,7 @@ package org.apache.qpid.test.client.failover;
import org.apache.log4j.Logger;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.test.utils.FailoverBaseCase;
@@ -35,7 +36,6 @@ import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
-import javax.naming.NamingException;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -75,7 +75,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
failoverComplete = new CountDownLatch(1);
}
- protected void init(boolean transacted, int mode) throws JMSException, NamingException
+ private void init(boolean transacted, int mode) throws Exception
{
consumerSession = connection.createSession(transacted, mode);
queue = consumerSession.createQueue(getName()+System.currentTimeMillis());
@@ -125,7 +125,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
}
}
- private void sendMessages(int startIndex,int endIndex, boolean transacted) throws JMSException
+ private void sendMessages(int startIndex,int endIndex, boolean transacted) throws Exception
{
_logger.debug("**************** Send (Start: " + startIndex + ", End:" + endIndex + ")***********************");
@@ -144,6 +144,10 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
{
producerSession.commit();
}
+ else
+ {
+ ((AMQSession<?, ?>)producerSession).sync();
+ }
}
public void testP2PFailover() throws Exception
@@ -163,13 +167,13 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
{
if (CLUSTERED)
{
- testP2PFailover(numMessages, false,true, false);
+ testP2PFailover(numMessages, false, true, false);
}
}
public void testP2PFailoverTransacted() throws Exception
{
- testP2PFailover(numMessages, true,true, false);
+ testP2PFailover(numMessages, true,true, true);
}
public void testP2PFailoverTransactedWithMessagesLeftToConsumeAndProduce() throws Exception
@@ -177,17 +181,16 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
// Currently the cluster does not support transactions that span a failover
if (CLUSTERED)
{
- testP2PFailover(numMessages, false,false, false);
+ testP2PFailover(numMessages, false, false, false);
}
}
-
- private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+ private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws Exception
{
init(transacted, Session.AUTO_ACKNOWLEDGE);
runP2PFailover(totalMessages,consumeAll, produceAll , transacted);
}
-
- protected void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+
+ private void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws Exception
{
int toProduce = totalMessages;
@@ -254,7 +257,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
//evil ignore IE.
}
}
-
+
public void testClientAckFailover() throws Exception
{
init(false, Session.CLIENT_ACKNOWLEDGE);
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
index 5b350d2d89..3cc15d5e9d 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
@@ -63,8 +63,7 @@ public class JMSDestinationTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
- //Ensure JMX management is enabled for MovedToQueue test
- setConfigurationProperty("management.enabled", "true");
+ getBrokerConfiguration().addJmxManagementConfiguration();
super.setUp();
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
index ee81e7c372..9bf7dbd62a 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
@@ -54,11 +54,9 @@ public class SyncWaitDelayTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", String.valueOf(POST_COMMIT_DELAY));
- setConfigurationProperty("management.enabled", "false");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", String.valueOf(POST_COMMIT_DELAY));
-
super.setUp();
//Set the syncWrite timeout to be just larger than the delay on the commitTran.
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
index 53f37cd915..8961574d1e 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
@@ -21,16 +21,23 @@
package org.apache.qpid.test.unit.basic;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
+import java.util.Collections;
+import java.util.Map;
+import javax.jms.Connection;
import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
+import javax.jms.Topic;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
public class InvalidDestinationTest extends QpidBrokerTestCase
{
@@ -48,21 +55,23 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
super.tearDown();
}
-
-
public void testInvalidDestination() throws Exception
{
- Queue invalidDestination = new AMQQueue("amq.direct","unknownQ");
- AMQQueue validDestination = new AMQQueue("amq.direct","knownQ");
QueueSession queueSession = _connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue invalidDestination = queueSession.createQueue("unknownQ");
+
+ Queue validDestination = queueSession.createQueue(getTestQueueName());
+
// This is the only easy way to create and bind a queue from the API :-(
queueSession.createConsumer(validDestination);
+ QueueSender sender;
+ TextMessage msg= queueSession.createTextMessage("Hello");
- QueueSender sender = queueSession.createSender(invalidDestination);
- TextMessage msg = queueSession.createTextMessage("Hello");
try
{
+ sender = queueSession.createSender(invalidDestination);
+
sender.send(msg);
fail("Expected InvalidDestinationException");
}
@@ -70,10 +79,8 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
{
// pass
}
- sender.close();
sender = queueSession.createSender(null);
- invalidDestination = new AMQQueue("amq.direct","unknownQ");
try
{
@@ -86,19 +93,79 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
}
sender.send(validDestination,msg);
sender.close();
- validDestination = new AMQQueue("amq.direct","knownQ");
sender = queueSession.createSender(validDestination);
sender.send(msg);
+ }
+ /**
+ * Tests that specifying the {@value ClientProperties#VERIFY_QUEUE_ON_SEND} system property
+ * results in an exception when sending to an invalid queue destination.
+ */
+ public void testInvalidDestinationOnMessageProducer() throws Exception
+ {
+ setTestSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "true");
+ final AMQConnection connection = (AMQConnection) getConnection();
+ doInvalidDestinationOnMessageProducer(connection);
+ }
+ /**
+ * Tests that specifying the {@value ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND}
+ * connection URL option property results in an exception when sending to an
+ * invalid queue destination.
+ */
+ public void testInvalidDestinationOnMessageProducerURL() throws Exception
+ {
+ Map<String, String> options = Collections.singletonMap(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND, "true");
+ doInvalidDestinationOnMessageProducer(getConnectionWithOptions(options));
+ }
+ private void doInvalidDestinationOnMessageProducer(Connection connection) throws JMSException
+ {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- }
+ String invalidQueueName = getTestQueueName() + "UnknownQ";
+ Queue invalidDestination = session.createQueue(invalidQueueName);
+ String validQueueName = getTestQueueName() + "KnownQ";
+ Queue validDestination = session.createQueue(validQueueName);
- public static junit.framework.Test suite()
- {
+ // This is the only easy way to create and bind a queue from the API :-(
+ session.createConsumer(validDestination);
+
+ MessageProducer sender;
+ TextMessage msg = session.createTextMessage("Hello");
+ try
+ {
+ sender = session.createProducer(invalidDestination);
+ sender.send(msg);
+ fail("Expected InvalidDestinationException");
+ }
+ catch (InvalidDestinationException ex)
+ {
+ // pass
+ }
- return new junit.framework.TestSuite(InvalidDestinationTest.class);
+ sender = session.createProducer(null);
+ invalidDestination = new AMQQueue("amq.direct",invalidQueueName);
+
+ try
+ {
+ sender.send(invalidDestination,msg);
+ fail("Expected InvalidDestinationException");
+ }
+ catch (InvalidDestinationException ex)
+ {
+ // pass
+ }
+ sender.send(validDestination, msg);
+ sender.close();
+ sender = session.createProducer(validDestination);
+ sender.send(msg);
+
+ //Verify sending to an 'invalid' Topic doesn't throw an exception
+ String invalidTopic = getTestQueueName() + "UnknownT";
+ Topic topic = session.createTopic(invalidTopic);
+ sender = session.createProducer(topic);
+ sender.send(msg);
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
index 8577fb5b6a..4e9477f4b6 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
@@ -20,26 +20,59 @@
*/
package org.apache.qpid.test.unit.client;
+import java.io.IOException;
+
import org.apache.qpid.AMQException;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.test.utils.JMXTestUtils;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.url.BindingURL;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.Session;
-/**
- * QPID-155
- *
- * Test to validate that setting the respective qpid.declare_queues,
- * qpid.declare_exchanges system properties functions as expected.
- */
public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
{
- public void testQueueDeclare() throws Exception
+ private JMXTestUtils _jmxUtils;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ _jmxUtils = new JMXTestUtils(this);
+ _jmxUtils.setUp();
+
+ super.setUp();
+ _jmxUtils.open();
+ }
+
+ @Override
+ public void tearDown() throws Exception
{
- setSystemProperty("qpid.declare_queues", "false");
+ try
+ {
+ if (_jmxUtils != null)
+ {
+ _jmxUtils.close();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ /*
+ * Tests to validate that setting the respective qpid.declare_queues,
+ * qpid.declare_exchanges system properties functions as expected.
+ */
+
+ public void testQueueNotDeclaredDuringConsumerCreation() throws Exception
+ {
+ setSystemProperty(ClientProperties.QPID_DECLARE_QUEUES_PROP_NAME, "false");
Connection connection = getConnection();
@@ -58,16 +91,16 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
}
}
- public void testExchangeDeclare() throws Exception
+ public void testExchangeNotDeclaredDuringConsumerCreation() throws Exception
{
- setSystemProperty("qpid.declare_exchanges", "false");
+ setSystemProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "false");
Connection connection = getConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- String EXCHANGE_TYPE = "test.direct";
- Queue queue = session.createQueue("direct://" + EXCHANGE_TYPE + "/queue/queue");
+ String exchangeName = getTestQueueName();
+ Queue queue = session.createQueue("direct://" + exchangeName + "/queue/queue");
try
{
@@ -78,6 +111,50 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
{
checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
}
+
+ //verify the exchange was not declared
+ String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName);
+ assertFalse("exchange should not exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+ }
+
+ /**
+ * Checks that setting {@value ClientProperties#QPID_DECLARE_EXCHANGES_PROP_NAME} false results in
+ * disabling implicit ExchangeDeclares during producer creation when using a {@link BindingURL}
+ */
+ public void testExchangeNotDeclaredDuringProducerCreation() throws Exception
+ {
+ Connection connection = getConnection();
+ Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ String exchangeName1 = getTestQueueName() + "1";
+
+
+ Queue queue = session1.createQueue("direct://" + exchangeName1 + "/queue/queue");
+ session1.createProducer(queue);
+
+ //close the session to ensure any previous commands were fully processed by
+ //the broker before observing their effect
+ session1.close();
+
+ //verify the exchange was declared
+ String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName1);
+ assertTrue("exchange should exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+
+ //Now disable the implicit exchange declares and try again
+ setSystemProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "false");
+
+ Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ String exchangeName2 = getTestQueueName() + "2";
+
+ Queue queue2 = session2.createQueue("direct://" + exchangeName2 + "/queue/queue");
+ session2.createProducer(queue2);
+
+ //close the session to ensure any previous commands were fully processed by
+ //the broker before observing their effect
+ session2.close();
+
+ //verify the exchange was not declared
+ String exchangeObjectName2 = _jmxUtils.getExchangeObjectName("test", exchangeName2);
+ assertFalse("exchange should not exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName2));
}
private void checkExceptionErrorCode(JMSException original, AMQConstant code)
@@ -87,4 +164,71 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
assertTrue("Linked exception should be an AMQException", linked instanceof AMQException);
assertEquals("Error code should be " + code.getCode(), code, ((AMQException) linked).getErrorCode());
}
+
+ /*
+ * Tests to validate that the custom exchanges declared by the client during
+ * consumer and producer creation have the expected properties.
+ */
+
+ public void testPropertiesOfCustomExchangeDeclaredDuringProducerCreation() throws Exception
+ {
+ implTestPropertiesOfCustomExchange(true, false);
+ }
+
+ public void testPropertiesOfCustomExchangeDeclaredDuringConsumerCreation() throws Exception
+ {
+ implTestPropertiesOfCustomExchange(false, true);
+ }
+
+ private void implTestPropertiesOfCustomExchange(boolean createProducer, boolean createConsumer) throws Exception
+ {
+ Connection connection = getConnection();
+
+ Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ String exchangeName1 = getTestQueueName() + "1";
+ String queueName1 = getTestQueueName() + "1";
+
+ Queue queue = session1.createQueue("direct://" + exchangeName1 + "/" + queueName1 + "/" + queueName1 + "?" + BindingURL.OPTION_EXCHANGE_AUTODELETE + "='true'");
+ if(createProducer)
+ {
+ session1.createProducer(queue);
+ }
+
+ if(createConsumer)
+ {
+ session1.createConsumer(queue);
+ }
+ session1.close();
+
+ //verify the exchange was declared to expectation
+ verifyDeclaredExchange(exchangeName1, true, false);
+
+ Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ String exchangeName2 = getTestQueueName() + "2";
+ String queueName2 = getTestQueueName() + "2";
+
+ Queue queue2 = session2.createQueue("direct://" + exchangeName2 + "/" + queueName2 + "/" + queueName2 + "?" + BindingURL.OPTION_EXCHANGE_DURABLE + "='true'");
+ if(createProducer)
+ {
+ session2.createProducer(queue2);
+ }
+
+ if(createConsumer)
+ {
+ session2.createConsumer(queue2);
+ }
+ session2.close();
+
+ //verify the exchange was declared to expectation
+ verifyDeclaredExchange(exchangeName2, false, true);
+ }
+
+ private void verifyDeclaredExchange(String exchangeName, boolean isAutoDelete, boolean isDurable) throws IOException
+ {
+ String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName);
+ assertTrue("exchange should exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+ ManagedExchange exchange = _jmxUtils.getManagedExchange(exchangeName);
+ assertEquals(isAutoDelete, exchange.isAutoDelete());
+ assertEquals(isDurable,exchange.isDurable());
+ }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
index bc1eead8b4..40db17f799 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
@@ -74,19 +74,20 @@ public class MaxDeliveryCountTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
//enable DLQ/maximumDeliveryCount support for all queues at the vhost level
- setConfigurationProperty("virtualhosts.virtualhost.test.queues.maximumDeliveryCount",
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.queues.maximumDeliveryCount",
String.valueOf(MAX_DELIVERY_COUNT));
- setConfigurationProperty("virtualhosts.virtualhost.test.queues.deadLetterQueues",
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.queues.deadLetterQueues",
String.valueOf(true));
//Ensure management is on
- setConfigurationProperty("management.enabled", "true");
- setConfigurationProperty("management.ssl.enabled", "false");
+ getBrokerConfiguration().addJmxManagementConfiguration();
// Set client-side flag to allow the server to determine if messages
// dead-lettered or requeued.
- setTestClientSystemProperty(ClientProperties.REJECT_BEHAVIOUR_PROP_NAME, "server");
-
+ if (!isBroker010())
+ {
+ setTestClientSystemProperty(ClientProperties.REJECT_BEHAVIOUR_PROP_NAME, "server");
+ }
super.setUp();
boolean durableSub = isDurSubTest();
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
deleted file mode 100644
index 1c9ee27b94..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
+++ /dev/null
@@ -1,236 +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.test.unit.client.channelclose;
-
-import junit.textui.TestRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Due to bizarre exception handling all sessions are closed if you get
- * a channel close request and no exception listener is registered.
- * <p/>
- * JIRA issue IBTBLZ-10.
- * <p/>
- * Simulate by:
- * <p/>
- * 0. Create two sessions with no exception listener.
- * 1. Publish message to queue/topic that does not exist (wrong routing key).
- * 2. This will cause a channel close.
- * 3. Since client does not have an exception listener, currently all sessions are
- * closed.
- */
-public class ChannelCloseOkTest extends QpidBrokerTestCase
-{
- private AMQConnection _connection;
- private Destination _destination1;
- private Destination _destination2;
- private Session _session1;
- private Session _session2;
- private final List<Message> _received1 = new ArrayList<Message>();
- private final List<Message> _received2 = new ArrayList<Message>();
-
- private static final Logger _log = LoggerFactory.getLogger(ChannelCloseOkTest.class);
-
- protected void setUp() throws Exception
- {
- super.setUp();
-
- _connection = (AMQConnection) getConnection("guest", "guest");
-
- _destination1 = new AMQQueue(_connection, "q1", true);
- _destination2 = new AMQQueue(_connection, "q2", true);
- _session1 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- _session1.createConsumer(_destination1).setMessageListener(new MessageListener()
- {
- public void onMessage(Message message)
- {
- _log.debug("consumer 1 got message [" + getTextMessage(message) + "]");
- synchronized (_received1)
- {
- _received1.add(message);
- _received1.notify();
- }
- }
- });
- _session2 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- _session2.createConsumer(_destination2).setMessageListener(new MessageListener()
- {
- public void onMessage(Message message)
- {
- _log.debug("consumer 2 got message [" + getTextMessage(message) + "]");
- synchronized (_received2)
- {
- _received2.add(message);
- _received2.notify();
- }
- }
- });
-
- _connection.start();
- }
-
- private String getTextMessage(Message message)
- {
- TextMessage tm = (TextMessage) message;
- try
- {
- return tm.getText();
- }
- catch (JMSException e)
- {
- return "oops " + e;
- }
- }
-
- protected void tearDown() throws Exception
- {
- closeConnection();
- super.tearDown();
- }
-
- public void closeConnection() throws JMSException
- {
- if (_connection != null)
- {
- _log.info(">>>>>>>>>>>>>>.. closing");
- _connection.close();
- }
- }
-
- public void testWithoutExceptionListener() throws Exception
- {
- doTest();
- }
-
- public void testWithExceptionListener() throws Exception
- {
- _connection.setExceptionListener(new ExceptionListener()
- {
- public void onException(JMSException jmsException)
- {
- _log.warn("onException - " + jmsException.getMessage());
- }
- });
-
- doTest();
- }
-
- public void doTest() throws Exception
- {
- // Check both sessions are ok.
- sendAndWait(_session1, _destination1, "first", _received1, 1);
- sendAndWait(_session2, _destination2, "second", _received2, 1);
- assertEquals(1, _received1.size());
- assertEquals(1, _received2.size());
-
- // Now send message to incorrect destination on session 1.
- Destination destination = new AMQQueue(_connection, "incorrect");
- send(_session1, destination, "third"); // no point waiting as message will never be received.
-
- // Ensure both sessions are still ok.
- // Send a bunch of messages as this give time for the sessions to be erroneously closed.
- final int num = 300;
- for (int i = 0; i < num; ++i)
- {
- send(_session1, _destination1, "" + i);
- send(_session2, _destination2, "" + i);
- }
-
- waitFor(_received1, num + 1);
- waitFor(_received2, num + 1);
-
- // Note that the third message is never received as it is sent to an incorrect destination.
- assertEquals(num + 1, _received1.size());
- assertEquals(num + 1, _received2.size());
- }
-
- private void sendAndWait(Session session, Destination destination, String message, List<Message> received, int count)
- throws JMSException, InterruptedException
- {
- send(session, destination, message);
- waitFor(received, count);
- }
-
- private void send(Session session, Destination destination, String message) throws JMSException
- {
- _log.debug("sending message " + message);
- MessageProducer producer1 = session.createProducer(destination);
- producer1.send(session.createTextMessage(message));
- }
-
- private void waitFor(List<Message> received, int count) throws InterruptedException
- {
- long timeout = 20000;
-
- synchronized (received)
- {
- long start = System.currentTimeMillis();
- while (received.size() < count)
- {
- if (System.currentTimeMillis() - start > timeout)
- {
- fail("timeout expired waiting for messages");
- }
- try
- {
- received.wait(timeout);
- }
- catch (InterruptedException e)
- {
- _log.info("Interrupted: " + e);
- throw e;
- }
-
- }
- }
- }
-
- private static String randomize(String in)
- {
- return in + System.currentTimeMillis();
- }
-
- public static void main(String[] args)
- {
- TestRunner.run(ChannelCloseOkTest.class);
- }
-
- public static junit.framework.Test suite()
- {
- return new junit.framework.TestSuite(ChannelCloseOkTest.class);
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
deleted file mode 100644
index c20eefd987..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.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.test.unit.client.channelclose;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.failover.FailoverException;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.framing.AMQFrame;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ChannelCloseOkBody;
-import org.apache.qpid.framing.ChannelOpenBody;
-import org.apache.qpid.framing.ChannelOpenOkBody;
-import org.apache.qpid.framing.ExchangeDeclareBody;
-import org.apache.qpid.framing.ExchangeDeclareOkBody;
-import org.apache.qpid.jms.ConnectionListener;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionListener, ConnectionListener
-{
- private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseTest.class);
-
- private Connection _connection;
- private Session _session;
- private static final long SYNC_TIMEOUT = 500;
- private int TEST = 0;
-
- /**
- * Close channel, use chanel with same id ensure error.
- *
- * This test is only valid for non 0-10 connection .
- */
- public void testReusingChannelAfterFullClosure() throws Exception
- {
- _connection=newConnection();
-
- // Create Producer
- try
- {
- _connection.start();
-
- createChannelAndTest(1);
-
- // Cause it to close
- try
- {
- _logger.info("Testing invalid exchange");
- declareExchange(1, "", "name_that_will_lookup_to_null", false);
- fail("Exchange name is empty so this should fail ");
- }
- catch (AMQException e)
- {
- assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode());
- }
-
- // Check that
- try
- {
- _logger.info("Testing valid exchange should fail");
- declareExchange(1, "topic", "amq.topic", false);
- fail("This should not succeed as the channel should be closed ");
- }
- catch (AMQException e)
- {
- if (_logger.isInfoEnabled())
- {
- _logger.info("Exception occured was:" + e.getErrorCode());
- }
-
- assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode());
-
- _connection=newConnection();
- }
-
- checkSendingMessage();
-
- _session.close();
- _connection.close();
-
- }
- catch (JMSException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
- }
-
- /*
- close channel and send guff then send ok no errors
- REMOVE TEST - The behaviour after server has sent close is undefined.
- the server should be free to fail as it may wish to reclaim its resources
- immediately after close.
- */
- /*public void testSendingMethodsAfterClose() throws Exception
- {
- // this is testing an 0.8 connection
- if(isBroker08())
- {
- try
- {
- _connection=new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'");
-
- ((AMQConnection) _connection).setConnectionListener(this);
-
- _connection.setExceptionListener(this);
-
- // Change the StateManager for one that doesn't respond with Close-OKs
- AMQStateManager oldStateManager=((AMQConnection) _connection).getProtocolHandler().getStateManager();
-
- _session=_connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- _connection.start();
-
- // Test connection
- checkSendingMessage();
-
- // Set StateManager to manager that ignores Close-oks
- AMQProtocolSession protocolSession=
- ((AMQConnection) _connection).getProtocolHandler().getProtocolSession();
-
- MethodDispatcher d = protocolSession.getMethodDispatcher();
-
- MethodDispatcher wrappedDispatcher = (MethodDispatcher)
- Proxy.newProxyInstance(d.getClass().getClassLoader(),
- d.getClass().getInterfaces(),
- new MethodDispatcherProxyHandler(
- (ClientMethodDispatcherImpl) d));
-
- protocolSession.setMethodDispatcher(wrappedDispatcher);
-
-
- AMQStateManager newStateManager=new NoCloseOKStateManager(protocolSession);
- newStateManager.changeState(oldStateManager.getCurrentState());
-
- ((AMQConnection) _connection).getProtocolHandler().setStateManager(newStateManager);
-
- final int TEST_CHANNEL=1;
- _logger.info("Testing Channel(" + TEST_CHANNEL + ") Creation");
-
- createChannelAndTest(TEST_CHANNEL);
-
- // Cause it to close
- try
- {
- _logger.info("Closing Channel - invalid exchange");
- declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false);
- fail("Exchange name is empty so this should fail ");
- }
- catch (AMQException e)
- {
- assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode());
- }
-
- try
- {
- // Send other methods that should be ignored
- // send them no wait as server will ignore them
- _logger.info("Tested known exchange - should ignore");
- declareExchange(TEST_CHANNEL, "topic", "amq.topic", true);
-
- _logger.info("Tested known invalid exchange - should ignore");
- declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true);
-
- _logger.info("Tested known invalid exchange - should ignore");
- declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true);
-
- // Send sync .. server will igore and timy oue
- _logger.info("Tested known invalid exchange - should ignore");
- declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false);
- }
- catch (AMQTimeoutException te)
- {
- assertEquals("Request should timeout", AMQConstant.REQUEST_TIMEOUT, te.getErrorCode());
- }
- catch (AMQException e)
- {
- fail("This should not fail as all requests should be ignored");
- }
-
- _logger.info("Sending Close");
- // Send Close-ok
- sendClose(TEST_CHANNEL);
-
- _logger.info("Re-opening channel");
-
- createChannelAndTest(TEST_CHANNEL);
-
- // Test connection is still ok
-
- checkSendingMessage();
-
- }
- catch (JMSException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
-
- }
- catch (URLSyntaxException e)
- {
- fail(e.getMessage());
- }
- finally
- {
- try
- {
- _session.close();
- _connection.close();
- }
- catch (JMSException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
- }
- }
- }
- }
-*/
- private void createChannelAndTest(int channel) throws FailoverException
- {
- // Create A channel
- try
- {
- createChannel(channel);
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
-
- // Test it is ok
- try
- {
- declareExchange(channel, "topic", "amq.topic", false);
- _logger.info("Tested known exchange");
- }
- catch (AMQException e)
- {
- fail("This should not fail as this is the default exchange details");
- }
- }
-
- private void sendClose(int channel)
- {
- ChannelCloseOkBody body =
- ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelCloseOkBody();
- AMQFrame frame = body.generateFrame(channel);
-
- ((AMQConnection) _connection).getProtocolHandler().writeFrame(frame);
- }
-
- private void checkSendingMessage() throws JMSException
- {
- TEST++;
- _logger.info("Test creating producer which will use channel id 1");
-
- Queue queue = _session.createQueue("CCT_test_validation_queue" + TEST);
-
- MessageConsumer consumer = _session.createConsumer(queue);
-
- MessageProducer producer = _session.createProducer(queue);
-
- final String MESSAGE = "CCT_Test_Message";
- producer.send(_session.createTextMessage(MESSAGE));
-
- Message msg = consumer.receive(2000);
-
- assertNotNull("Received messages should not be null.", msg);
- assertEquals("Message received not what we sent", MESSAGE, ((TextMessage) msg).getText());
- }
-
- private Connection newConnection()
- {
- Connection connection = null;
- try
- {
- connection = getConnection();
-
- ((AMQConnection) connection).setConnectionListener(this);
-
- _session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- connection.start();
-
- }
- catch (Exception e)
- {
- fail("Creating new connection when:" + e.getMessage());
- }
-
- return connection;
- }
-
- private void declareExchange(int channelId, String _type, String _name, boolean nowait)
- throws AMQException, FailoverException
- {
- ExchangeDeclareBody body =
- ((AMQConnection) _connection).getProtocolHandler()
- .getMethodRegistry()
- .createExchangeDeclareBody(0,
- new AMQShortString(_name),
- new AMQShortString(_type),
- true,
- false,
- false,
- false,
- nowait,
- null);
- AMQFrame exchangeDeclare = body.generateFrame(channelId);
- AMQProtocolHandler protocolHandler = ((AMQConnection) _connection).getProtocolHandler();
-
-
- if (nowait)
- {
- protocolHandler.writeFrame(exchangeDeclare);
- }
- else
- {
- protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class, SYNC_TIMEOUT);
- }
-
-// return null;
-// }
-// }, (AMQConnection)_connection).execute();
-
- }
-
- private void createChannel(int channelId) throws AMQException, FailoverException
- {
- ChannelOpenBody body =
- ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelOpenBody(null);
-
- ((AMQConnection) _connection).getProtocolHandler().syncWrite(body.generateFrame(channelId), // outOfBand
- ChannelOpenOkBody.class);
-
- }
-
- public void onException(JMSException jmsException)
- {
- // _logger.info("CCT" + jmsException);
- fail(jmsException.getMessage());
- }
-
- public void bytesSent(long count)
- { }
-
- public void bytesReceived(long count)
- { }
-
- public boolean preFailover(boolean redirect)
- {
- return false;
- }
-
- public boolean preResubscribe()
- {
- return false;
- }
-
- public void failoverComplete()
- { }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java
index f2387fa99b..b43fe35a09 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java
@@ -21,7 +21,7 @@
package org.apache.qpid.test.unit.close;
import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.client.AMQSession_0_8;
import org.apache.qpid.framing.AMQFrame;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ExchangeDeclareBody;
@@ -81,7 +81,7 @@ public class JavaServerCloseRaceConditionTest extends QpidBrokerTestCase
AMQConnection connection = (AMQConnection) getConnection();
- AMQSession session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ AMQSession_0_8 session = (AMQSession_0_8) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Set no wait true so that we block the connection
// Also set a different exchange class string so the attempt to declare
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
index a07e531b98..a9ac028af6 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java
@@ -73,7 +73,7 @@ public class DurableSubscriptionTest extends QpidBrokerTestCase
public void setUp() throws Exception
{
- setConfigurationProperty("management.enabled", "true");
+ getBrokerConfiguration().addJmxManagementConfiguration();
_jmxConnected=false;
super.setUp();
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
index fd8beffbe6..d93c7a2e71 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
@@ -29,7 +29,7 @@ public class TransactionTimeoutDisabledTest extends TransactionTimeoutTestCase
protected void configure() throws Exception
{
// Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100");
// No transaction timeout configuration.
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
index b11df5a2a0..4dc26847da 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
@@ -39,29 +39,29 @@ public class TransactionTimeoutTest extends TransactionTimeoutTestCase
protected void configure() throws Exception
{
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100");
+ // Setup housekeeping every 100ms
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100");
if (getName().contains("ProducerIdle"))
{
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "0");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "0");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1500");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "0");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "0");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1500");
}
else if (getName().contains("ProducerOpen"))
{
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "0");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "0");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "0");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "0");
}
else
{
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1000");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500");
+ setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1000");
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
index e2b0f00ee4..721dc027c6 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
@@ -23,17 +23,13 @@ package org.apache.qpid.test.unit.transacted;
import junit.framework.TestCase;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.jms.Session;
+import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.util.LogMonitor;
+import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
@@ -41,6 +37,7 @@ import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
+import javax.jms.Session;
import javax.jms.TextMessage;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -61,7 +58,7 @@ public abstract class TransactionTimeoutTestCase extends QpidBrokerTestCase impl
public static final String OPEN = "Open";
protected LogMonitor _monitor;
- protected AMQConnection _con;
+ protected Connection _con;
protected Session _psession, _csession;
protected Queue _queue;
protected MessageConsumer _consumer;
@@ -89,16 +86,14 @@ public abstract class TransactionTimeoutTestCase extends QpidBrokerTestCase impl
super.setUp();
// Connect to broker
- String broker = ("tcp://localhost:" + DEFAULT_PORT);
- ConnectionURL url = new AMQConnectionURL("amqp://guest:guest@clientid/test?brokerlist='" + broker + "'&maxprefetch='1'");
- _con = (AMQConnection) getConnection(url);
+ setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, String.valueOf(1));
+ _con = getConnection();
_con.setExceptionListener(this);
_con.start();
// Create queue
Session qsession = _con.createSession(true, Session.SESSION_TRANSACTED);
- AMQShortString queueName = new AMQShortString("test");
- _queue = new AMQQueue(qsession.getDefaultQueueExchangeName(), queueName, queueName, false, true);
+ _queue = qsession.createQueue(getTestQueueName());
qsession.close();
// Create producer and consumer
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java
new file mode 100644
index 0000000000..12d286f822
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java
@@ -0,0 +1,79 @@
+/* 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.test.utils;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Generates the command to start a broker by substituting the tokens
+ * in the provided broker command.
+ *
+ * The command is returned as a list so that it can be easily used by a
+ * {@link java.lang.ProcessBuilder}.
+ */
+public class BrokerCommandHelper
+{
+ private final List<String> _brokerCommandTemplateAsList;
+
+ public BrokerCommandHelper(String brokerCommandTemplate)
+ {
+ _brokerCommandTemplateAsList = new LinkedList<String>(Arrays.asList(brokerCommandTemplate.split("\\s+")));
+ }
+
+ public String[] getBrokerCommand( int port, String storePath, String storeType, File logConfigFile)
+ {
+ String[] command = new String[_brokerCommandTemplateAsList.size()];
+ int i=0;
+ for (String commandPart : _brokerCommandTemplateAsList)
+ {
+ command[i] = commandPart
+ .replace("@PORT", "" + port)
+ .replace("@STORE_PATH", storePath)
+ .replace("@STORE_TYPE", storeType)
+ .replace("@LOG_CONFIG_FILE", '"' + logConfigFile.getAbsolutePath() + '"');
+ i++;
+ }
+ return command;
+ }
+
+ private int getBrokerCommandLogOptionIndex(String logOption)
+ {
+ int logOptionIndex = _brokerCommandTemplateAsList.indexOf(logOption);
+ if(logOptionIndex == -1)
+ {
+ throw new RuntimeException("Could not find option " + logOption + " in " + _brokerCommandTemplateAsList);
+ }
+ return logOptionIndex;
+ }
+
+
+ public void removeBrokerCommandLog4JFile()
+ {
+ String logOption = "-l";
+ int logOptionIndex = getBrokerCommandLogOptionIndex(logOption);
+ if (logOptionIndex + 1 >= _brokerCommandTemplateAsList.size())
+ {
+ throw new RuntimeException("Could not find log config location");
+ }
+ _brokerCommandTemplateAsList.remove(logOptionIndex);
+ _brokerCommandTemplateAsList.remove(logOptionIndex);
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java
new file mode 100644
index 0000000000..f0bcea8e6e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java
@@ -0,0 +1,61 @@
+/* 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.test.utils;
+
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+
+public class BrokerCommandHelperTest extends QpidTestCase
+{
+ private BrokerCommandHelper _brokerCommandHelper = new BrokerCommandHelper("qpid -p @PORT -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE");
+
+ private File logConfigFile = mock(File.class);
+
+ @Override
+ public void setUp()
+ {
+ when(logConfigFile.getAbsolutePath()).thenReturn("log Config File");
+ }
+
+ public void testGetBrokerCommand()
+ {
+ String[] brokerCommand = _brokerCommandHelper.getBrokerCommand(1, "configFile", "json", logConfigFile);
+
+ String[] expected = { "qpid", "-p", "1", "-sp", "configFile", "-st", "json", "-l", "\"log Config File\"" };
+ assertEquals("Unexpected broker command", 9, brokerCommand.length);
+ for (int i = 0; i < expected.length; i++)
+ {
+ assertEquals("Unexpected command part value at " + i,expected[i], brokerCommand[i] );
+ }
+ }
+
+ public void testRemoveBrokerCommandLog4JFile()
+ {
+ _brokerCommandHelper.removeBrokerCommandLog4JFile();
+ String[] brokerCommand = _brokerCommandHelper.getBrokerCommand(1, "configFile", "json", logConfigFile);
+
+ String[] expected = { "qpid", "-p", "1", "-sp", "configFile", "-st", "json" };
+ assertEquals("Unexpected broker command", 7, brokerCommand.length);
+ for (int i = 0; i < expected.length; i++)
+ {
+ assertEquals("Unexpected command part value at " + i,expected[i], brokerCommand[i] );
+ }
+ }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java b/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
index a71a4ef517..8bad73d0ea 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
@@ -20,9 +20,6 @@
*/
package org.apache.qpid.test.utils;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
import java.util.Set;
import org.apache.log4j.Logger;
@@ -82,28 +79,7 @@ public class InternalBrokerHolder implements BrokerHolder
@Override
public String dumpThreads()
{
- ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
- ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
- StringBuilder dump = new StringBuilder();
- dump.append(String.format("%n"));
- for (ThreadInfo threadInfo : threadInfos)
- {
- dump.append(threadInfo);
- }
-
- long[] deadLocks = threadMXBean.findDeadlockedThreads();
- if (deadLocks != null && deadLocks.length > 0)
- {
- ThreadInfo[] deadlockedThreads = threadMXBean.getThreadInfo(deadLocks);
- dump.append(String.format("%n"));
- dump.append("Deadlock is detected!");
- dump.append(String.format("%n"));
- for (ThreadInfo threadInfo : deadlockedThreads)
- {
- dump.append(threadInfo);
- }
- }
- return dump.toString();
+ return TestUtils.dumpThreads();
}
@Override
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java b/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
index 43b80b45fb..6e6e3271f0 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
@@ -24,7 +24,6 @@ import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.management.common.JMXConnnectionFactory;
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
import org.apache.qpid.management.common.mbeans.ManagedBroker;
import org.apache.qpid.management.common.mbeans.ManagedConnection;
@@ -32,6 +31,8 @@ import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
import org.apache.qpid.management.common.mbeans.ServerInformation;
import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.plugin.PluginFactory;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
@@ -46,7 +47,9 @@ import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -78,7 +81,7 @@ public class JMXTestUtils
public void setUp() throws IOException, ConfigurationException, Exception
{
- _test.setConfigurationProperty("management.enabled", "true");
+ _test.getBrokerConfiguration().addJmxManagementConfiguration();
}
public void open() throws Exception
@@ -287,9 +290,7 @@ public class JMXTestUtils
public ObjectName getQueueObjectName(String virtualHostName, String queue)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost="
- + ObjectName.quote(virtualHostName) + ",name="
- + ObjectName.quote(queue) + ",*";
+ String query = getQueueObjectNameString(virtualHostName, queue);
Set<ObjectName> objectNames = queryObjects(query);
@@ -302,32 +303,20 @@ public class JMXTestUtils
return objectName;
}
+ public String getQueueObjectNameString(String virtualHostName, String queue) {
+ return "org.apache.qpid:type=VirtualHost.Queue,VirtualHost="
+ + ObjectName.quote(virtualHostName) + ",name="
+ + ObjectName.quote(queue) + ",*";
+ }
+
/**
- * Retrive the ObjectName for the given Exchange on a VirtualHost.
- *
- * This is then used to create a proxy to the ManagedExchange MBean.
- *
- * @param virtualHostName the VirtualHost the Exchange is on
- * @param exchange the Exchange to retireve e.g. 'direct'
- * @return the ObjectName for the given Exchange on the VirtualHost
+ * Generate the ObjectName for the given Exchange on a VirtualHost.
*/
- @SuppressWarnings("static-access")
- public ObjectName getExchangeObjectName(String virtualHostName, String exchange)
+ public String getExchangeObjectName(String virtualHostName, String exchange)
{
- // Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost="
+ return "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost="
+ ObjectName.quote(virtualHostName) + ",name="
+ ObjectName.quote(exchange) + ",*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- _test.assertNotNull("Null ObjectName Set returned", objectNames);
- _test.assertEquals("Incorrect number of exchange with name '" + exchange + "' returned", 1, objectNames.size());
-
- // We have verified we have only one value in objectNames so return it
- ObjectName objectName = objectNames.iterator().next();
- _test.getLogger().info("Loading: " + objectName);
- return objectName;
}
@SuppressWarnings("static-access")
@@ -343,7 +332,7 @@ public class JMXTestUtils
return getManagedObject(managedClass, objectName);
}
- public boolean isManagedObjectExist(String query)
+ public boolean doesManagedObjectExist(String query)
{
return !queryObjects(query).isEmpty();
}
@@ -373,9 +362,20 @@ public class JMXTestUtils
return getManagedObject(ManagedBroker.class, getVirtualHostManagerObjectName(virtualHost));
}
+ @SuppressWarnings("static-access")
public ManagedExchange getManagedExchange(String exchangeName)
{
- ObjectName objectName = getExchangeObjectName("test", exchangeName);
+ String query = getExchangeObjectName("test", exchangeName);
+
+ Set<ObjectName> objectNames = queryObjects(query);
+
+ _test.assertNotNull("Null ObjectName Set returned", objectNames);
+ _test.assertEquals("Incorrect number of exchange with name '" + exchangeName + "' returned", 1, objectNames.size());
+
+ // We have verified we have only one value in objectNames so return an mbean proxy for it
+ ObjectName objectName = objectNames.iterator().next();
+ _test.getLogger().info("Loading: " + objectName);
+
return MBeanServerInvocationHandler.newProxyInstance(_mbsc, objectName, ManagedExchange.class, false);
}
@@ -391,12 +391,6 @@ public class JMXTestUtils
return getManagedObject(LoggingManagement.class, objectName);
}
- public ConfigurationManagement getConfigurationManagement() throws MalformedObjectNameException
- {
- ObjectName objectName = new ObjectName("org.apache.qpid:type=ConfigurationManagement,name=ConfigurationManagement");
- return getManagedObject(ConfigurationManagement.class, objectName);
- }
-
public UserManagement getUserManagement() throws MalformedObjectNameException
{
ObjectName objectName = new ObjectName("org.apache.qpid:type=UserManagement,name=UserManagement");
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
index aa909a6674..d36f57171f 100644..100755
--- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
@@ -19,18 +19,17 @@ package org.apache.qpid.test.utils;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.PrintStream;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.Destination;
@@ -45,32 +44,34 @@ import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.jms.Topic;
+import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQTopic;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
import org.apache.qpid.server.Broker;
import org.apache.qpid.server.BrokerOptions;
-import org.apache.qpid.server.ProtocolExclusion;
-import org.apache.qpid.server.ProtocolInclusion;
-import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.VirtualHost;
import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.store.MessageStoreConstants;
+import org.apache.qpid.server.store.MessageStoreCreator;
+import org.apache.qpid.server.store.MessageStoreFactory;
import org.apache.qpid.server.store.derby.DerbyMessageStore;
import org.apache.qpid.url.URLSyntaxException;
import org.apache.qpid.util.FileUtils;
-import org.apache.qpid.util.LogMonitor;
/**
* Qpid base class for system testing test cases.
@@ -80,7 +81,7 @@ public class QpidBrokerTestCase extends QpidTestCase
public enum BrokerType
{
EXTERNAL /** Test case relies on a Broker started independently of the test-suite */,
- INTERNAL /** Test case starts an embedded broker within this JVM */,
+ INTERNAL /** Test case starts an embedded broker within this JVM */,
SPAWNED /** Test case spawns a new broker as a separate process */
}
@@ -88,9 +89,9 @@ public class QpidBrokerTestCase extends QpidTestCase
public static final String GUEST_PASSWORD = "guest";
protected final static String QpidHome = System.getProperty("QPID_HOME");
- protected File _configFile = new File(System.getProperty("broker.config"));
- protected File _logConfigFile = new File(System.getProperty("log4j.configuration"));
-
+ private final File _configFile = new File(System.getProperty("broker.config"));
+ private File _logConfigFile;
+ protected final String _brokerStoreType = System.getProperty("broker.config-store-type", "json");
protected static final Logger _logger = Logger.getLogger(QpidBrokerTestCase.class);
protected static final int LOGMONITOR_TIMEOUT = 5000;
@@ -98,7 +99,7 @@ public class QpidBrokerTestCase extends QpidTestCase
private Map<String, String> _propertiesSetForBroker = new HashMap<String, String>();
- private XMLConfiguration _testConfiguration = new XMLConfiguration();
+ private Map<Integer, TestBrokerConfiguration> _brokerConfigurations;
private XMLConfiguration _testVirtualhosts = new XMLConfiguration();
protected static final String INDEX = "index";
@@ -106,24 +107,31 @@ public class QpidBrokerTestCase extends QpidTestCase
private static final String DEFAULT_INITIAL_CONTEXT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+ private static Map<String, String> supportedStoresClassToTypeMapping = new HashMap<String, String>();
+
static
{
- String initialContext = System.getProperty(InitialContext.INITIAL_CONTEXT_FACTORY);
+ String initialContext = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
if (initialContext == null || initialContext.length() == 0)
{
- System.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, DEFAULT_INITIAL_CONTEXT);
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_INITIAL_CONTEXT);
+ }
+
+ MessageStoreCreator messageStoreCreator = new MessageStoreCreator();
+ Collection<MessageStoreFactory> factories = messageStoreCreator.getFactories();
+ for (MessageStoreFactory messageStoreFactory : factories)
+ {
+ supportedStoresClassToTypeMapping.put(messageStoreFactory.createMessageStore().getClass().getName(), messageStoreFactory.getType());
}
}
// system properties
private static final String TEST_VIRTUALHOSTS = "test.virtualhosts";
- private static final String TEST_CONFIG = "test.config";
private static final String BROKER_LANGUAGE = "broker.language";
protected static final String BROKER_TYPE = "broker.type";
private static final String BROKER_COMMAND = "broker.command";
private static final String BROKER_CLEAN_BETWEEN_TESTS = "broker.clean.between.tests";
- private static final String BROKER_EXISTING_QPID_WORK = "broker.existing.qpid.work";
private static final String BROKER_VERSION = "broker.version";
protected static final String BROKER_READY = "broker.ready";
private static final String BROKER_STOPPED = "broker.stopped";
@@ -131,8 +139,14 @@ public class QpidBrokerTestCase extends QpidTestCase
private static final String BROKER_LOG_INTERLEAVE = "broker.log.interleave";
private static final String BROKER_LOG_PREFIX = "broker.log.prefix";
private static final String BROKER_PERSITENT = "broker.persistent";
- public static final String BROKER_PROTOCOL_EXCLUDES = "broker.protocol.excludes";
- public static final String BROKER_PROTOCOL_INCLUDES = "broker.protocol.includes";
+ public static final String PROFILE_USE_SSL = "profile.use_ssl";
+
+ public static final int DEFAULT_PORT_VALUE = 5672;
+ public static final int DEFAULT_SSL_PORT_VALUE = 5671;
+ 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;
// values
protected static final String JAVA = "java";
@@ -140,15 +154,15 @@ public class QpidBrokerTestCase extends QpidTestCase
protected static final String QPID_HOME = "QPID_HOME";
- public static final int DEFAULT_VM_PORT = 1;
- public static final int DEFAULT_PORT = Integer.getInteger("test.port", ServerConfiguration.DEFAULT_PORT);
+ public static final int DEFAULT_PORT = Integer.getInteger("test.port", DEFAULT_PORT_VALUE);
public static final int FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt"));
- public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", ServerConfiguration.DEFAULT_JMXPORT_REGISTRYSERVER);
- public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.port.ssl", ServerConfiguration.DEFAULT_SSL_PORT);
+ public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", DEFAULT_JMXPORT_REGISTRYSERVER);
+ public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.port.ssl", DEFAULT_SSL_PORT_VALUE);
protected String _brokerLanguage = System.getProperty(BROKER_LANGUAGE, JAVA);
protected BrokerType _brokerType = BrokerType.valueOf(System.getProperty(BROKER_TYPE, "").toUpperCase());
- protected String _brokerCommand = System.getProperty(BROKER_COMMAND);
+
+ protected BrokerCommandHelper _brokerCommandHelper = new BrokerCommandHelper(System.getProperty(BROKER_COMMAND));
private Boolean _brokerCleanBetweenTests = Boolean.getBoolean(BROKER_CLEAN_BETWEEN_TESTS);
private final AmqpProtocolVersion _brokerVersion = AmqpProtocolVersion.valueOf(System.getProperty(BROKER_VERSION, ""));
protected String _output = System.getProperty(TEST_OUTPUT, System.getProperty("java.io.tmpdir"));
@@ -190,14 +204,67 @@ public class QpidBrokerTestCase extends QpidTestCase
}
private MessageType _messageType = MessageType.TEXT;
- public QpidBrokerTestCase(String name)
- {
- super(name);
- }
-
public QpidBrokerTestCase()
{
super();
+ _brokerConfigurations = new HashMap<Integer, TestBrokerConfiguration>();
+ initialiseLogConfigFile();
+ }
+
+ public TestBrokerConfiguration getBrokerConfiguration(int port)
+ {
+ int actualPort = getPort(port);
+
+ synchronized (_brokerConfigurations)
+ {
+ TestBrokerConfiguration configuration = _brokerConfigurations.get(actualPort);
+ if (configuration == null)
+ {
+ configuration = createBrokerConfiguration(actualPort);
+ }
+ return configuration;
+ }
+ }
+
+ public TestBrokerConfiguration getBrokerConfiguration()
+ {
+ return getBrokerConfiguration(DEFAULT_PORT);
+ }
+
+ public TestBrokerConfiguration createBrokerConfiguration(int port)
+ {
+ int actualPort = getPort(port);
+ TestBrokerConfiguration configuration = new TestBrokerConfiguration(System.getProperty(_brokerStoreType), _configFile.getAbsolutePath());
+ synchronized (_brokerConfigurations)
+ {
+ _brokerConfigurations.put(actualPort, configuration);
+ }
+ if (actualPort != DEFAULT_PORT)
+ {
+ configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT, Port.PORT, actualPort);
+ configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_RMI_PORT, Port.PORT, getManagementPort(actualPort));
+ configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_JMX_PORT, Port.PORT, getManagementPort(actualPort) + JMXPORT_CONNECTORSERVER_OFFSET);
+ }
+ return configuration;
+ }
+
+ private void initialiseLogConfigFile()
+ {
+ try
+ {
+ _logger.info("About to initialise log config file from system property: " + LOG4J_CONFIG_FILE_PATH);
+
+ URI uri = new URI("file", LOG4J_CONFIG_FILE_PATH, null);
+ _logConfigFile = new File(uri);
+ if(!_logConfigFile.exists())
+ {
+ throw new RuntimeException("Log config file " + _logConfigFile.getAbsolutePath() + " does not exist");
+ }
+ }
+ catch (URISyntaxException e)
+ {
+ throw new RuntimeException("Couldn't create URI from log4.configuration: " + LOG4J_CONFIG_FILE_PATH, e);
+ }
}
public Logger getLogger()
@@ -289,16 +356,6 @@ public class QpidBrokerTestCase extends QpidTestCase
fail("Unable to test without config file:" + _configFile);
}
- String existingQpidWorkPath = System.getProperty(BROKER_EXISTING_QPID_WORK);
- if(existingQpidWorkPath != null && !existingQpidWorkPath.equals(""))
- {
-
- String qpidWork = getQpidWork(_brokerType, getPort());
- File existing = new File(existingQpidWorkPath);
- cleanBrokerWork(qpidWork);
- FileUtils.copyRecursive(existing, new File(qpidWork));
- }
-
startBroker();
}
@@ -322,7 +379,7 @@ public class QpidBrokerTestCase extends QpidTestCase
{
Set<Integer> ports = new HashSet<Integer>();
int managementPort = getManagementPort(mainPort);
- int connectorServerPort = managementPort + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET;
+ int connectorServerPort = managementPort + JMXPORT_CONNECTORSERVER_OFFSET;
ports.add(mainPort);
ports.add(managementPort);
@@ -354,37 +411,33 @@ public class QpidBrokerTestCase extends QpidTestCase
}
}
- protected String getBrokerCommand(int port) throws MalformedURLException
+ public void startBroker() throws Exception
{
- final int sslPort = port-1;
- final String protocolExcludesList = getProtocolExcludesList(port, sslPort);
- final String protocolIncludesList = getProtocolIncludesList(port, sslPort);
+ startBroker(0);
+ }
- return _brokerCommand
- .replace("@PORT", "" + port)
- .replace("@SSL_PORT", "" + sslPort)
- .replace("@MPORT", "" + getManagementPort(port))
- .replace("@CONFIG_FILE", _configFile.toString())
- .replace("@LOG_CONFIG_FILE", _logConfigFile.toString())
- .replace("@EXCLUDES", protocolExcludesList)
- .replace("@INCLUDES", protocolIncludesList);
+ public void startBroker(int port) throws Exception
+ {
+ int actualPort = getPort(port);
+ TestBrokerConfiguration configuration = getBrokerConfiguration(actualPort);
+ startBroker(actualPort, configuration, _testVirtualhosts);
}
- public void startBroker() throws Exception
+
+ protected File getBrokerCommandLog4JFile()
{
- startBroker(0);
+ return _logConfigFile;
}
- public void startBroker(int port) throws Exception
+ protected void setBrokerCommandLog4JFile(File file)
{
- startBroker(port, _testConfiguration, _testVirtualhosts);
+ _logConfigFile = file;
+ _logger.info("Modified log config file to: " + file);
}
- public void startBroker(int port, XMLConfiguration testConfiguration, XMLConfiguration virtualHosts) throws Exception
+ public void startBroker(int port, TestBrokerConfiguration testConfiguration, XMLConfiguration virtualHosts) throws Exception
{
port = getPort(port);
-
- // Save any configuration changes that have been made
String testConfig = saveTestConfiguration(port, testConfiguration);
String virtualHostsConfig = saveTestVirtualhosts(port, virtualHosts);
@@ -397,28 +450,20 @@ public class QpidBrokerTestCase extends QpidTestCase
if (_brokerType.equals(BrokerType.INTERNAL) && !existingInternalBroker())
{
- setConfigurationProperty(ServerConfiguration.MGMT_CUSTOM_REGISTRY_SOCKET, String.valueOf(false));
- testConfig = saveTestConfiguration(port, testConfiguration);
- _logger.info("Set test.config property to: " + testConfig);
_logger.info("Set test.virtualhosts property to: " + virtualHostsConfig);
- setSystemProperty(TEST_CONFIG, testConfig);
setSystemProperty(TEST_VIRTUALHOSTS, virtualHostsConfig);
-
+ setSystemProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, "false");
BrokerOptions options = new BrokerOptions();
- options.setConfigFile(_configFile.getAbsolutePath());
- options.addPort(port);
-
- addExcludedPorts(port, DEFAULT_SSL_PORT, options);
- addIncludedPorts(port, DEFAULT_SSL_PORT, options);
- options.setJmxPortRegistryServer(getManagementPort(port));
+ options.setConfigurationStoreType(_brokerStoreType);
+ options.setConfigurationStoreLocation(testConfig);
//Set the log config file, relying on the log4j.configuration system property
//set on the JVM by the JUnit runner task in module.xml.
options.setLogConfigFile(_logConfigFile.getAbsolutePath());
Broker broker = new Broker();
- _logger.info("starting internal broker (same JVM)");
+ _logger.info("Starting internal broker (same JVM)");
broker.startup(options);
_brokers.put(port, new InternalBrokerHolder(broker, System.getProperty("QPID_WORK"), portsUsedByBroker));
@@ -427,9 +472,10 @@ public class QpidBrokerTestCase extends QpidTestCase
{
// Add the port to QPID_WORK to ensure unique working dirs for multi broker tests
final String qpidWork = getQpidWork(_brokerType, port);
- String cmd = getBrokerCommand(port);
- _logger.info("starting external broker: " + cmd);
- ProcessBuilder pb = new ProcessBuilder(cmd.split("\\s+"));
+
+ String[] cmd = _brokerCommandHelper.getBrokerCommand(port, testConfig, _brokerStoreType, _logConfigFile);
+ _logger.info("Starting spawn broker using command: " + StringUtils.join(cmd, ' '));
+ ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Map<String, String> processEnv = pb.environment();
String qpidHome = System.getProperty(QPID_HOME);
@@ -459,28 +505,28 @@ public class QpidBrokerTestCase extends QpidTestCase
}
}
+ String qpidOpts = "";
- // Add default test logging levels that are used by the log4j-test
- // Use the convenience methods to push the current logging setting
- // in to the external broker's QPID_OPTS string.
- if (System.getProperty("amqj.protocol.logging.level") != null)
+ // a synchronized hack to avoid adding into QPID_OPTS the values
+ // of JVM properties "test.virtualhosts" and "test.config" set by a concurrent startup process
+ synchronized (_propertiesSetForBroker)
{
+ // Add default test logging levels that are used by the log4j-test
+ // Use the convenience methods to push the current logging setting
+ // in to the external broker's QPID_OPTS string.
setSystemProperty("amqj.protocol.logging.level");
- }
- if (System.getProperty("root.logging.level") != null)
- {
setSystemProperty("root.logging.level");
- }
-
- // set test.config and test.virtualhosts
- String qpidOpts = " -D" + TEST_CONFIG + "=" + testConfig + " -D" + TEST_VIRTUALHOSTS + "=" + virtualHostsConfig;
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES);
+ setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES);
+ setSystemProperty(TEST_VIRTUALHOSTS, virtualHostsConfig);
- // Add all the specified system properties to QPID_OPTS
- if (!_propertiesSetForBroker.isEmpty())
- {
- for (String key : _propertiesSetForBroker.keySet())
+ // Add all the specified system properties to QPID_OPTS
+ if (!_propertiesSetForBroker.isEmpty())
{
- qpidOpts += " -D" + key + "=" + _propertiesSetForBroker.get(key);
+ for (String key : _propertiesSetForBroker.keySet())
+ {
+ qpidOpts += " -D" + key + "=" + _propertiesSetForBroker.get(key);
+ }
}
}
if (processEnv.containsKey("QPID_OPTS"))
@@ -489,9 +535,6 @@ public class QpidBrokerTestCase extends QpidTestCase
}
processEnv.put("QPID_OPTS", qpidOpts);
- _logger.info("Set test.config property to: " + testConfig);
- _logger.info("Set test.virtualhosts property to: " + virtualHostsConfig);
-
// cpp broker requires that the work directory is created
createBrokerWork(qpidWork);
@@ -505,9 +548,15 @@ public class QpidBrokerTestCase extends QpidTestCase
p.start();
+ SpawnedBrokerHolder holder = new SpawnedBrokerHolder(process, qpidWork, portsUsedByBroker);
if (!p.await(30, TimeUnit.SECONDS))
{
_logger.info("broker failed to become ready (" + p.getReady() + "):" + p.getStopLine());
+ String threadDump = holder.dumpThreads();
+ if (!threadDump.isEmpty())
+ {
+ _logger.info("the result of a try to capture thread dump:" + threadDump);
+ }
//Ensure broker has stopped
process.destroy();
cleanBrokerWork(qpidWork);
@@ -528,65 +577,7 @@ public class QpidBrokerTestCase extends QpidTestCase
// this is expect if the broker started successfully
}
- _brokers.put(port, new SpawnedBrokerHolder(process, qpidWork, portsUsedByBroker));
- }
- }
-
- private void addExcludedPorts(int port, int sslPort, BrokerOptions options)
- {
- final String protocolExcludesList = getProtocolExcludesList(port, sslPort);
-
- if (protocolExcludesList.equals(""))
- {
- return;
- }
- final String[] toks = protocolExcludesList.split("\\s");
-
- if(toks.length % 2 != 0)
- {
- throw new IllegalArgumentException("Must be an even number of tokens in '" + protocolExcludesList + "'");
- }
- for (int i = 0; i < toks.length; i=i+2)
- {
- String excludeArg = toks[i];
- final int excludedPort = Integer.parseInt(toks[i+1]);
- options.addExcludedPort(ProtocolExclusion.lookup(excludeArg), excludedPort);
-
- _logger.info("Adding protocol exclusion " + excludeArg + " " + excludedPort);
- }
- }
-
- protected String getProtocolExcludesList(int port, int sslPort)
- {
- return System.getProperty(BROKER_PROTOCOL_EXCLUDES,"").replace("@PORT", "" + port).replace("@SSL_PORT", "" + sslPort);
- }
-
- private String getProtocolIncludesList(int port, int sslPort)
- {
- return System.getProperty(BROKER_PROTOCOL_INCLUDES, "").replace("@PORT", "" + port).replace("@SSL_PORT", "" + sslPort);
- }
-
- private void addIncludedPorts(int port, int sslPort, BrokerOptions options)
- {
- final String protocolIncludesList = getProtocolIncludesList(port, sslPort);
-
- if (protocolIncludesList.equals(""))
- {
- return;
- }
- final String[] toks = protocolIncludesList.split("\\s");
-
- if(toks.length % 2 != 0)
- {
- throw new IllegalArgumentException("Must be an even number of tokens in '" + protocolIncludesList + "'");
- }
- for (int i = 0; i < toks.length; i=i+2)
- {
- String includeArg = toks[i];
- final int includedPort = Integer.parseInt(toks[i+1]);
- options.addIncludedPort(ProtocolInclusion.lookup(includeArg), includedPort);
-
- _logger.info("Adding protocol inclusion " + includeArg + " " + includedPort);
+ _brokers.put(port, holder);
}
}
@@ -620,7 +611,7 @@ public class QpidBrokerTestCase extends QpidTestCase
public String getTestConfigFile(int port)
{
- return _output + "/" + getTestQueueName() + "-" + port + "-config.xml";
+ return _output + "/" + getTestQueueName() + "-" + port + "-config";
}
public String getTestVirtualhostsFile(int port)
@@ -633,44 +624,33 @@ public class QpidBrokerTestCase extends QpidTestCase
return file.replace(System.getProperty(QPID_HOME,"QPID_HOME") + "/","");
}
- protected void saveTestConfiguration() throws ConfigurationException
+ protected String getPathRelativeToWorkingDirectory(String file)
{
- String relative = saveTestConfiguration(getPort(), _testConfiguration);
- _logger.info("Set test.config property to: " + relative);
- setSystemProperty(TEST_CONFIG, relative);
+ File configLocation = new File(file);
+ File workingDirectory = new File(System.getProperty("user.dir"));
+ return configLocation.getAbsolutePath().replace(workingDirectory.getAbsolutePath(), "").substring(1);
}
- protected String saveTestConfiguration(int port, XMLConfiguration testConfiguration) throws ConfigurationException
+ protected String saveTestConfiguration(int port, TestBrokerConfiguration testConfiguration)
{
- // Specify the test config file
String testConfig = getTestConfigFile(port);
- String relative = relativeToQpidHome(testConfig);
-
- _logger.info("Saving test virtualhosts file at: " + testConfig);
-
- // Create the file if configuration does not exist
- if (testConfiguration.isEmpty())
+ String relative = getPathRelativeToWorkingDirectory(testConfig);
+ if (!testConfiguration.isSaved())
{
- testConfiguration.addProperty("__ignore", "true");
+ _logger.info("Saving test broker configuration at: " + testConfig);
+ testConfiguration.save(new File(testConfig));
+ testConfiguration.setSaved(true);
}
- testConfiguration.save(testConfig);
return relative;
}
- protected void saveTestVirtualhosts() throws ConfigurationException
- {
- String relative = saveTestVirtualhosts(getPort(), _testVirtualhosts);
- _logger.info("Set test.virtualhosts property to: " + relative);
- setSystemProperty(TEST_VIRTUALHOSTS, relative);
- }
-
protected String saveTestVirtualhosts(int port, XMLConfiguration virtualHostConfiguration) throws ConfigurationException
{
// Specify the test virtualhosts file
String testVirtualhosts = getTestVirtualhostsFile(port);
String relative = relativeToQpidHome(testVirtualhosts);
- _logger.info("Set test.virtualhosts property to: " + testVirtualhosts);
+ _logger.info("Path to virtualhosts configuration: " + testVirtualhosts);
// Create the file if configuration does not exist
if (virtualHostConfiguration.isEmpty())
@@ -818,57 +798,41 @@ public class QpidBrokerTestCase extends QpidTestCase
}
/**
- * Attempt to set the Java Broker to use the BDBMessageStore for persistence
- * Falling back to the DerbyMessageStore if
- *
- * @param virtualhost - The virtualhost to modify
+ * Creates a new virtual host within the test virtualhost file.
+ * @param brokerPort broker port
+ * @param virtualHostName virtual host name
*
- * @throws ConfigurationException - when reading/writing existing configuration
- * @throws IOException - When creating a temporary file.
+ * @throws ConfigurationException
*/
- protected void makeVirtualHostPersistent(String virtualhost)
- throws ConfigurationException, IOException
+ protected void createTestVirtualHost(int brokerPort, String virtualHostName) throws ConfigurationException
{
- Class<?> storeClass = null;
- try
+ String storeClassName = getTestProfileMessageStoreClassName();
+
+ _testVirtualhosts.setProperty("virtualhost.name(-1)", virtualHostName);
+ _testVirtualhosts.setProperty("virtualhost." + virtualHostName + ".store.class", storeClassName);
+
+ String storeDir = null;
+
+ if (System.getProperty("profile", "").startsWith("java-dby-mem"))
{
- // Try and lookup the BDB class
- storeClass = Class.forName("org.apache.qpid.server.store.berkeleydb.BDBMessageStore");
+ storeDir = DerbyMessageStore.MEMORY_STORE_LOCATION;
}
- catch (ClassNotFoundException e)
+ else if (!MEMORY_STORE_CLASS_NAME.equals(storeClassName))
{
- // No BDB store, we'll use Derby instead.
- storeClass = DerbyMessageStore.class;
+ storeDir = "${QPID_WORK}" + File.separator + virtualHostName + "-store";
}
+ if (storeDir != null)
+ {
+ _testVirtualhosts.setProperty("virtualhost." + virtualHostName + ".store." + MessageStoreConstants.ENVIRONMENT_PATH_PROPERTY, storeDir);
+ }
- setConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".store.class",
- storeClass.getName());
- setConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".store." + MessageStoreConstants.ENVIRONMENT_PATH_PROPERTY,
- "${QPID_WORK}/" + virtualhost);
- }
-
- /**
- * Get a property value from the current configuration file.
- *
- * @param property the property to lookup
- *
- * @return the requested String Value
- *
- * @throws org.apache.commons.configuration.ConfigurationException
- *
- */
- protected String getConfigurationStringProperty(String property) throws ConfigurationException
- {
- // Call save Configuration to be sure we have saved the test specific
- // file. As the optional status
- saveTestConfiguration();
- saveTestVirtualhosts();
-
- ServerConfiguration configuration = new ServerConfiguration(_configFile);
- // Don't need to configuration.configure() here as we are just pulling
- // values directly by String.
- return configuration.getConfig().getString(property);
+ // add new virtual host configuration to the broker store
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(VirtualHost.NAME, virtualHostName);
+ attributes.put(VirtualHost.CONFIG_PATH, System.getProperty("broker.virtualhosts-config"));
+ int port = getPort(brokerPort);
+ getBrokerConfiguration(port).addHostConfiguration(attributes);
}
/**
@@ -884,10 +848,8 @@ public class QpidBrokerTestCase extends QpidTestCase
* @param value the new value
*
* @throws ConfigurationException when loading the current config file
- * @throws IOException when writing the new config file
*/
- public void setConfigurationProperty(String property, String value)
- throws ConfigurationException, IOException
+ public void setVirtualHostConfigurationProperty(String property, String value) throws ConfigurationException
{
// Choose which file to write the property to based on prefix.
if (property.startsWith("virtualhosts"))
@@ -896,7 +858,7 @@ public class QpidBrokerTestCase extends QpidTestCase
}
else
{
- _testConfiguration.setProperty(property, value);
+ throw new ConfigurationException("Cannot set broker configuration as property");
}
}
@@ -914,11 +876,13 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected void setBrokerOnlySystemProperty(String property, String value)
{
- if (!_propertiesSetForBroker.containsKey(property))
+ synchronized (_propertiesSetForBroker)
{
- _propertiesSetForBroker.put(property, value);
+ if (!_propertiesSetForBroker.containsKey(property))
+ {
+ _propertiesSetForBroker.put(property, value);
+ }
}
-
}
/**
@@ -931,7 +895,11 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected void setSystemProperty(String property)
{
- setSystemProperty(property, System.getProperty(property));
+ String value = System.getProperty(property);
+ if (value != null)
+ {
+ setSystemProperty(property, value);
+ }
}
/**
@@ -939,7 +907,7 @@ public class QpidBrokerTestCase extends QpidTestCase
*
* When the test run is complete the value will be reverted.
*
- * The values set using this method will also be propogated to the external
+ * The values set using this method will also be propagated to the external
* Java Broker via a -D value defined in QPID_OPTS.
*
* If the value should not be set on the broker then use
@@ -950,9 +918,18 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected void setSystemProperty(String property, String value)
{
- // Record the value for the external broker
- _propertiesSetForBroker.put(property, value);
-
+ synchronized(_propertiesSetForBroker)
+ {
+ // Record the value for the external broker
+ if (value == null)
+ {
+ _propertiesSetForBroker.remove(property);
+ }
+ else
+ {
+ _propertiesSetForBroker.put(property, value);
+ }
+ }
//Set the value for the test client vm aswell.
setTestClientSystemProperty(property, value);
}
@@ -1073,7 +1050,7 @@ public class QpidBrokerTestCase extends QpidTestCase
_logger.info("get ConnectionFactory");
if (_connectionFactory == null)
{
- if (Boolean.getBoolean("profile.use_ssl"))
+ if (Boolean.getBoolean(PROFILE_USE_SSL))
{
_connectionFactory = getConnectionFactory("default.ssl");
}
@@ -1092,7 +1069,7 @@ public class QpidBrokerTestCase extends QpidTestCase
*
* @return A connection factory
*
- * @throws Exception if there is an error getting the tactory
+ * @throws Exception if there is an error getting the factory
*/
public AMQConnectionFactory getConnectionFactory(String factoryName) throws NamingException
{
@@ -1104,6 +1081,22 @@ public class QpidBrokerTestCase extends QpidTestCase
return getConnection(GUEST_USERNAME, GUEST_PASSWORD);
}
+ public Connection getConnectionWithOptions(Map<String, String> options)
+ throws URLSyntaxException, NamingException, JMSException
+ {
+ ConnectionURL curl = new AMQConnectionURL(getConnectionFactory().getConnectionURLString());
+ for(Map.Entry<String,String> entry : options.entrySet())
+ {
+ curl.setOption(entry.getKey(), entry.getValue());
+ }
+ curl = new AMQConnectionURL(curl.toString());
+
+ curl.setUsername(GUEST_USERNAME);
+ curl.setPassword(GUEST_PASSWORD);
+ return getConnection(curl);
+ }
+
+
public Connection getConnection(ConnectionURL url) throws JMSException
{
_logger.info(url.getURL());
@@ -1363,11 +1356,6 @@ public class QpidBrokerTestCase extends QpidTestCase
_messageSize = byteSize;
}
- public ConnectionURL getConnectionURL() throws NamingException
- {
- return getConnectionFactory().getConnectionURL();
- }
-
public BrokerDetails getBroker()
{
try
@@ -1390,31 +1378,6 @@ public class QpidBrokerTestCase extends QpidTestCase
return null;
}
- /**
- * Reloads the broker security configuration using the ApplicationRegistry (InVM brokers) or the
- * ConfigurationManagementMBean via the JMX interface (Standalone brokers, management must be
- * enabled before calling the method).
- */
- public void reloadBrokerSecurityConfig() throws Exception
- {
- JMXTestUtils jmxu = new JMXTestUtils(this);
- jmxu.open();
-
- try
- {
- ConfigurationManagement configMBean = jmxu.getConfigurationManagement();
- configMBean.reloadSecurityConfiguration();
- }
- finally
- {
- jmxu.close();
- }
-
- LogMonitor _monitor = new LogMonitor(_outputFile);
- assertTrue("The expected server security configuration reload did not occur",
- _monitor.waitForMessage(ServerConfiguration.SECURITY_CONFIG_RELOADED, LOGMONITOR_TIMEOUT));
- }
-
protected int getFailingPort()
{
return FAILING_PORT;
@@ -1430,13 +1393,14 @@ public class QpidBrokerTestCase extends QpidTestCase
_testVirtualhosts = testVirtualhosts;
}
- public XMLConfiguration getTestConfiguration()
+ public String getTestProfileMessageStoreType()
{
- return _testConfiguration;
+ final String storeClass = getTestProfileMessageStoreClassName();
+ if (storeClass == null)
+ {
+ return MemoryMessageStore.TYPE;
+ }
+ return supportedStoresClassToTypeMapping.get(storeClass);
}
- public void setTestConfiguration(XMLConfiguration testConfiguration)
- {
- _testConfiguration = testConfiguration;
- }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java
deleted file mode 100644
index 72003ed7d7..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java
+++ /dev/null
@@ -1,295 +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.test.utils;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.JMSAMQException;
-import org.apache.qpid.url.URLSyntaxException;
-
-import javax.jms.Connection;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-/**
- * @todo This was originally cut and paste from the client module leading to a duplicate class, then altered very
- * slightly. To avoid the duplicate class the name was altered slightly to have 'Helper' on the end in order
- * to distinguish it from the original. Delete this class and use the original instead, just upgrade it to
- * provide the new features needed.
- */
-public class QpidClientConnectionHelper implements ExceptionListener
-{
-
- private static final Logger _logger = Logger.getLogger(QpidClientConnectionHelper.class);
-
- private boolean transacted = true;
- private int ackMode = Session.CLIENT_ACKNOWLEDGE;
- private Connection connection;
-
- private String virtualHost;
- private String brokerlist;
- private int prefetch;
- protected Session session;
- protected boolean connected;
-
- public QpidClientConnectionHelper(String broker)
- {
- super();
- setVirtualHost("/test");
- setBrokerList(broker);
- setPrefetch(5000);
- }
-
- public void connect() throws JMSException
- {
- if (!connected)
- {
- /*
- * amqp://[user:pass@][clientid]/virtualhost?
- * brokerlist='[transport://]host[:port][?option='value'[&option='value']];'
- * [&failover='method[?option='value'[&option='value']]']
- * [&option='value']"
- */
- String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'";
- try
- {
- AMQConnectionFactory factory = new AMQConnectionFactory(new AMQConnectionURL(brokerUrl));
- _logger.info("connecting to Qpid :" + brokerUrl);
- connection = factory.createConnection();
-
- // register exception listener
- connection.setExceptionListener(this);
-
- session = ((AMQConnection) connection).createSession(transacted, ackMode, prefetch);
-
- _logger.info("starting connection");
- connection.start();
-
- connected = true;
- }
- catch (URLSyntaxException e)
- {
- throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e);
- }
- }
- }
-
- public void disconnect() throws JMSException
- {
- if (connected)
- {
- session.commit();
- session.close();
- connection.close();
- connected = false;
- _logger.info("disconnected");
- }
- }
-
- public void disconnectWithoutCommit() throws JMSException
- {
- if (connected)
- {
- session.close();
- connection.close();
- connected = false;
- _logger.info("disconnected without commit");
- }
- }
-
- public String getBrokerList()
- {
- return brokerlist;
- }
-
- public void setBrokerList(String brokerlist)
- {
- this.brokerlist = brokerlist;
- }
-
- public String getVirtualHost()
- {
- return virtualHost;
- }
-
- public void setVirtualHost(String virtualHost)
- {
- this.virtualHost = virtualHost;
- }
-
- public void setPrefetch(int prefetch)
- {
- this.prefetch = prefetch;
- }
-
- /** override as necessary */
- public void onException(JMSException exception)
- {
- _logger.info("ExceptionListener event: error " + exception.getErrorCode() + ", message: " + exception.getMessage());
- }
-
- public boolean isConnected()
- {
- return connected;
- }
-
- public Session getSession()
- {
- return session;
- }
-
- /**
- * Put a String as a text messages, repeat n times. A null payload will result in a null message.
- *
- * @param queueName The queue name to put to
- * @param payload the content of the payload
- * @param copies the number of messages to put
- *
- * @throws javax.jms.JMSException any exception that occurs
- */
- public void put(String queueName, String payload, int copies, int deliveryMode) throws JMSException
- {
- if (!connected)
- {
- connect();
- }
-
- _logger.info("putting to queue " + queueName);
- Queue queue = session.createQueue(queueName);
-
- final MessageProducer sender = session.createProducer(queue);
-
- sender.setDeliveryMode(deliveryMode);
-
- for (int i = 0; i < copies; i++)
- {
- Message m = session.createTextMessage(payload + i);
- m.setIntProperty("index", i + 1);
- sender.send(m);
- }
-
- session.commit();
- sender.close();
- _logger.info("put " + copies + " copies");
- }
-
- /**
- * GET the top message on a queue. Consumes the message. Accepts timeout value.
- *
- * @param queueName The quename to get from
- * @param readTimeout The timeout to use
- *
- * @return the content of the text message if any
- *
- * @throws javax.jms.JMSException any exception that occured
- */
- public Message getNextMessage(String queueName, long readTimeout) throws JMSException
- {
- if (!connected)
- {
- connect();
- }
-
- Queue queue = session.createQueue(queueName);
-
- final MessageConsumer consumer = session.createConsumer(queue);
-
- Message message = consumer.receive(readTimeout);
- session.commit();
- consumer.close();
-
- Message result;
-
- // all messages we consume should be TextMessages
- if (message instanceof TextMessage)
- {
- result = ((TextMessage) message);
- }
- else if (null == message)
- {
- result = null;
- }
- else
- {
- _logger.info("warning: received non-text message");
- result = message;
- }
-
- return result;
- }
-
- /**
- * GET the top message on a queue. Consumes the message.
- *
- * @param queueName The Queuename to get from
- *
- * @return The string content of the text message, if any received
- *
- * @throws javax.jms.JMSException any exception that occurs
- */
- public Message getNextMessage(String queueName) throws JMSException
- {
- return getNextMessage(queueName, 0);
- }
-
- /**
- * Completely clears a queue. For readTimeout behaviour see Javadocs for javax.jms.MessageConsumer.
- *
- * @param queueName The Queue name to consume from
- * @param readTimeout The timeout for each consume
- *
- * @throws javax.jms.JMSException Any exception that occurs during the consume
- * @throws InterruptedException If the consume thread was interrupted during a consume.
- */
- public void consume(String queueName, int readTimeout) throws JMSException, InterruptedException
- {
- if (!connected)
- {
- connect();
- }
-
- _logger.info("consuming queue " + queueName);
- Queue queue = session.createQueue(queueName);
-
- final MessageConsumer consumer = session.createConsumer(queue);
- int messagesReceived = 0;
-
- _logger.info("consuming...");
- while ((consumer.receive(readTimeout)) != null)
- {
- messagesReceived++;
- }
-
- session.commit();
- consumer.close();
- _logger.info("consumed: " + messagesReceived);
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
new file mode 100644
index 0000000000..80f8010678
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
@@ -0,0 +1,219 @@
+/*
+ *
+ * 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.test.utils;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.ConfigurationEntry;
+import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Plugin;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.UUIDGenerator;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.plugin.PluginFactory;
+
+public class TestBrokerConfiguration
+{
+ public static final String ENTRY_NAME_HTTP_PORT = "http";
+ public static final String ENTRY_NAME_AMQP_PORT = "amqp";
+ public static final String ENTRY_NAME_RMI_PORT = "rmi";
+ public static final String ENTRY_NAME_JMX_PORT = "jmx";
+ public static final String ENTRY_NAME_VIRTUAL_HOST = "test";
+ public static final String ENTRY_NAME_AUTHENTICATION_PROVIDER = "plain";
+ public static final String ENTRY_NAME_EXTERNAL_PROVIDER = "external";
+ public static final String ENTRY_NAME_SSL_PORT = "sslPort";
+ public static final String ENTRY_NAME_HTTP_MANAGEMENT = "MANAGEMENT-HTTP";
+ public static final String MANAGEMENT_HTTP_PLUGIN_TYPE = "MANAGEMENT-HTTP";
+ public static final String ENTRY_NAME_JMX_MANAGEMENT = "MANAGEMENT-JMX";
+ public static final String MANAGEMENT_JMX_PLUGIN_TYPE = "MANAGEMENT-JMX";
+ public static final String ENTRY_NAME_ANONYMOUS_PROVIDER = "anonymous";
+
+ private JsonConfigurationEntryStore _store;
+ private boolean _saved;
+
+ public TestBrokerConfiguration(String storeType, String intialStoreLocation)
+ {
+ // TODO: add support for DERBY store
+ _store = new JsonConfigurationEntryStore();
+ _store.open(JsonConfigurationEntryStore.IN_MEMORY, intialStoreLocation);
+ }
+
+ public boolean setBrokerAttribute(String name, Object value)
+ {
+ return setObjectAttribute(_store.getRootEntry(), name, value);
+ }
+
+ public boolean setObjectAttribute(String objectName, String attributeName, Object value)
+ {
+ ConfigurationEntry entry = findObjectByName(objectName);
+ if (entry == null)
+ {
+ return false;
+ }
+ return setObjectAttribute(entry, attributeName, value);
+ }
+
+ public boolean setObjectAttributes(String objectName, Map<String, Object> attributes)
+ {
+ ConfigurationEntry entry = findObjectByName(objectName);
+ if (entry == null)
+ {
+ return false;
+ }
+ return setObjectAttributes(entry, attributes);
+ }
+
+ public boolean save(File configFile)
+ {
+ _store.copyTo(configFile.getAbsolutePath());
+ return true;
+ }
+
+ public UUID[] removeObjectConfiguration(String name)
+ {
+ ConfigurationEntry entry = findObjectByName(name);
+ if (entry != null)
+ {
+ return _store.remove(entry.getId());
+ }
+ return null;
+ }
+
+ public UUID addObjectConfiguration(String name, String type, Map<String, Object> attributes)
+ {
+ UUID id = UUIDGenerator.generateBrokerChildUUID(type, name);
+ addObjectConfiguration(id, type, attributes);
+ return id;
+ }
+
+ public UUID addJmxManagementConfiguration()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(PluginFactory.PLUGIN_TYPE, MANAGEMENT_JMX_PLUGIN_TYPE);
+ attributes.put(Plugin.NAME, ENTRY_NAME_JMX_MANAGEMENT);
+ return addObjectConfiguration(ENTRY_NAME_JMX_MANAGEMENT, Plugin.class.getSimpleName(), attributes);
+ }
+
+ public UUID addHttpManagementConfiguration()
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(PluginFactory.PLUGIN_TYPE, MANAGEMENT_HTTP_PLUGIN_TYPE);
+ attributes.put(Plugin.NAME, ENTRY_NAME_HTTP_MANAGEMENT);
+ return addObjectConfiguration(ENTRY_NAME_HTTP_MANAGEMENT, Plugin.class.getSimpleName(), attributes);
+ }
+
+ public UUID addPortConfiguration(Map<String, Object> attributes)
+ {
+ String name = (String) attributes.get(Port.NAME);
+ return addObjectConfiguration(name, Port.class.getSimpleName(), attributes);
+ }
+
+ public UUID addHostConfiguration(Map<String, Object> attributes)
+ {
+ String name = (String) attributes.get(VirtualHost.NAME);
+ return addObjectConfiguration(name, VirtualHost.class.getSimpleName(), attributes);
+ }
+
+ public UUID addAuthenticationProviderConfiguration(Map<String, Object> attributes)
+ {
+ String name = (String) attributes.get(AuthenticationProvider.NAME);
+ return addObjectConfiguration(name, AuthenticationProvider.class.getSimpleName(), attributes);
+ }
+
+ private boolean setObjectAttributes(ConfigurationEntry entry, Map<String, Object> attributes)
+ {
+ Map<String, Object> newAttributes = new HashMap<String, Object>(entry.getAttributes());
+ newAttributes.putAll(attributes);
+ ConfigurationEntry newEntry = new ConfigurationEntry(entry.getId(), entry.getType(), newAttributes,
+ entry.getChildrenIds(), _store);
+ _store.save(newEntry);
+ return true;
+ }
+
+ private ConfigurationEntry findObjectByName(String objectName)
+ {
+ ConfigurationEntry root = _store.getRootEntry();
+ return findObjectByName(root, objectName);
+ }
+
+ private ConfigurationEntry findObjectByName(ConfigurationEntry entry, String objectName)
+ {
+ Map<String, Object> attributes = entry.getAttributes();
+ if (attributes != null)
+ {
+ String name = (String) attributes.get("name");
+ if (objectName.equals(name))
+ {
+ return entry;
+ }
+ }
+ Set<UUID> childrenIds = entry.getChildrenIds();
+ for (UUID uuid : childrenIds)
+ {
+ ConfigurationEntry child = _store.getEntry(uuid);
+ ConfigurationEntry result = findObjectByName(child, objectName);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private void addObjectConfiguration(UUID id, String type, Map<String, Object> attributes)
+ {
+ ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, Collections.<UUID> emptySet(), _store);
+ ConfigurationEntry root = _store.getRootEntry();
+ Set<UUID> childrenIds = new HashSet<UUID>(root.getChildrenIds());
+ childrenIds.add(id);
+ ConfigurationEntry newRoot = new ConfigurationEntry(root.getId(), root.getType(), root.getAttributes(), childrenIds,
+ _store);
+ _store.save(newRoot, entry);
+ }
+
+ private boolean setObjectAttribute(ConfigurationEntry entry, String attributeName, Object value)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes());
+ attributes.put(attributeName, value);
+ ConfigurationEntry newEntry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, entry.getChildrenIds(),
+ _store);
+ _store.save(newEntry);
+ return true;
+ }
+
+ public boolean isSaved()
+ {
+ return _saved;
+ }
+
+ public void setSaved(boolean saved)
+ {
+ _saved = saved;
+ }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java
new file mode 100644
index 0000000000..9d5be775dc
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java
@@ -0,0 +1,30 @@
+/*
+ * 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.test.utils;
+
+public interface TestSSLConstants
+{
+ String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks";
+ String KEYSTORE_PASSWORD = "password";
+ String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
+ String TRUSTSTORE_PASSWORD = "password";
+
+ String BROKER_KEYSTORE = "test-profiles/test_resources/ssl/java_broker_keystore.jks";
+ String BROKER_KEYSTORE_PASSWORD = "password";
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java
new file mode 100644
index 0000000000..c651d3ec7f
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.test.utils;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+public class TestUtils
+{
+ public static String dumpThreads()
+ {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
+ StringBuilder dump = new StringBuilder();
+ dump.append(String.format("%n"));
+ for (ThreadInfo threadInfo : threadInfos)
+ {
+ dump.append(threadInfo);
+ }
+
+ long[] deadLocks = threadMXBean.findDeadlockedThreads();
+ if (deadLocks != null && deadLocks.length > 0)
+ {
+ ThreadInfo[] deadlockedThreads = threadMXBean.getThreadInfo(deadLocks);
+ dump.append(String.format("%n"));
+ dump.append("Deadlock is detected!");
+ dump.append(String.format("%n"));
+ for (ThreadInfo threadInfo : deadlockedThreads)
+ {
+ dump.append(threadInfo);
+ }
+ }
+ return dump.toString();
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java b/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java
index 2b99289cd1..d77731d09f 100644
--- a/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java
+++ b/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java
@@ -30,8 +30,10 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
/**
* Utility to simplify the monitoring of Log4j file output
@@ -42,6 +44,8 @@ import java.util.List;
*/
public class LogMonitor
{
+ private static final Logger _logger = Logger.getLogger(LogMonitor.class);
+
// The file that the log statements will be written to.
private final File _logfile;
@@ -90,6 +94,8 @@ public class LogMonitor
_appender.setImmediateFlush(true);
Logger.getRootLogger().addAppender(_appender);
}
+
+ _logger.info("Created LogMonitor. Monitoring file: " + _logfile.getAbsolutePath());
}
/**
@@ -156,6 +162,39 @@ public class LogMonitor
return results;
}
+ public Map<String, List<String>> findMatches(String... pattern) throws IOException
+ {
+
+ Map<String, List<String>> results= new HashMap<String, List<String>>();
+ for (String p : pattern)
+ {
+ results.put(p, new LinkedList<String>());
+ }
+ LineNumberReader reader = new LineNumberReader(new FileReader(_logfile));
+ try
+ {
+ while (reader.ready())
+ {
+ String line = reader.readLine();
+ if (reader.getLineNumber() > _linesToSkip)
+ {
+ for (String p : pattern)
+ {
+ if (line.contains(p))
+ {
+ results.get(p).add(line);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ reader.close();
+ }
+
+ return results;
+ }
/**
* Checks the log file for a given message to appear. If the caller
* has previously called {@link #markDiscardPoint()}, lines up until the discard
diff --git a/java/test-profiles/CPPExcludes b/java/test-profiles/CPPExcludes
index 018ced4a68..8b74a19b8e 100755
--- a/java/test-profiles/CPPExcludes
+++ b/java/test-profiles/CPPExcludes
@@ -23,8 +23,6 @@ org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateEx
// QPID-3576: Java client issue. MessageConsumer#close() time-out.
org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testDeleteOptions
-org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
-
// Those tests are testing 0.8 specific semantics
org.apache.qpid.test.client.ImmediateAndMandatoryPublishingTest#*
@@ -128,17 +126,8 @@ org.apache.qpid.client.failover.AddressBasedFailoverBehaviourTest#testFlowContro
org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage#*
-//Excluded due to QPID-1447 : CPP broker does not have SlowConsumer Disconnection
-org.apache.qpid.systest.GlobalQueuesTest#*
-org.apache.qpid.systest.GlobalTopicsTest#*
-org.apache.qpid.systest.MergeConfigurationTest#*
-org.apache.qpid.systest.SubscriptionTest#*
-org.apache.qpid.systest.TopicTest#*
-
// Excluded because Java plugins not used in CPP broker
org.apache.qpid.server.virtualhost.plugin.*
-org.apache.qpid.server.virtualhost.plugin.policies.*
-org.apache.qpid.info.systest.InfoPluginTest#*
org.apache.qpid.info.test.*
org.apache.qpid.server.security.access.*
org.apache.qpid.server.security.access.plugins.*
@@ -182,4 +171,15 @@ org.apache.qpid.systest.disttest.*
org.apache.qpid.disttest.*
// Exclude java broker REST API tests
-org.apache.qpid.server.management.plugin.servlet.rest.*
+org.apache.qpid.systest.rest.*
+org.apache.qpid.systest.rest.acl.*
+
+// Exclude failover tests requiring virtual host functionality
+org.apache.qpid.client.failover.MultipleBrokersFailoverTest#*
+
+// Uses Java broker specific configuration
+org.apache.qpid.client.ssl.SSLTest#testClientCertMissingWhilstWanting
+
+// QPID-2796 : Java 0-10 client only sends heartbeats in response to heartbeats from the server, not timeout based
+org.apache.qpid.client.HeartbeatTest#testReadOnlyConnectionHeartbeats
+
diff --git a/java/test-profiles/Excludes b/java/test-profiles/Excludes
index c0532e0b97..9c07fea574 100644
--- a/java/test-profiles/Excludes
+++ b/java/test-profiles/Excludes
@@ -30,4 +30,3 @@ org.apache.qpid.server.logging.MemoryMessageStoreLoggingTest#testMessageStoreClo
org.apache.qpid.server.logging.DerbyMessageStoreLoggingTest#*
org.apache.qpid.client.ssl.SSLTest#testVerifyLocalHostLocalDomain
-
diff --git a/java/test-profiles/Java010Excludes b/java/test-profiles/Java010Excludes
index ca2383a8f3..c4b3ac8d66 100755
--- a/java/test-profiles/Java010Excludes
+++ b/java/test-profiles/Java010Excludes
@@ -37,9 +37,6 @@ org.apache.qpid.test.unit.close.JavaServerCloseRaceConditionTest#*
//QPID-1864: rollback with subscriptions does not work in 0-10 yet
org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage
-// This test uses 0-8 channel frames
-org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
-
//QPID-3422: test fails because ring queue is not implemented on java broker
org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testBrowseMode
@@ -64,3 +61,6 @@ org.apache.qpid.client.failover.AddressBasedFailoverBehaviourTest#testFlowContro
// QPID-3604: Immediate Prefetch no longer supported by 0-10
org.apache.qpid.client.AsynchMessageListenerTest#testImmediatePrefetchWithMessageListener
+
+// QPID-2796 : Java 0-10 client only sends heartbeats in response to heartbeats from the server, not timeout based
+org.apache.qpid.client.HeartbeatTest#testReadOnlyConnectionHeartbeats
diff --git a/java/test-profiles/JavaTransientExcludes b/java/test-profiles/JavaTransientExcludes
index e7b423ef34..2f96584589 100644
--- a/java/test-profiles/JavaTransientExcludes
+++ b/java/test-profiles/JavaTransientExcludes
@@ -20,6 +20,8 @@
//These tests require a persistent store
org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
org.apache.qpid.server.store.PersistentStoreTest#*
+org.apache.qpid.server.logging.AlertingTest#testAlertingReallyWorksWithRestart
+org.apache.qpid.server.logging.AlertingTest#testAlertingReallyWorksWithChanges
org.apache.qpid.test.unit.ack.ClientAcknowledgeTest#testClientAckWithLargeFlusherPeriod
org.apache.qpid.test.unit.ct.DurableSubscriberTest#*
diff --git a/java/test-profiles/cpp.ssl.excludes b/java/test-profiles/cpp.ssl.excludes
index 14c8ac2fe3..3d7b929831 100644
--- a/java/test-profiles/cpp.ssl.excludes
+++ b/java/test-profiles/cpp.ssl.excludes
@@ -17,8 +17,6 @@
// under the License.
//
-#org.apache.qpid.test.client.failover.FailoverTest#*
-
//This test does not supply a client keystore, therefore it cant login to the C++ broker
//in this test profile as it demands client certificate authentication
org.apache.qpid.client.ssl.SSLTest#testCreateSSLConnectionUsingConnectionURLParamsTrustStoreOnly
diff --git a/java/test-profiles/java-bdb-spawn.0-10.testprofile b/java/test-profiles/java-bdb-spawn.0-10.testprofile
index 35991645d8..78ab05a179 100644
--- a/java/test-profiles/java-bdb-spawn.0-10.testprofile
+++ b/java/test-profiles/java-bdb-spawn.0-10.testprofile
@@ -19,11 +19,11 @@
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes Java010Excludes JavaBDBExcludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-bdb-spawn.0-8.testprofile b/java/test-profiles/java-bdb-spawn.0-8.testprofile
index a4b74748e6..7f6efcbc3d 100644
--- a/java/test-profiles/java-bdb-spawn.0-8.testprofile
+++ b/java/test-profiles/java-bdb-spawn.0-8.testprofile
@@ -19,15 +19,15 @@
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
broker.version=v0_8
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-bdb-spawn.0-9-1.testprofile b/java/test-profiles/java-bdb-spawn.0-9-1.testprofile
index 9cd70a4ea7..28668b94f7 100644
--- a/java/test-profiles/java-bdb-spawn.0-9-1.testprofile
+++ b/java/test-profiles/java-bdb-spawn.0-9-1.testprofile
@@ -19,15 +19,15 @@
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
broker.version=v0_9_1
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-bdb-spawn.0-9.testprofile b/java/test-profiles/java-bdb-spawn.0-9.testprofile
index 5c0ad2baf3..aa8e6830d4 100644
--- a/java/test-profiles/java-bdb-spawn.0-9.testprofile
+++ b/java/test-profiles/java-bdb-spawn.0-9.testprofile
@@ -19,15 +19,15 @@
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
broker.version=v0_9
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-bdb.0-10.testprofile b/java/test-profiles/java-bdb.0-10.testprofile
index 892188aa24..8c4b145e0b 100644
--- a/java/test-profiles/java-bdb.0-10.testprofile
+++ b/java/test-profiles/java-bdb.0-10.testprofile
@@ -20,11 +20,11 @@
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes Java010Excludes JavaBDBExcludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-bdb.0-8.testprofile b/java/test-profiles/java-bdb.0-8.testprofile
index 87eea96dda..acf031040e 100644
--- a/java/test-profiles/java-bdb.0-8.testprofile
+++ b/java/test-profiles/java-bdb.0-8.testprofile
@@ -20,15 +20,15 @@
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
broker.version=v0_8
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-bdb.0-9-1.testprofile b/java/test-profiles/java-bdb.0-9-1.testprofile
index 1339dc1dc7..fa86720bbb 100644
--- a/java/test-profiles/java-bdb.0-9-1.testprofile
+++ b/java/test-profiles/java-bdb.0-9-1.testprofile
@@ -20,15 +20,15 @@
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
broker.version=v0_9_1
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-bdb.0-9.testprofile b/java/test-profiles/java-bdb.0-9.testprofile
index c097d53c85..ed3d7b2170 100644
--- a/java/test-profiles/java-bdb.0-9.testprofile
+++ b/java/test-profiles/java-bdb.0-9.testprofile
@@ -20,15 +20,15 @@
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-bdb.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-bdb.xml
messagestore.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessageStore
profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes
broker.clean.between.tests=true
broker.persistent=true
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
broker.version=v0_9
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
diff --git a/java/test-profiles/java-dby-mem.0-10.testprofile b/java/test-profiles/java-dby-mem.0-10.testprofile
index 33f9527c86..bfe031b338 100644
--- a/java/test-profiles/java-dby-mem.0-10.testprofile
+++ b/java/test-profiles/java-dby-mem.0-10.testprofile
@@ -20,12 +20,12 @@ broker.language=java
broker.version=v0_10
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-broker.config=build/etc/config-systests-derby-mem.xml
-messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby-mem.xml
+messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes Java010Excludes
broker.clean.between.tests=true
broker.persistent=true
diff --git a/java/test-profiles/java-dby-mem.0-8.testprofile b/java/test-profiles/java-dby-mem.0-8.testprofile
index 89bad84769..28bce8e434 100644
--- a/java/test-profiles/java-dby-mem.0-8.testprofile
+++ b/java/test-profiles/java-dby-mem.0-8.testprofile
@@ -20,12 +20,12 @@ broker.version=v0_8
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby-mem.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
-messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby-mem.xml
+messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
broker.persistent=true
diff --git a/java/test-profiles/java-dby-mem.0-9-1.testprofile b/java/test-profiles/java-dby-mem.0-9-1.testprofile
index 8deea281a4..0d2f82ebb5 100644
--- a/java/test-profiles/java-dby-mem.0-9-1.testprofile
+++ b/java/test-profiles/java-dby-mem.0-9-1.testprofile
@@ -20,12 +20,12 @@ broker.version=v0_9_1
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby-mem.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby-mem.xml
+messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
broker.persistent=true
diff --git a/java/test-profiles/java-dby-mem.0-9.testprofile b/java/test-profiles/java-dby-mem.0-9.testprofile
index b691a7d153..4dd9fbb899 100644
--- a/java/test-profiles/java-dby-mem.0-9.testprofile
+++ b/java/test-profiles/java-dby-mem.0-9.testprofile
@@ -20,12 +20,12 @@ broker.version=v0_9
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby-mem.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
-messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby-mem.xml
+messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
broker.persistent=true
diff --git a/java/test-profiles/java-dby-spawn.0-10.testprofile b/java/test-profiles/java-dby-spawn.0-10.testprofile
index e2e2b44dae..9795533b52 100644
--- a/java/test-profiles/java-dby-spawn.0-10.testprofile
+++ b/java/test-profiles/java-dby-spawn.0-10.testprofile
@@ -19,11 +19,11 @@
broker.language=java
broker.version=v0_10
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-broker.config=build/etc/config-systests-derby.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes Java010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby-spawn.0-8.testprofile b/java/test-profiles/java-dby-spawn.0-8.testprofile
index 3f609226e3..a980fd181d 100644
--- a/java/test-profiles/java-dby-spawn.0-8.testprofile
+++ b/java/test-profiles/java-dby-spawn.0-8.testprofile
@@ -19,11 +19,11 @@
broker.version=v0_8
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby-spawn.0-9-1.testprofile b/java/test-profiles/java-dby-spawn.0-9-1.testprofile
index 80d40458fd..04428b5021 100644
--- a/java/test-profiles/java-dby-spawn.0-9-1.testprofile
+++ b/java/test-profiles/java-dby-spawn.0-9-1.testprofile
@@ -19,11 +19,11 @@
broker.version=v0_9_1
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby-spawn.0-9.testprofile b/java/test-profiles/java-dby-spawn.0-9.testprofile
index 122eccdca1..4724eba660 100644
--- a/java/test-profiles/java-dby-spawn.0-9.testprofile
+++ b/java/test-profiles/java-dby-spawn.0-9.testprofile
@@ -19,11 +19,11 @@
broker.version=v0_9
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby.0-10.testprofile b/java/test-profiles/java-dby.0-10.testprofile
index d3b03054de..a2b1a41c31 100644
--- a/java/test-profiles/java-dby.0-10.testprofile
+++ b/java/test-profiles/java-dby.0-10.testprofile
@@ -20,11 +20,11 @@ broker.language=java
broker.version=v0_10
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
-broker.config=build/etc/config-systests-derby.xml
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes Java010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby.0-8.testprofile b/java/test-profiles/java-dby.0-8.testprofile
index 51580e6c7a..509796331f 100644
--- a/java/test-profiles/java-dby.0-8.testprofile
+++ b/java/test-profiles/java-dby.0-8.testprofile
@@ -20,11 +20,11 @@ broker.version=v0_8
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby.0-9-1.testprofile b/java/test-profiles/java-dby.0-9-1.testprofile
index b92397eae7..be087a6344 100644
--- a/java/test-profiles/java-dby.0-9-1.testprofile
+++ b/java/test-profiles/java-dby.0-9-1.testprofile
@@ -20,11 +20,11 @@ broker.version=v0_9_1
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-dby.0-9.testprofile b/java/test-profiles/java-dby.0-9.testprofile
index 17363b7e47..3b5e586ba4 100644
--- a/java/test-profiles/java-dby.0-9.testprofile
+++ b/java/test-profiles/java-dby.0-9.testprofile
@@ -20,11 +20,11 @@ broker.version=v0_9
broker.language=java
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.config=build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests-derby.xml
messagestore.class.name=org.apache.qpid.server.store.derby.DerbyMessageStore
profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes
broker.clean.between.tests=true
diff --git a/java/test-profiles/java-mms-spawn.0-10.testprofile b/java/test-profiles/java-mms-spawn.0-10.testprofile
index 57af5c4a41..71aaf48562 100644
--- a/java/test-profiles/java-mms-spawn.0-10.testprofile
+++ b/java/test-profiles/java-mms-spawn.0-10.testprofile
@@ -19,10 +19,11 @@
broker.version=v0_10
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms-spawn.0-8.testprofile b/java/test-profiles/java-mms-spawn.0-8.testprofile
index 24f088e0c5..6365fa20f0 100644
--- a/java/test-profiles/java-mms-spawn.0-8.testprofile
+++ b/java/test-profiles/java-mms-spawn.0-8.testprofile
@@ -19,10 +19,11 @@
broker.version=v0_8
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms-spawn.0-9-1.testprofile b/java/test-profiles/java-mms-spawn.0-9-1.testprofile
index c1f6d10675..1eb4b00a1d 100644
--- a/java/test-profiles/java-mms-spawn.0-9-1.testprofile
+++ b/java/test-profiles/java-mms-spawn.0-9-1.testprofile
@@ -19,10 +19,11 @@
broker.version=v0_9_1
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms-spawn.0-9.testprofile b/java/test-profiles/java-mms-spawn.0-9.testprofile
index 421ae7476e..4ebce66c05 100644
--- a/java/test-profiles/java-mms-spawn.0-9.testprofile
+++ b/java/test-profiles/java-mms-spawn.0-9.testprofile
@@ -19,10 +19,11 @@
broker.version=v0_9
broker.language=java
broker.type=spawned
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms.0-10.testprofile b/java/test-profiles/java-mms.0-10.testprofile
index 6dd40cff47..0de5ffea09 100644
--- a/java/test-profiles/java-mms.0-10.testprofile
+++ b/java/test-profiles/java-mms.0-10.testprofile
@@ -20,9 +20,10 @@ broker.language=java
broker.version=v0_10
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
profile.excludes=JavaTransientExcludes Java010Excludes
diff --git a/java/test-profiles/java-mms.0-8.testprofile b/java/test-profiles/java-mms.0-8.testprofile
index f82bf8c473..dddad95157 100644
--- a/java/test-profiles/java-mms.0-8.testprofile
+++ b/java/test-profiles/java-mms.0-8.testprofile
@@ -20,10 +20,11 @@ broker.language=java
broker.version=v0_8
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1,AMQP_0_9
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms.0-9-1.testprofile b/java/test-profiles/java-mms.0-9-1.testprofile
index 9b8baaa5a3..3c2f68a2c9 100644
--- a/java/test-profiles/java-mms.0-9-1.testprofile
+++ b/java/test-profiles/java-mms.0-9-1.testprofile
@@ -20,10 +20,11 @@ broker.language=java
broker.version=v0_9_1
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/java-mms.0-9.testprofile b/java/test-profiles/java-mms.0-9.testprofile
index 56ace6d9e1..992168b044 100644
--- a/java/test-profiles/java-mms.0-9.testprofile
+++ b/java/test-profiles/java-mms.0-9.testprofile
@@ -20,10 +20,11 @@ broker.language=java
broker.version=v0_9
broker.type=internal
#broker.command only used for the second broker during failover tests in this profile
-broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES @INCLUDES -c @CONFIG_FILE -l @LOG_CONFIG_FILE
+broker.command=build/bin/qpid-server -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE
broker.ready=BRK-1004
broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT
+qpid.broker_default_amqp_protocol_excludes=AMQP_1_0,AMQP_0_10,AMQP_0_9_1
+broker.virtualhosts-config=${QPID_HOME}/etc/virtualhosts-systests.xml
#
# Do not enable. Allow client to attempt 0-10 and negotiate downwards
#
diff --git a/java/test-profiles/testprofile.defaults b/java/test-profiles/testprofile.defaults
index 47992b9334..033da12a97 100644
--- a/java/test-profiles/testprofile.defaults
+++ b/java/test-profiles/testprofile.defaults
@@ -20,7 +20,7 @@ java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFac
java.naming.provider.url=${test.profiles}/test-provider.properties
broker.ready=Listening on TCP
-broker.config=build/etc/config-systests.xml
+broker.config=build/etc/config-systests.json
messagestore.class.name=org.apache.qpid.server.store.MemoryMessageStore
broker.protocol.excludes=
broker.persistent=false
@@ -33,13 +33,20 @@ amqj.logging.level=${log}
amqj.server.logging.level=${log}
amqj.protocol.logging.level=${log}
root.logging.level=warn
-log4j.configuration=test-profiles/log4j-test.xml
+
+# System property log4j.configuration is used by log4j.
+# QpidBrokerTestCase uses log4j.configuration.file to construct a java.io.File, eg for log configuration of spawned brokers.
+log4j.configuration.file=${test.profiles}/log4j-test.xml
+log4j.configuration=file:///${log4j.configuration.file}
+
log4j.debug=false
# Note test-provider.properties also has variables of same name.
# Keep in sync
test.port=15672
test.mport=18999
+test.cport=19099
+test.hport=18080
#Note : Management will start open second port on: mport + 100 : 19099
test.port.ssl=15671
test.port.alt=25672
@@ -55,5 +62,7 @@ haltonerror=no
exclude.modules=none
profile.clustered=false
+broker.config-store-type=json
+broker.virtualhosts-config="${QPID_HOME}/etc/virtualhosts-systests.xml"